diff --git a/routing/bicycle_directions.cpp b/routing/bicycle_directions.cpp index baa5309d4a..8df139863d 100644 --- a/routing/bicycle_directions.cpp +++ b/routing/bicycle_directions.cpp @@ -151,9 +151,10 @@ bool IsJoint(IRoadGraph::TEdgeVector const & ingoingEdges, namespace routing { // BicycleDirectionsEngine::AdjacentEdges --------------------------------------------------------- -bool BicycleDirectionsEngine::AdjacentEdges::operator==(AdjacentEdges const & rhs) const +bool BicycleDirectionsEngine::AdjacentEdges::IsAlmostEqual(AdjacentEdges const & rhs) const { - return m_outgoingTurns == rhs.m_outgoingTurns && m_ingoingTurnsCount == rhs.m_ingoingTurnsCount; + return m_outgoingTurns.IsAlmostEqual(rhs.m_outgoingTurns) && + m_ingoingTurnsCount == rhs.m_ingoingTurnsCount; } // BicycleDirectionsEngine ------------------------------------------------------------------------ @@ -366,7 +367,7 @@ void BicycleDirectionsEngine::FillPathSegmentsAndAdjacentEdgesMap( // A route may be build through intermediate points. So it may contain the same |segmentRange| // several times. But in that case |adjacentEdges| corresponds to |segmentRange| // should be the same as well. - ASSERT(it == m_adjacentEdges.cend() || it->second == adjacentEdges, + ASSERT(it == m_adjacentEdges.cend() || it->second.IsAlmostEqual(adjacentEdges), ("segmentRange:", segmentRange, "corresponds to adjacent edges which aren't equal.")); m_adjacentEdges.insert(it, make_pair(segmentRange, move(adjacentEdges))); diff --git a/routing/bicycle_directions.hpp b/routing/bicycle_directions.hpp index 64064165bd..897cbbc441 100644 --- a/routing/bicycle_directions.hpp +++ b/routing/bicycle_directions.hpp @@ -19,8 +19,7 @@ public: struct AdjacentEdges { explicit AdjacentEdges(size_t ingoingTurnsCount = 0) : m_ingoingTurnsCount(ingoingTurnsCount) {} - bool operator==(AdjacentEdges const & rhs) const; - bool operator!=(AdjacentEdges const & rhs) const { return !(*this == rhs); } + bool IsAlmostEqual(AdjacentEdges const & rhs) const; turns::TurnCandidates m_outgoingTurns; size_t m_ingoingTurnsCount; diff --git a/routing/turn_candidate.hpp b/routing/turn_candidate.hpp index e6bcc0e448..3a448c376e 100644 --- a/routing/turn_candidate.hpp +++ b/routing/turn_candidate.hpp @@ -2,6 +2,8 @@ #include "routing/turns.hpp" +#include "base/math.hpp" + #include "std/vector.hpp" namespace ftypes @@ -41,13 +43,27 @@ struct TurnCandidate { } - bool operator==(TurnCandidate const & rhs) const + bool IsAlmostEqual(TurnCandidate const & rhs) const { - return angle == rhs.angle && m_segmentRange == rhs.m_segmentRange && + double constexpr kEpsilon = 0.01; + return my::AlmostEqualAbs(angle, rhs.angle, kEpsilon) && m_segmentRange == rhs.m_segmentRange && highwayClass == rhs.highwayClass; } }; +inline bool IsAlmostEqual(vector const & lhs, vector const & rhs) +{ + if (lhs.size() != rhs.size()) + return false; + + for (size_t i = 0; i < lhs.size(); ++i) + { + if (!lhs[i].IsAlmostEqual(rhs[i])) + return false; + } + return true; +} + struct TurnCandidates { vector candidates; @@ -55,11 +71,11 @@ struct TurnCandidates explicit TurnCandidates(bool angleValid = true) : isCandidatesAngleValid(angleValid) {} - bool operator==(TurnCandidates const & rhs) const + bool IsAlmostEqual(TurnCandidates const & rhs) const { - return candidates == rhs.candidates && isCandidatesAngleValid == rhs.isCandidatesAngleValid; + return turns::IsAlmostEqual(candidates, rhs.candidates) && + isCandidatesAngleValid == rhs.isCandidatesAngleValid; } }; - } // namespace routing } // namespace turns diff --git a/routing/turns.cpp b/routing/turns.cpp index 73f73281ce..8d521f255c 100644 --- a/routing/turns.cpp +++ b/routing/turns.cpp @@ -4,10 +4,12 @@ #include "base/internal/message.hpp" -#include "std/array.hpp" -#include "std/utility.hpp" - +#include +#include #include +#include + +using namespace std; namespace { @@ -53,8 +55,6 @@ static_assert(g_turnNames.size() == static_cast(CarDirection::Count), namespace routing { -using namespace std; - // SegmentRange ----------------------------------------------------------------------------------- SegmentRange::SegmentRange(FeatureID const & featureId, uint32_t startSegId, uint32_t endSegId, bool forward) @@ -276,9 +276,11 @@ bool ParseLanes(string lanesString, vector & lanes) if (lanesString.empty()) return false; lanes.clear(); - transform(lanesString.begin(), lanesString.end(), lanesString.begin(), tolower); - lanesString.erase(remove_if(lanesString.begin(), lanesString.end(), isspace), - lanesString.end()); + transform(lanesString.begin(), lanesString.end(), lanesString.begin(), + [](string::value_type c) { return tolower(c); }); + lanesString.erase( + remove_if(lanesString.begin(), lanesString.end(), [](char c) { return isspace(c); }), + lanesString.end()); vector SplitLanesStrings; SingleLaneInfo lane; diff --git a/routing/turns.hpp b/routing/turns.hpp index 8218ce0c2c..65f2fc278e 100644 --- a/routing/turns.hpp +++ b/routing/turns.hpp @@ -4,10 +4,10 @@ #include "geometry/point2d.hpp" -#include "std/initializer_list.hpp" -#include "std/limits.hpp" -#include "std/string.hpp" -#include "std/vector.hpp" +#include +#include +#include +#include namespace routing { @@ -16,7 +16,7 @@ namespace routing /// and a direction. struct SegmentRange { - friend string DebugPrint(SegmentRange const & segmentRange); + friend std::string DebugPrint(SegmentRange const & segmentRange); SegmentRange() = default; SegmentRange(FeatureID const & featureId, uint32_t startSegId, uint32_t endSegId, bool forward); @@ -37,7 +37,7 @@ private: bool m_forward = true; // Segment direction in |m_featureId|. }; -string DebugPrint(SegmentRange const & segmentRange); +std::string DebugPrint(SegmentRange const & segmentRange); namespace turns { @@ -80,7 +80,7 @@ enum class CarDirection Count /**< This value is used for internals only. */ }; -string DebugPrint(CarDirection const l); +std::string DebugPrint(CarDirection const l); /*! * \warning The values of PedestrianDirectionType shall be synchronized with values in java @@ -96,7 +96,7 @@ enum class PedestrianDirection Count /**< This value is used for internals only. */ }; -string DebugPrint(PedestrianDirection const l); +std::string DebugPrint(PedestrianDirection const l); /*! * \warning The values of LaneWay shall be synchronized with values of LaneWay enum in java. @@ -117,9 +117,9 @@ enum class LaneWay Count /**< This value is used for internals only. */ }; -string DebugPrint(LaneWay const l); +std::string DebugPrint(LaneWay const l); -typedef vector TSingleLane; +typedef std::vector TSingleLane; struct SingleLaneInfo { @@ -127,11 +127,11 @@ struct SingleLaneInfo bool m_isRecommended = false; SingleLaneInfo() = default; - SingleLaneInfo(initializer_list const & l) : m_lane(l) {} + SingleLaneInfo(std::initializer_list const & l) : m_lane(l) {} bool operator==(SingleLaneInfo const & other) const; }; -string DebugPrint(SingleLaneInfo const & singleLaneInfo); +std::string DebugPrint(SingleLaneInfo const & singleLaneInfo); struct TurnItem { @@ -168,8 +168,8 @@ struct TurnItem CarDirection m_turn; /*!< The turn instruction of the TurnItem */ vector m_lanes; /*!< Lane information on the edge before the turn. */ uint32_t m_exitNum; /*!< Number of exit on roundabout. */ - string m_sourceName; /*!< Name of the street which the ingoing edge belongs to */ - string m_targetName; /*!< Name of the street which the outgoing edge belongs to */ + std::string m_sourceName; /*!< Name of the street which the ingoing edge belongs to */ + std::string m_targetName; /*!< Name of the street which the outgoing edge belongs to */ /*! * \brief m_keepAnyway is true if the turn shall not be deleted * and shall be demonstrated to an end user. @@ -182,7 +182,7 @@ struct TurnItem PedestrianDirection m_pedestrianTurn; }; -string DebugPrint(TurnItem const & turnItem); +std::string DebugPrint(TurnItem const & turnItem); struct TurnItemDist { @@ -196,9 +196,9 @@ struct TurnItemDist double m_distMeters = 0.0; }; -string DebugPrint(TurnItemDist const & turnItemDist); +std::string DebugPrint(TurnItemDist const & turnItemDist); -string const GetTurnString(CarDirection turn); +std::string const GetTurnString(CarDirection turn); bool IsLeftTurn(CarDirection t); bool IsRightTurn(CarDirection t); @@ -232,9 +232,9 @@ bool IsLaneWayConformedTurnDirectionApproximately(LaneWay l, CarDirection t); * Note 1: if @lanesString is empty returns false. * Note 2: @laneString is passed by value on purpose. It'll be used(changed) in the method. */ -bool ParseLanes(string lanesString, vector & lanes); -void SplitLanes(string const & lanesString, char delimiter, vector & lanes); -bool ParseSingleLane(string const & laneString, char delimiter, TSingleLane & lane); +bool ParseLanes(std::string lanesString, vector & lanes); +void SplitLanes(std::string const & lanesString, char delimiter, std::vector & lanes); +bool ParseSingleLane(std::string const & laneString, char delimiter, TSingleLane & lane); /*! * \returns pi minus angle from vector [junctionPoint, ingoingPoint]