Merge pull request #2312 from oxidase/stateless-parameters-grammars
Stateless parameters grammars and fix for PhantomNode bitfields packing in MSVC
This commit is contained in:
		
						commit
						15e3928906
					
				| @ -63,18 +63,9 @@ struct Hint | ||||
|     friend std::ostream &operator<<(std::ostream &, const Hint &); | ||||
| }; | ||||
| 
 | ||||
| #ifndef _MSC_VER | ||||
| static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected"); | ||||
| constexpr std::size_t ENCODED_HINT_SIZE = 88; | ||||
| static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), | ||||
|               "ENCODED_HINT_SIZE does not match size of Hint"); | ||||
| #else | ||||
| // PhantomNode is bigger under windows because MSVC does not support bit packing
 | ||||
| static_assert(sizeof(Hint) == 72 + 4, "Hint is bigger than expected"); | ||||
| constexpr std::size_t ENCODED_HINT_SIZE = 104; | ||||
| static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), | ||||
|               "ENCODED_HINT_SIZE does not match size of Hint"); | ||||
| #endif | ||||
| static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), "ENCODED_HINT_SIZE does not match size of Hint"); | ||||
| } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -149,13 +149,11 @@ struct PhantomNode | ||||
|     unsigned reverse_packed_geometry_id; | ||||
|     struct ComponentType | ||||
|     { | ||||
|         uint32_t id : 31; | ||||
|         bool is_tiny : 1; | ||||
|         std::uint32_t id         : 31; | ||||
|         std::uint32_t is_tiny    : 1; | ||||
|     } component; | ||||
| // bit-fields are broken on Windows
 | ||||
| #ifndef _MSC_VER | ||||
|     static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big"); | ||||
| #endif | ||||
| 
 | ||||
|     util::Coordinate location; | ||||
|     util::Coordinate input_location; | ||||
|     unsigned short fwd_segment_position; | ||||
| @ -165,11 +163,7 @@ struct PhantomNode | ||||
|     extractor::TravelMode backward_travel_mode; | ||||
| }; | ||||
| 
 | ||||
| #ifndef _MSC_VER | ||||
| static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected"); | ||||
| #else | ||||
| static_assert(sizeof(PhantomNode) == 72, "PhantomNode has more padding then expected"); | ||||
| #endif | ||||
| 
 | ||||
| using PhantomNodePair = std::pair<PhantomNode, PhantomNode>; | ||||
| 
 | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
| #include "engine/polyline_compressor.hpp" | ||||
| 
 | ||||
| #include <boost/optional.hpp> | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| #include <limits> | ||||
| @ -21,7 +21,11 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| } | ||||
| 
 | ||||
