forked from organicmaps/organicmaps
Using struct bit field for transit edge flags.
This commit is contained in:
parent
44ab61e68d
commit
99369a0842
4 changed files with 70 additions and 24 deletions
|
@ -227,11 +227,18 @@ UNIT_TEST(Transit_EdgeSerialization)
|
|||
TEST(edge.IsValid(), (edge));
|
||||
}
|
||||
{
|
||||
Edge edge(1 /* start stop id */, 2 /* finish stop id */, 123 /* weight */, 11 /* line id */,
|
||||
Edge edge(1 /* start stop id */, 2 /* finish stop id */, 123 /* weight */, kInvalidLineId,
|
||||
true /* transfer */, {} /* shape ids */);
|
||||
TestSerialization(edge);
|
||||
TEST(edge.IsValid(), (edge));
|
||||
}
|
||||
{
|
||||
Edge edge(1 /* start stop id */, 2 /* finish stop id */, 123 /* weight */, 11 /* line id */,
|
||||
true /* transfer */, {} /* shape ids */);
|
||||
TestSerialization(edge);
|
||||
// Note. A transfer edge (transfer == true) with a valid line id is not allowable.
|
||||
TEST(!edge.IsValid(), (edge));
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_TransferSerialization)
|
||||
|
|
|
@ -261,7 +261,12 @@ public:
|
|||
(*this)(e.m_shapeIds);
|
||||
}
|
||||
|
||||
void operator()(EdgeFlags & f, char const * /* name */ = nullptr) { (*this)(f.m_flags); }
|
||||
void operator()(EdgeFlags & f, char const * /* name */ = nullptr)
|
||||
{
|
||||
uint8_t flags = 0;
|
||||
(*this)(flags);
|
||||
f.SetFlags(flags);
|
||||
}
|
||||
|
||||
void operator()(vector<m2::PointD> & vs, char const * /* name */ = nullptr)
|
||||
{
|
||||
|
|
|
@ -227,15 +227,41 @@ bool ShapeId::IsValid() const
|
|||
}
|
||||
|
||||
// EdgeFlags --------------------------------------------------------------------------------------
|
||||
void EdgeFlags::SetBit(bool bit, uint8_t bitMask)
|
||||
EdgeFlags::EdgeFlags()
|
||||
: m_transfer(0)
|
||||
, m_isShapeIdsEmpty(0)
|
||||
, m_isShapeIdsSingle(0)
|
||||
, m_isShapeIdsSame(0)
|
||||
, m_isShapeIdsReversed(0)
|
||||
{
|
||||
if (bit)
|
||||
m_flags |= bitMask;
|
||||
else
|
||||
m_flags &= ~bitMask;
|
||||
}
|
||||
|
||||
string DebugPrint(EdgeFlags const & f) { return strings::to_string(f.GetFlags()); }
|
||||
uint8_t EdgeFlags::GetFlags() const
|
||||
{
|
||||
return m_transfer + m_isShapeIdsEmpty * kEmptyShapeIdsMask +
|
||||
m_isShapeIdsSingle * kSingleShapeIdMask + m_isShapeIdsSame * kShapeIdIsSameMask +
|
||||
m_isShapeIdsReversed * kShapeIdIsReversedMask;
|
||||
}
|
||||
|
||||
void EdgeFlags::SetFlags(uint8_t flags)
|
||||
{
|
||||
m_transfer = GetBit(flags, kTransferMask);
|
||||
m_isShapeIdsEmpty = GetBit(flags, kEmptyShapeIdsMask);
|
||||
m_isShapeIdsSingle = GetBit(flags, kSingleShapeIdMask);
|
||||
m_isShapeIdsSame = GetBit(flags, kShapeIdIsSameMask);
|
||||
m_isShapeIdsReversed = GetBit(flags, kShapeIdIsReversedMask);
|
||||
}
|
||||
|
||||
string DebugPrint(EdgeFlags const & f)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "EdgeFlags [m_transfer:" << f.IsTransfer();
|
||||
ss << ", m_isShapeIdsEmpty:" << f.IsEmptyShapeIds();
|
||||
ss << ", m_isShapeIdsSingle:" << f.IsSingleShapeId();
|
||||
ss << ", m_isShapeIdsSame:" << f.IsShapeIdTheSame();
|
||||
ss << ", m_isShapeIdsReversed:" << f.IsShapeIdReversed() << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Edge -------------------------------------------------------------------------------------------
|
||||
Edge::Edge(StopId stop1Id, StopId stop2Id, Weight weight, LineId lineId, bool transfer,
|
||||
|
|
|
@ -260,45 +260,53 @@ class EdgeFlags
|
|||
public:
|
||||
DECLARE_TRANSIT_TYPE_FRIENDS
|
||||
|
||||
bool IsTransfer() const { return IsBit(kTransferMask); }
|
||||
void SetTransfer(bool transfer) { SetBit(transfer, kTransferMask); }
|
||||
EdgeFlags();
|
||||
|
||||
bool IsTransfer() const { return m_transfer == 1; }
|
||||
void SetTransfer(bool transfer) { m_transfer = BoolToUint(transfer); }
|
||||
|
||||
/// \returns true if |Edge::m_shapeIds| is empty.
|
||||
bool IsEmptyShapeIds() const { return IsBit(kEmptyShapeIdsMask); }
|
||||
void SetEmptyShapeIds(bool emptyShapeIds) { SetBit(emptyShapeIds, kEmptyShapeIdsMask); }
|
||||
bool IsEmptyShapeIds() const { return m_isShapeIdsEmpty == 1; }
|
||||
void SetEmptyShapeIds(bool emptyShapeIds) { m_isShapeIdsEmpty = BoolToUint(emptyShapeIds); }
|
||||
|
||||
/// \returns true if |Edge::m_shapeIds| contains only one item.
|
||||
bool IsSingleShapeId() const { return IsBit(kSingleShapeIdMask); }
|
||||
void SetSingleShapeId(bool singleShapeId) { SetBit(singleShapeId, kSingleShapeIdMask); }
|
||||
bool IsSingleShapeId() const { return m_isShapeIdsSingle == 1; }
|
||||
void SetSingleShapeId(bool singleShapeId) { m_isShapeIdsSingle = BoolToUint(singleShapeId); }
|
||||
|
||||
/// \note It's valid only if IsSingleShapeId() returns true.
|
||||
/// \returns true if
|
||||
/// |Edge::m_stop1Id == m_shapeIds[0].m_stop1Id && Edge::m_stop2Id == m_shapeIds[0].m_stop2Id|.
|
||||
bool IsShapeIdTheSame() const { return IsBit(kShapeIdIsTheSameMask); }
|
||||
void SetShapeIdTheSame(bool same) { SetBit(same, kShapeIdIsTheSameMask); }
|
||||
bool IsShapeIdTheSame() const { return m_isShapeIdsSame == 1; }
|
||||
void SetShapeIdTheSame(bool same) { m_isShapeIdsSame = BoolToUint(same); }
|
||||
|
||||
/// \note It's valid only if IsSingleShapeId() returns true.
|
||||
/// \returns true if
|
||||
/// |Edge::m_stop1Id == m_shapeIds[0].m_stop2Id && Edge::m_stop2Id == m_shapeIds[0].m_stop1Id|.
|
||||
bool IsShapeIdReversed() const { return IsBit(kShapeIdIsReversedMask); }
|
||||
void SetShapeIdReversed(bool reversed) { SetBit(reversed, kShapeIdIsReversedMask); }
|
||||
bool IsShapeIdReversed() const { return m_isShapeIdsReversed == 1; }
|
||||
void SetShapeIdReversed(bool reversed) { m_isShapeIdsReversed = BoolToUint(reversed); }
|
||||
|
||||
uint8_t GetFlags() const { return m_flags; }
|
||||
void SetFlags(uint8_t flags) { m_flags = flags; }
|
||||
uint8_t GetFlags() const;
|
||||
void SetFlags(uint8_t flags);
|
||||
|
||||
private:
|
||||
bool IsBit(uint8_t bitMask) const { return m_flags & bitMask; }
|
||||
void SetBit(bool bit, uint8_t bitMask);
|
||||
uint8_t BoolToUint(bool b) { return static_cast<uint8_t>(b ? 1 : 0); }
|
||||
uint8_t GetBit(uint8_t flags, uint8_t mask) { return BoolToUint(flags & mask); }
|
||||
|
||||
static uint8_t constexpr kTransferMask = 1;
|
||||
static uint8_t constexpr kEmptyShapeIdsMask = (1 << 1);
|
||||
static uint8_t constexpr kSingleShapeIdMask = (1 << 2);
|
||||
static uint8_t constexpr kShapeIdIsTheSameMask = (1 << 3);
|
||||
static uint8_t constexpr kShapeIdIsSameMask = (1 << 3);
|
||||
static uint8_t constexpr kShapeIdIsReversedMask = (1 << 4);
|
||||
|
||||
uint8_t m_flags = 0;
|
||||
uint8_t m_transfer : 1;
|
||||
uint8_t m_isShapeIdsEmpty : 1;
|
||||
uint8_t m_isShapeIdsSingle : 1;
|
||||
uint8_t m_isShapeIdsSame : 1;
|
||||
uint8_t m_isShapeIdsReversed : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(EdgeFlags) == 1, "Wrong EdgeFlags size.");
|
||||
|
||||
std::string DebugPrint(EdgeFlags const & f);
|
||||
|
||||
class Edge
|
||||
|
|
Loading…
Add table
Reference in a new issue