Program Listing for File SequenceNumber.h
↰ Return to documentation for file (/tmp/ws/src/fastrtps/include/fastdds/rtps/common/SequenceNumber.h
)
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _FASTDDS_RPTS_ELEM_SEQNUM_H_
#define _FASTDDS_RPTS_ELEM_SEQNUM_H_
#include <algorithm>
#include <cassert>
#include <limits>
#include <vector>
#include <fastrtps/fastrtps_dll.h>
#include <fastrtps/utils/fixed_size_bitmap.hpp>
#include <fastdds/rtps/common/Types.h>
namespace eprosima {
namespace fastrtps {
namespace rtps {
struct RTPS_DllAPI SequenceNumber_t
{
int32_t high = 0;
uint32_t low = 0;
SequenceNumber_t() noexcept
{
high = 0;
low = 0;
}
SequenceNumber_t(
int32_t hi,
uint32_t lo) noexcept
: high(hi)
, low(lo)
{
}
explicit
SequenceNumber_t(
uint64_t u) noexcept
: high(static_cast<int32_t>(u >> 32u))
, low(static_cast<uint32_t>(u))
{
}
uint64_t to64long() const noexcept
{
return (static_cast<uint64_t>(high) << 32u) + low;
}
SequenceNumber_t& operator ++() noexcept
{
++low;
if (low == 0)
{
assert(std::numeric_limits<decltype(high)>::max() > high);
++high;
}
return *this;
}
SequenceNumber_t operator ++(
int) noexcept
{
SequenceNumber_t result(*this);
++(*this);
return result;
}
SequenceNumber_t& operator +=(
int inc) noexcept
{
assert(inc >= 0);
uint32_t aux_low = low;
low += static_cast<uint32_t>(inc);
if (low < aux_low)
{
// Being the type of the parameter an 'int', the increment of 'high' will be as much as 1.
assert(std::numeric_limits<decltype(high)>::max() > high);
++high;
}
return *this;
}
static SequenceNumber_t unknown() noexcept
{
return { -1, 0 };
}
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
inline bool operator ==(
const SequenceNumber_t& sn1,
const SequenceNumber_t& sn2) noexcept
{
return (sn1.low == sn2.low) && (sn1.high == sn2.high);
}
inline bool operator !=(
const SequenceNumber_t& sn1,
const SequenceNumber_t& sn2) noexcept
{
return (sn1.low != sn2.low) || (sn1.high != sn2.high);
}
inline bool operator >(
const SequenceNumber_t& seq1,
const SequenceNumber_t& seq2) noexcept
{
if (seq1.high == seq2.high)
{
return seq1.low > seq2.low;
}
return seq1.high > seq2.high;
}
inline bool operator <(
const SequenceNumber_t& seq1,
const SequenceNumber_t& seq2) noexcept
{
if (seq1.high == seq2.high)
{
return seq1.low < seq2.low;
}
return seq1.high < seq2.high;
}
inline bool operator >=(
const SequenceNumber_t& seq1,
const SequenceNumber_t& seq2) noexcept
{
if (seq1.high == seq2.high)
{
return seq1.low >= seq2.low;
}
return seq1.high > seq2.high;
}
inline bool operator <=(
const SequenceNumber_t& seq1,
const SequenceNumber_t& seq2) noexcept
{
if (seq1.high == seq2.high)
{
return seq1.low <= seq2.low;
}
return seq1.high < seq2.high;
}
inline SequenceNumber_t operator -(
const SequenceNumber_t& seq,
const uint32_t inc) noexcept
{
SequenceNumber_t res(seq.high, seq.low - inc);
if (inc > seq.low)
{
// Being the type of the parameter an 'uint32_t', the decrement of 'high' will be as much as 1.
assert(0 < res.high);
--res.high;
}
return res;
}
inline SequenceNumber_t operator +(
const SequenceNumber_t& seq,
const uint32_t inc) noexcept
{
SequenceNumber_t res(seq.high, seq.low + inc);
if (res.low < seq.low)
{
// Being the type of the parameter an 'uint32_t', the increment of 'high' will be as much as 1.
assert(std::numeric_limits<decltype(res.high)>::max() > res.high);
++res.high;
}
return res;
}
inline SequenceNumber_t operator -(
const SequenceNumber_t& minuend,
const SequenceNumber_t& subtrahend) noexcept
{
assert(minuend >= subtrahend);
SequenceNumber_t res(minuend.high - subtrahend.high, minuend.low - subtrahend.low);
if (minuend.low < subtrahend.low)
{
assert(0 < res.high);
--res.high;
}
return res;
}
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
const SequenceNumber_t c_SequenceNumber_Unknown{-1, 0};
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
inline bool sort_seqNum(
const SequenceNumber_t& s1,
const SequenceNumber_t& s2) noexcept
{
return s1 < s2;
}
inline std::ostream& operator <<(
std::ostream& output,
const SequenceNumber_t& seqNum)
{
return output << seqNum.to64long();
}
inline std::ostream& operator <<(
std::ostream& output,
const std::vector<SequenceNumber_t>& seqNumSet)
{
for (const SequenceNumber_t& sn : seqNumSet)
{
output << sn << " ";
}
return output;
}
struct SequenceNumberHash
{
std::size_t operator ()(
const SequenceNumber_t& sequence_number) const noexcept
{
return static_cast<std::size_t>(sequence_number.to64long());
}
};
struct SequenceNumberDiff
{
uint32_t operator ()(
const SequenceNumber_t& a,
const SequenceNumber_t& b) const noexcept
{
SequenceNumber_t diff = a - b;
return diff.low;
}
};
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
using SequenceNumberSet_t = BitmapRange<SequenceNumber_t, SequenceNumberDiff, 256>;
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
inline std::ostream& operator <<(
std::ostream& output,
const SequenceNumberSet_t& sns)
{
output << sns.base().to64long() << ":";
sns.for_each([&output](
SequenceNumber_t it)
{
output << it.to64long() << "-";
});
return output;
}
inline std::istream& operator >>(
std::istream& input,
SequenceNumber_t& seqNum)
{
uint64_t aux;
if (input >> aux)
{
seqNum = SequenceNumber_t(aux);
}
return input;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
} // namespace rtps
} // namespace fastrtps
} // namespace eprosima
#endif /* _FASTDDS_RTPS_ELEM_SEQNUM_H_ */