| template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_policies<T> | ||||
| { | ||||
| @ -63,17 +67,25 @@ template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_poli | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator> | ||||
| template <typename Iterator, typename Signature> | ||||
| struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature> | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
|     using RadiusesT = std::vector<boost::optional<double>>; | ||||
|     using json_policy = no_trailing_dot_policy<double, 'j', 's', 'o', 'n'>; | ||||
| 
 | ||||
|     BaseParametersGrammar(qi::rule<Iterator> &root_rule_, engine::api::BaseParameters ¶meters_) | ||||
|         : BaseParametersGrammar::base_type(root_rule_), base_parameters(parameters_) | ||||
|     BaseParametersGrammar(qi::rule<Iterator, Signature> &root_rule) | ||||
|         : BaseParametersGrammar::base_type(root_rule) | ||||
|     { | ||||
|         const auto add_hint = [](engine::api::BaseParameters &base_parameters, const std::string &hint_string) | ||||
|         { | ||||
|             if (hint_string.size() > 0) | ||||
|             { | ||||
|                 base_parameters.hints.emplace_back(engine::Hint::FromBase64(hint_string)); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         const auto add_bearing = [](engine::api::BaseParameters &base_parameters, | ||||
|                                     boost::optional<boost::fusion::vector2<short, short>> bearing_range) | ||||
|         { | ||||
|         const auto add_bearing = | ||||
|             [this](boost::optional<boost::fusion::vector2<short, short>> bearing_range) { | ||||
|             boost::optional<engine::Bearing> bearing; | ||||
|             if (bearing_range) | ||||
|             { | ||||
| @ -82,57 +94,73 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator> | ||||
|             } | ||||
|             base_parameters.bearings.push_back(std::move(bearing)); | ||||
|         }; | ||||
|         const auto set_radiuses = [this](RadiusesT radiuses) { | ||||
|             base_parameters.radiuses = std::move(radiuses); | ||||
|         }; | ||||
|         const auto add_hint = [this](const std::string &hint_string) { | ||||
|             if (hint_string.size() > 0) | ||||
|             { | ||||
|                 base_parameters.hints.push_back(engine::Hint::FromBase64(hint_string)); | ||||
|             } | ||||
|         }; | ||||
|         const auto add_coordinate = [this](const boost::fusion::vector<double, double> &lonLat) { | ||||
|             base_parameters.coordinates.emplace_back(util::Coordinate( | ||||
|                 util::FixedLongitude(boost::fusion::at_c<0>(lonLat) * COORDINATE_PRECISION), | ||||
|                 util::FixedLatitude(boost::fusion::at_c<1>(lonLat) * COORDINATE_PRECISION))); | ||||
|         }; | ||||
|         const auto polyline_to_coordinates = [this](const std::string &polyline) { | ||||
|             base_parameters.coordinates = engine::decodePolyline(polyline); | ||||
|         }; | ||||
| 
 | ||||
|         alpha_numeral = +qi::char_("a-zA-Z0-9"); | ||||
|         polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^"); | ||||
|         base64_char = qi::char_("a-zA-Z0-9--_="); | ||||
|         unlimited_rule = qi::lit("unlimited")[qi::_val = std::numeric_limits<double>::infinity()]; | ||||
| 
 | ||||
|         unlimited.add("unlimited", std::numeric_limits<double>::infinity()); | ||||
|         bearing_rule | ||||
|             = (qi::short_ > ',' > qi::short_) | ||||
|               [qi::_val = ph::bind([](short bearing, short range) { | ||||
|                   return osrm::engine::Bearing{bearing, range}; | ||||
|               }, qi::_1, qi::_2)] | ||||
|             ; | ||||
| 
 | ||||
|         radiuses_rule = qi::lit("radiuses=") > -(unlimited | qi::double_) % ";"; | ||||
|         hints_rule = | ||||
|             qi::lit("hints=") > | ||||
|             qi::as_string[qi::repeat(engine::ENCODED_HINT_SIZE)[base64_char]][add_hint] % ";"; | ||||
|         bearings_rule = | ||||
|             qi::lit("bearings=") > (-(qi::short_ > ',' > qi::short_))[add_bearing] % ";"; | ||||
|         polyline_rule = qi::as_string[qi::lit("polyline(") > +polyline_chars > qi::lit(")")] | ||||
|                                      [polyline_to_coordinates]; | ||||
|         location_rule = (double_ > qi::lit(',') > double_)[add_coordinate]; | ||||
|         query_rule = (location_rule % ';') | polyline_rule; | ||||
|         location_rule | ||||
|             = (double_ > qi::lit(',') > double_) | ||||
|               [qi::_val = ph::bind([](double lon, double lat) { | ||||
|                   return util::Coordinate(util::FixedLongitude(lon * COORDINATE_PRECISION), | ||||
|                                           util::FixedLatitude(lat * COORDINATE_PRECISION)); | ||||
|               }, qi::_1, qi::_2)] | ||||
|             ; | ||||
| 
 | ||||
|         base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule; | ||||
|         polyline_rule | ||||
|             = qi::as_string[qi::lit("polyline(") > +polyline_chars > ')'] | ||||
|               [qi::_val = ph::bind([](const std::string &polyline) { | ||||
|                   return engine::decodePolyline(polyline); | ||||
|               }, qi::_1)] | ||||
|             ; | ||||
| 
 | ||||
|         query_rule | ||||
|             = ((location_rule % ';') | polyline_rule) | ||||
|               [ph::bind(&engine::api::BaseParameters::coordinates, qi::_r1) = qi::_1] | ||||
|             ; | ||||
| 
 | ||||
|         radiuses_rule | ||||
|             = qi::lit("radiuses=") | ||||
|             > (-(qi::double_ | unlimited_rule) % ';') | ||||
|               [ph::bind(&engine::api::BaseParameters::radiuses, qi::_r1) = qi::_1] | ||||
|             ; | ||||
| 
 | ||||
|         hints_rule | ||||
|             = qi::lit("hints=") | ||||
|             > qi::as_string[qi::repeat(engine::ENCODED_HINT_SIZE)[base64_char]][ph::bind(add_hint, qi::_r1, qi::_1)] % ';' | ||||
|             ; | ||||
| 
 | ||||
|         bearings_rule | ||||
|             = qi::lit("bearings=") > | ||||
|             (-(qi::short_ > ',' > qi::short_))[ph::bind(add_bearing, qi::_r1, qi::_1)] % ';' | ||||
|             ; | ||||
| 
 | ||||
|         base_rule = radiuses_rule(qi::_r1) | hints_rule(qi::_r1) | bearings_rule(qi::_r1); | ||||
|     } | ||||
| 
 | ||||
|   protected: | ||||
|     qi::rule<Iterator> base_rule; | ||||
|     qi::rule<Iterator> query_rule; | ||||
|     qi::rule<Iterator, Signature> base_rule; | ||||
|     qi::rule<Iterator, Signature> query_rule; | ||||
| 
 | ||||
|   private: | ||||
|     engine::api::BaseParameters &base_parameters; | ||||
|     qi::rule<Iterator> bearings_rule; | ||||
|     qi::rule<Iterator> hints_rule; | ||||
|     qi::rule<Iterator> polyline_rule, location_rule; | ||||
|     qi::symbols<char, double> unlimited; | ||||
|     qi::rule<Iterator, RadiusesT()> radiuses_rule; | ||||
|     qi::rule<Iterator, Signature> bearings_rule; | ||||
|     qi::rule<Iterator, Signature> radiuses_rule; | ||||
|     qi::rule<Iterator, Signature> hints_rule; | ||||
| 
 | ||||
|     qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule; | ||||
|     qi::rule<Iterator, osrm::util::Coordinate()> location_rule; | ||||
|     qi::rule<Iterator, std::vector<osrm::util::Coordinate>()> polyline_rule; | ||||
| 
 | ||||
|     qi::rule<Iterator, unsigned char()> base64_char; | ||||
|     qi::rule<Iterator, std::string()> alpha_numeral, polyline_chars; | ||||
|     qi::rule<Iterator, std::string()> polyline_chars; | ||||
|     qi::rule<Iterator, double()> unlimited_rule; | ||||
|     qi::real_parser<double, json_policy> double_; | ||||
| }; | ||||
| } | ||||
|  | ||||
| @ -2,9 +2,9 @@ | ||||
| #define MATCH_PARAMETERS_GRAMMAR_HPP | ||||
| 
 | ||||
| #include "engine/api/match_parameters.hpp" | ||||
| #include "server/api/base_parameters_grammar.hpp" | ||||
| #include "server/api/route_parameters_grammar.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -14,58 +14,34 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| 
 | ||||
| struct MatchParametersGrammar final : public BaseParametersGrammar | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
|     using StepsT = bool; | ||||
|     using TimestampsT = std::vector<unsigned>; | ||||
|     using GeometriesT = engine::api::RouteParameters::GeometriesType; | ||||
|     using OverviewT = engine::api::RouteParameters::OverviewType; | ||||
| 
 | ||||
|     MatchParametersGrammar() : BaseParametersGrammar(root_rule, parameters) | ||||
|     { | ||||
|         const auto set_geojson_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::GeoJSON; | ||||
|         }; | ||||
|         const auto set_polyline_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::Polyline; | ||||
|         }; | ||||
| 
 | ||||
|         const auto set_simplified_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Simplified; | ||||
|         }; | ||||
|         const auto set_full_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Full; | ||||
|         }; | ||||
|         const auto set_false_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::False; | ||||
|         }; | ||||
|         const auto set_steps = [this](const StepsT steps) { parameters.steps = steps; }; | ||||
|         const auto set_timestamps = [this](TimestampsT timestamps) { | ||||
|             parameters.timestamps = std::move(timestamps); | ||||
|         }; | ||||
| 
 | ||||
|         steps_rule = qi::lit("steps=") > qi::bool_; | ||||
|         geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | | ||||
|                           qi::lit("geometries=polyline")[set_polyline_type]; | ||||
|         overview_rule = qi::lit("overview=simplified")[set_simplified_type] | | ||||
|                         qi::lit("overview=full")[set_full_type] | | ||||
|                         qi::lit("overview=false")[set_false_type]; | ||||
|         timestamps_rule = qi::lit("timestamps=") > qi::uint_ % ";"; | ||||
|         match_rule = steps_rule[set_steps] | geometries_rule | overview_rule | | ||||
|                      timestamps_rule[set_timestamps]; | ||||
|         root_rule = | ||||
|             query_rule > -qi::lit(".json") > -(qi::lit("?") > (match_rule | base_rule) % '&'); | ||||
| } | ||||
| 
 | ||||
|     engine::api::MatchParameters parameters; | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::MatchParameters &)> | ||||
| struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Signature> | ||||
| { | ||||
|     using BaseGrammar = RouteParametersGrammar<Iterator, Signature>; | ||||
| 
 | ||||
|     MatchParametersGrammar() : BaseGrammar(root_rule) | ||||
|     { | ||||
|         timestamps_rule | ||||
|             = qi::lit("timestamps=") | ||||
|             > (qi::uint_ % ';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1] | ||||
|             ; | ||||
| 
 | ||||
|         root_rule | ||||
|             = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") | ||||
|             > -('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&') | ||||
|             ; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule, match_rule, geometries_rule, overview_rule; | ||||
|     qi::rule<Iterator, TimestampsT()> timestamps_rule; | ||||
|     qi::rule<Iterator, StepsT()> steps_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
|     qi::rule<Iterator, Signature> timestamps_rule; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "engine/api/nearest_parameters.hpp" | ||||
| #include "server/api/base_parameters_grammar.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -14,27 +14,34 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| 
 | ||||
| struct NearestParametersGrammar final : public BaseParametersGrammar | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
| 
 | ||||
|     NearestParametersGrammar() : BaseParametersGrammar(root_rule, parameters) | ||||
|     { | ||||
|         const auto set_number = [this](const unsigned number) { | ||||
|             parameters.number_of_results = number; | ||||
|         }; | ||||
|         nearest_rule = (qi::lit("number=") > qi::uint_)[set_number]; | ||||
|         root_rule = | ||||
|             query_rule > -qi::lit(".json") > -(qi::lit("?") > (nearest_rule | base_rule) % '&'); | ||||
| } | ||||
| 
 | ||||
|     engine::api::NearestParameters parameters; | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::NearestParameters &)> | ||||
| struct NearestParametersGrammar final : public BaseParametersGrammar<Iterator, Signature> | ||||
| { | ||||
|     using BaseGrammar = BaseParametersGrammar<Iterator, Signature>; | ||||
| 
 | ||||
|     NearestParametersGrammar() : BaseGrammar(root_rule) | ||||
|     { | ||||
|         nearest_rule | ||||
|             = (qi::lit("number=") > qi::uint_) | ||||
|               [ph::bind(&engine::api::NearestParameters::number_of_results, qi::_r1) = qi::_1] | ||||
|             ; | ||||
| 
 | ||||
|         root_rule | ||||
|             = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") | ||||
|             > -('?' > (nearest_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&') | ||||
|             ; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule; | ||||
|     qi::rule<Iterator> nearest_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
|     qi::rule<Iterator, Signature> nearest_rule; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -30,7 +30,8 @@ using is_parameter_t = | ||||
| // Starts parsing and iter and modifies it until iter == end or parsing failed
 | ||||
| template <typename ParameterT, | ||||
|           typename std::enable_if<detail::is_parameter_t<ParameterT>::value, int>::type = 0> | ||||
| boost::optional<ParameterT> parseParameters(std::string::iterator &iter, const std::string::iterator end); | ||||
| boost::optional<ParameterT> parseParameters(std::string::iterator &iter, | ||||
|                                             const std::string::iterator end); | ||||
| 
 | ||||
| // Copy on purpose because we need mutability
 | ||||
| template <typename ParameterT, | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "engine/api/route_parameters.hpp" | ||||
| #include "server/api/base_parameters_grammar.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -14,64 +14,66 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| 
 | ||||
| struct RouteParametersGrammar : public BaseParametersGrammar | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
|     using StepsT = bool; | ||||
|     using AlternativeT = bool; | ||||
|     using GeometriesT = engine::api::RouteParameters::GeometriesType; | ||||
|     using OverviewT = engine::api::RouteParameters::OverviewType; | ||||
|     using UturnsT = bool; | ||||
| 
 | ||||
|     RouteParametersGrammar() : BaseParametersGrammar(root_rule, parameters) | ||||
|     { | ||||
|         const auto set_geojson_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::GeoJSON; | ||||
|         }; | ||||
|         const auto set_polyline_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::Polyline; | ||||
|         }; | ||||
| 
 | ||||
|         const auto set_simplified_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Simplified; | ||||
|         }; | ||||
|         const auto set_full_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Full; | ||||
|         }; | ||||
|         const auto set_false_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::False; | ||||
|         }; | ||||
|         const auto set_steps = [this](const StepsT steps) { parameters.steps = steps; }; | ||||
|         const auto set_alternatives = [this](const AlternativeT alternatives) { | ||||
|             parameters.alternatives = alternatives; | ||||
|         }; | ||||
|         const auto set_continue_straight = [this](UturnsT continue_straight) { parameters.continue_straight = std::move(continue_straight); }; | ||||
| 
 | ||||
|         alternatives_rule = qi::lit("alternatives=") > qi::bool_; | ||||
|         steps_rule = qi::lit("steps=") > qi::bool_; | ||||
|         geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | | ||||
|                           qi::lit("geometries=polyline")[set_polyline_type]; | ||||
|         overview_rule = qi::lit("overview=simplified")[set_simplified_type] | | ||||
|                         qi::lit("overview=full")[set_full_type] | | ||||
|                         qi::lit("overview=false")[set_false_type]; | ||||
|         continue_straight_rule = qi::lit("continue_straight=default") | (qi::lit("continue_straight=") > qi::bool_)[set_continue_straight]; | ||||
|         route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule | | ||||
|                      overview_rule | continue_straight_rule; | ||||
| 
 | ||||
|         root_rule = | ||||
|             query_rule > -qi::lit(".json") > -(qi::lit("?") > (route_rule | base_rule) % '&'); | ||||
| } | ||||
| 
 | ||||
|     engine::api::RouteParameters parameters; | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::RouteParameters &)> | ||||
| struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature> | ||||
| { | ||||
|     using BaseGrammar = BaseParametersGrammar<Iterator, Signature>; | ||||
| 
 | ||||
|     RouteParametersGrammar() : RouteParametersGrammar(root_rule) | ||||
|     { | ||||
|         route_rule | ||||
|             = (qi::lit("alternatives=") > qi::bool_[ph::bind(&engine::api::RouteParameters::alternatives, qi::_r1) = qi::_1]) | ||||
|             | (qi::lit("continue_straight=") | ||||
|                > (qi::lit("default") | ||||
|                  | qi::bool_[ph::bind(&engine::api::RouteParameters::continue_straight, qi::_r1) = qi::_1])) | ||||
|             ; | ||||
| 
 | ||||
|         root_rule | ||||
|             = query_rule(qi::_r1) > -qi::lit(".json") | ||||
|             > -('?' > (route_rule(qi::_r1) | base_rule(qi::_r1)) % '&') | ||||
|             ; | ||||
|     } | ||||
| 
 | ||||
|     RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_) | ||||
|     { | ||||
|         geometries_type.add | ||||
|             ("geojson", engine::api::RouteParameters::GeometriesType::GeoJSON) | ||||
|             ("polyline", engine::api::RouteParameters::GeometriesType::Polyline) | ||||
|             ; | ||||
| 
 | ||||
|         overview_type.add | ||||
|             ("simplified", engine::api::RouteParameters::OverviewType::Simplified) | ||||
|             ("full", engine::api::RouteParameters::OverviewType::Full) | ||||
|             ("false", engine::api::RouteParameters::OverviewType::False) | ||||
|             ; | ||||
| 
 | ||||
|         base_rule = | ||||
|             BaseGrammar::base_rule(qi::_r1) | ||||
|             | (qi::lit("steps=") > qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1]) | ||||
|             | (qi::lit("geometries=") > geometries_type[ph::bind(&engine::api::RouteParameters::geometries, qi::_r1) = qi::_1]) | ||||
|             | (qi::lit("overview=") > overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1]) | ||||
|             ; | ||||
| 
 | ||||
|         query_rule = BaseGrammar::query_rule(qi::_r1); | ||||
|     } | ||||
| 
 | ||||
|   protected: | ||||
|     qi::rule<Iterator, Signature> base_rule; | ||||
|     qi::rule<Iterator, Signature> query_rule; | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule; | ||||
|     qi::rule<Iterator> route_rule, geometries_rule, overview_rule; | ||||
|     qi::rule<Iterator, UturnsT()> continue_straight_rule; | ||||
|     qi::rule<Iterator, StepsT()> steps_rule; | ||||
|     qi::rule<Iterator, AlternativeT()> alternatives_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
|     qi::rule<Iterator, Signature> route_rule; | ||||
| 
 | ||||
|     qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type; | ||||
|     qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "engine/api/table_parameters.hpp" | ||||
| #include "server/api/base_parameters_grammar.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -14,43 +14,53 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| 
 | ||||
| struct TableParametersGrammar final : public BaseParametersGrammar | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
|     using SourcesT = std::vector<std::size_t>; | ||||
|     using DestinationsT = std::vector<std::size_t>; | ||||
| 
 | ||||
|     TableParametersGrammar() : BaseParametersGrammar(root_rule, parameters) | ||||
|     { | ||||
|         const auto set_destiantions = [this](DestinationsT dests) { | ||||
|             parameters.destinations = std::move(dests); | ||||
|         }; | ||||
|         const auto set_sources = [this](SourcesT sources) { | ||||
|             parameters.sources = std::move(sources); | ||||
|         }; | ||||
| // TODO: ulonglong -> size_t not only on Windows but on all 32 bit platforms; unsupported anyway as of now
 | ||||
| #ifdef WIN32 | ||||
|         destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_long % ";")[set_destiantions]); | ||||
|         sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_long % ";")[set_sources]); | ||||
| #else | ||||
|         destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]); | ||||
|         sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]); | ||||
| #endif | ||||
|         table_rule = destinations_rule | sources_rule; | ||||
| 
 | ||||
|         root_rule = | ||||
|             query_rule > -qi::lit(".json") > -(qi::lit("?") > (table_rule | base_rule) % '&'); | ||||
| } | ||||
| 
 | ||||
|     engine::api::TableParameters parameters; | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::TableParameters &)> | ||||
| struct TableParametersGrammar final : public BaseParametersGrammar<Iterator, Signature> | ||||
| { | ||||
|     using BaseGrammar = BaseParametersGrammar<Iterator, Signature>; | ||||
| 
 | ||||
|     TableParametersGrammar() : BaseGrammar(root_rule) | ||||
|     { | ||||
| #ifdef BOOST_HAS_LONG_LONG | ||||
|         if (std::is_same<std::size_t, unsigned long long>::value) | ||||
|             size_t_ = qi::ulong_long; | ||||
|         else | ||||
|             size_t_ = qi::ulong_; | ||||
| #else | ||||
|         size_t_ = qi::ulong_; | ||||
| #endif | ||||
| 
 | ||||
|         destinations_rule | ||||
|             = qi::lit("destinations=") | ||||
|             > (qi::lit("all") | (size_t_ % ';')[ph::bind(&engine::api::TableParameters::destinations, qi::_r1) = qi::_1]) | ||||
|             ; | ||||
| 
 | ||||
|         sources_rule | ||||
|             = qi::lit("sources=") | ||||
|             > (qi::lit("all") | (size_t_ % ';')[ph::bind(&engine::api::TableParameters::sources, qi::_r1) = qi::_1]) | ||||
|             ; | ||||
| 
 | ||||
|         table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1); | ||||
| 
 | ||||
|         root_rule | ||||
|             = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") | ||||
|             > -('?' > (table_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&') | ||||
|             ; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule; | ||||
|     qi::rule<Iterator> table_rule; | ||||
|     qi::rule<Iterator> sources_rule; | ||||
|     qi::rule<Iterator> destinations_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
|     qi::rule<Iterator, Signature> table_rule; | ||||
|     qi::rule<Iterator, Signature> sources_rule; | ||||
|     qi::rule<Iterator, Signature> destinations_rule; | ||||
|     qi::rule<Iterator, std::size_t()> size_t_; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
| #include "engine/hint.hpp" | ||||
| #include "engine/polyline_compressor.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/phoenix.hpp> | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| #include <string> | ||||
| @ -18,28 +18,29 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace qi = boost::spirit::qi; | ||||
| struct TileParametersGrammar final : boost::spirit::qi::grammar<std::string::iterator> | ||||
| namespace | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
| namespace ph = boost::phoenix; | ||||
| namespace qi = boost::spirit::qi; | ||||
| } | ||||
| 
 | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::TileParameters &)> | ||||
| struct TileParametersGrammar final : boost::spirit::qi::grammar<Iterator, Signature> | ||||
| { | ||||
|     TileParametersGrammar() : TileParametersGrammar::base_type(root_rule) | ||||
|     { | ||||
|         const auto set_x = [this](const unsigned x_) { parameters.x = x_; }; | ||||
|         const auto set_y = [this](const unsigned y_) { parameters.y = y_; }; | ||||
|         const auto set_z = [this](const unsigned z_) { parameters.z = z_; }; | ||||
| 
 | ||||
|         query_rule = qi::lit("tile(") > qi::uint_[set_x]             //
 | ||||
|                      > qi::lit(",") > qi::uint_[set_y] >             //
 | ||||
|                      qi::lit(",") > qi::uint_[set_z] > qi::lit(")"); //
 | ||||
| 
 | ||||
|         root_rule = query_rule > qi::lit(".mvt"); | ||||
|         root_rule | ||||
|             = qi::lit("tile(") | ||||
|             > qi::uint_[ph::bind(&engine::api::TileParameters::x, qi::_r1) = qi::_1] > ',' | ||||
|             > qi::uint_[ph::bind(&engine::api::TileParameters::y, qi::_r1) = qi::_1] > ',' | ||||
|             > qi::uint_[ph::bind(&engine::api::TileParameters::z, qi::_r1) = qi::_1] | ||||
|             > qi::lit(").mvt") | ||||
|             ; | ||||
|     } | ||||
|     engine::api::TileParameters parameters; | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule; | ||||
|     qi::rule<Iterator> query_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -2,9 +2,8 @@ | ||||
| #define TRIP_PARAMETERS_GRAMMAR_HPP | ||||
| 
 | ||||
| #include "engine/api/trip_parameters.hpp" | ||||
| #include "server/api/base_parameters_grammar.hpp" | ||||
| #include "server/api/route_parameters_grammar.hpp" | ||||
| 
 | ||||
| //#define BOOST_SPIRIT_DEBUG
 | ||||
| #include <boost/spirit/include/qi.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -14,52 +13,27 @@ namespace server | ||||
| namespace api | ||||
| { | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| namespace qi = boost::spirit::qi; | ||||
| 
 | ||||
| struct TripParametersGrammar final : public BaseParametersGrammar | ||||
| { | ||||
|     using Iterator = std::string::iterator; | ||||
|     using StepsT = bool; | ||||
|     using GeometriesT = engine::api::RouteParameters::GeometriesType; | ||||
|     using OverviewT = engine::api::RouteParameters::OverviewType; | ||||
| 
 | ||||
|     TripParametersGrammar() : BaseParametersGrammar(root_rule, parameters) | ||||
|     { | ||||
|         const auto set_geojson_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::GeoJSON; | ||||
|         }; | ||||
|         const auto set_polyline_type = [this] { | ||||
|             parameters.geometries = engine::api::RouteParameters::GeometriesType::Polyline; | ||||
|         }; | ||||
| 
 | ||||
|         const auto set_simplified_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Simplified; | ||||
|         }; | ||||
|         const auto set_full_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::Full; | ||||
|         }; | ||||
|         const auto set_false_type = [this] { | ||||
|             parameters.overview = engine::api::RouteParameters::OverviewType::False; | ||||
|         }; | ||||
|         const auto set_steps = [this](const StepsT steps) { parameters.steps = steps; }; | ||||
| 
 | ||||
|         steps_rule = qi::lit("steps=") > qi::bool_; | ||||
|         geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | | ||||
|                           qi::lit("geometries=polyline")[set_polyline_type]; | ||||
|         overview_rule = qi::lit("overview=simplified")[set_simplified_type] | | ||||
|                         qi::lit("overview=full")[set_full_type] | | ||||
|                         qi::lit("overview=false")[set_false_type]; | ||||
|         trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule; | ||||
| 
 | ||||
|         root_rule = | ||||
|             query_rule > -qi::lit(".json") > -(qi::lit("?") > (trip_rule | base_rule) % '&'); | ||||
| } | ||||
| 
 | ||||
|     engine::api::TripParameters parameters; | ||||
| template <typename Iterator = std::string::iterator, | ||||
|           typename Signature = void(engine::api::TripParameters &)> | ||||
| struct TripParametersGrammar final : public RouteParametersGrammar<Iterator, Signature> | ||||
| { | ||||
|     using BaseGrammar = RouteParametersGrammar<Iterator, Signature>; | ||||
| 
 | ||||
|     TripParametersGrammar() : BaseGrammar(root_rule) | ||||
|     { | ||||
|         root_rule | ||||
|             = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") | ||||
|             > -('?' > (BaseGrammar::base_rule(qi::_r1)) % '&') | ||||
|             ; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     qi::rule<Iterator> root_rule, trip_rule, geometries_rule, overview_rule; | ||||
|     qi::rule<Iterator, StepsT()> steps_rule; | ||||
|     qi::rule<Iterator, Signature> root_rule; | ||||
| }; | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -72,12 +72,9 @@ struct SegmentID | ||||
|     } | ||||
| 
 | ||||
|     NodeID  id              : 31; | ||||
|     bool enabled : 1; | ||||
|     std::uint32_t enabled   :  1; | ||||
| }; | ||||
| 
 | ||||
| // bit-fields are broken on Windows
 | ||||
| #ifndef _MSC_VER | ||||
| static_assert(sizeof(SegmentID) == 4, "SegmentID needs to be 4 bytes big"); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* TYPEDEFS_H */ | ||||
|  | ||||
| @ -19,28 +19,28 @@ namespace api | ||||
| namespace detail | ||||
| { | ||||
| template <typename T> | ||||
| using is_grammar_t = std::integral_constant<bool, | ||||
|                                             std::is_base_of<BaseParametersGrammar, T>::value || | ||||
|                                                 std::is_same<TileParametersGrammar, T>::value>; | ||||
| using is_grammar_t = std::integral_constant<bool, std::is_same<RouteParametersGrammar<>, T>::value || | ||||
|    std::is_same<TableParametersGrammar<>, T>::value || std::is_same<NearestParametersGrammar<>, T>::value || | ||||
|    std::is_same<TripParametersGrammar<>, T>::value || std::is_same<MatchParametersGrammar<>, T>::value || | ||||
|    std::is_same<TileParametersGrammar<>, T>::value>; | ||||
| 
 | ||||
| template <typename ParameterT, | ||||
|           typename GrammarT, | ||||
| template <typename ParameterT, typename GrammarT, | ||||
|           typename std::enable_if<detail::is_parameter_t<ParameterT>::value, int>::type = 0, | ||||
|           typename std::enable_if<detail::is_grammar_t<GrammarT>::value, int>::type = 0> | ||||
| boost::optional<ParameterT> parseParameters(std::string::iterator &iter, | ||||
|                                             const std::string::iterator end) | ||||
| boost::optional<ParameterT> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     using It = std::decay<decltype(iter)>::type; | ||||
| 
 | ||||
|     GrammarT grammar; | ||||
|     static const GrammarT grammar; | ||||
| 
 | ||||
|     try | ||||
|     { | ||||
|         const auto ok = boost::spirit::qi::parse(iter, end, grammar); | ||||
|         ParameterT parameters; | ||||
|         const auto ok = boost::spirit::qi::parse(iter, end, grammar(boost::phoenix::ref(parameters))); | ||||
| 
 | ||||
|         // return move(a.b) is needed to move b out of a and then return the rvalue by implicit move
 | ||||
|         if (ok && iter == end) | ||||
|             return std::move(grammar.parameters); | ||||
|             return std::move(parameters); | ||||
|     } | ||||
|     catch (const qi::expectation_failure<It> &failure) | ||||
|     { | ||||
| @ -54,46 +54,39 @@ boost::optional<ParameterT> parseParameters(std::string::iterator &iter, | ||||
| } // ns detail
 | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::RouteParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                               const std::string::iterator end) | ||||
| boost::optional<engine::api::RouteParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::RouteParameters, RouteParametersGrammar>(iter, end); | ||||
|     return detail::parseParameters<engine::api::RouteParameters, RouteParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::TableParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                               const std::string::iterator end) | ||||
| boost::optional<engine::api::TableParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::TableParameters, TableParametersGrammar>(iter, end); | ||||
|     return detail::parseParameters<engine::api::TableParameters, TableParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::NearestParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                                 const std::string::iterator end) | ||||
| boost::optional<engine::api::NearestParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::NearestParameters, NearestParametersGrammar>(iter, | ||||
|                                                                                              end); | ||||
|     return detail::parseParameters<engine::api::NearestParameters, NearestParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::TripParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                              const std::string::iterator end) | ||||
| boost::optional<engine::api::TripParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::TripParameters, TripParametersGrammar>(iter, end); | ||||
|     return detail::parseParameters<engine::api::TripParameters, TripParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::MatchParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                               const std::string::iterator end) | ||||
| boost::optional<engine::api::MatchParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar>(iter, end); | ||||
|     return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| boost::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter, | ||||
|                                                              const std::string::iterator end) | ||||
| boost::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter, const std::string::iterator end) | ||||
| { | ||||
|     return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar>(iter, end); | ||||
|     return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar<>>(iter, end); | ||||
| } | ||||
| 
 | ||||
| } // ns api
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| #include "extractor/raster_source.hpp" | ||||
| #include "util/typedefs.hpp" | ||||
| #include "util/exception.hpp" | ||||
| #include "util/typedefs.hpp" | ||||
| 
 | ||||
| #include <osrm/coordinate.hpp> | ||||
| 
 | ||||
| @ -15,14 +15,10 @@ using namespace osrm::extractor; | ||||
| int normalize(double coord) { return static_cast<int>(coord * COORDINATE_PRECISION); } | ||||
| 
 | ||||
| #define CHECK_QUERY(source_id, lon, lat, expected)                                                 \ | ||||
|     BOOST_CHECK_EQUAL(                                                                             \ | ||||
|         sources.getRasterDataFromSource(source_id, lon, lat).datum,          \ | ||||
|         expected) | ||||
|     BOOST_CHECK_EQUAL(sources.getRasterDataFromSource(source_id, lon, lat).datum, expected) | ||||
| 
 | ||||
| #define CHECK_INTERPOLATE(source_id, lon, lat, expected)                                           \ | ||||
|     BOOST_CHECK_EQUAL(                                                                             \ | ||||
|         sources.getRasterInterpolateFromSource(source_id, lon, lat).datum,   \ | ||||
|         expected) | ||||
|     BOOST_CHECK_EQUAL(sources.getRasterInterpolateFromSource(source_id, lon, lat).datum, expected) | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(raster_test) | ||||
| { | ||||
|  | ||||
| @ -45,9 +45,9 @@ BOOST_AUTO_TEST_CASE(invalid_route_urls) | ||||
|     BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&hints=foo"), | ||||
|                       29UL); | ||||
|     BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&geometries=foo"), | ||||
|                       22UL); | ||||
|                       34UL); | ||||
|     BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&overview=foo"), | ||||
|                       22L); | ||||
|                       32L); | ||||
|     BOOST_CHECK_EQUAL( | ||||
|         testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&alternatives=foo"), 36UL); | ||||
|     BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(""), 0); | ||||
| @ -273,6 +273,16 @@ BOOST_AUTO_TEST_CASE(valid_match_urls) | ||||
|     CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings); | ||||
|     CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses); | ||||
|     CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates); | ||||
| 
 | ||||
|     MatchParameters reference_2{}; | ||||
|     reference_2.coordinates = coords_1; | ||||
|     reference_2.timestamps = {5, 6}; | ||||
|     auto result_2 = parseParameters<MatchParameters>("1,2;3,4?timestamps=5;6"); | ||||
|     BOOST_CHECK(result_2); | ||||
|     CHECK_EQUAL_RANGE(reference_2.timestamps, result_2->timestamps); | ||||
|     CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings); | ||||
|     CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses); | ||||
|     CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(valid_nearest_urls) | ||||
| @ -287,6 +297,16 @@ BOOST_AUTO_TEST_CASE(valid_nearest_urls) | ||||
|     CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings); | ||||
|     CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses); | ||||
|     CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates); | ||||
| 
 | ||||
|     NearestParameters reference_2{}; | ||||
|     reference_2.coordinates = coords_1; | ||||
|     reference_2.number_of_results = 42; | ||||
|     auto result_2 = parseParameters<NearestParameters>("1,2?number=42"); | ||||
|     BOOST_CHECK(result_2); | ||||
|     BOOST_CHECK_EQUAL(reference_2.number_of_results, result_2->number_of_results); | ||||
|     CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings); | ||||
|     CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses); | ||||
|     CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(valid_tile_urls) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user