From 150ba94d14d89d1187e010464a63eaddf10e2225 Mon Sep 17 00:00:00 2001 From: Bruno Iljazovic Date: Thu, 18 Sep 2025 20:25:30 +0200 Subject: [PATCH] Drop Spirit dependency Summary: Ref #36 Reviewers: ivica Reviewed By: ivica Subscribers: miljen Differential Revision: https://repo.mireo.local/D37107 --- CMakeLists.txt | 3 - build.jam | 3 - .../boost/mqtt5/impl/codecs/base_decoders.hpp | 441 +++++++----------- .../mqtt5/impl/codecs/message_decoders.hpp | 64 +-- include/boost/mqtt5/impl/endpoints.hpp | 94 ++-- test/cmake_subdir_test/CMakeLists.txt | 14 +- test/unit/endpoints.cpp | 4 +- vcpkg.json | 3 +- 8 files changed, 250 insertions(+), 376 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47a9fe3..8944f4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,12 +49,9 @@ else() Boost::container Boost::core Boost::endian - Boost::fusion - Boost::optional Boost::random Boost::range Boost::smart_ptr - Boost::spirit Boost::system Boost::type_traits Threads::Threads diff --git a/build.jam b/build.jam index d44988d..f4bec20 100644 --- a/build.jam +++ b/build.jam @@ -13,12 +13,9 @@ constant boost_dependencies : /boost/container//boost_container /boost/core//boost_core /boost/endian//boost_endian - /boost/fusion//boost_fusion - /boost/optional//boost_optional /boost/random//boost_random /boost/range//boost_range /boost/smart_ptr//boost_smart_ptr - /boost/spirit//boost_spirit /boost/system//boost_system /boost/type_traits//boost_type_traits ; diff --git a/include/boost/mqtt5/impl/codecs/base_decoders.hpp b/include/boost/mqtt5/impl/codecs/base_decoders.hpp index 61640c7..c6ee082 100644 --- a/include/boost/mqtt5/impl/codecs/base_decoders.hpp +++ b/include/boost/mqtt5/impl/codecs/base_decoders.hpp @@ -12,11 +12,7 @@ #include -#include -#include -#include -#include -#include +#include #include #include @@ -24,217 +20,49 @@ namespace boost::mqtt5::decoders { -namespace x3 = boost::spirit::x3; - -template -struct convert { using type = T; }; - -template -struct convert> { - using type = std::tuple::type...>; -}; - -template -struct convert> { - using type = std::optional; -}; - -template -struct convert> { - using type = std::vector::type>; -}; - -template -constexpr auto as(Parser&& p) { - return x3::rule{} = std::forward(p); -} - - template auto type_parse(It& first, const It last, const Parser& p) { - using ctx_type = decltype(x3::make_context(std::declval())); - using attr_type = typename x3::traits::attribute_of::type; - - using rv_type = typename convert::type; + using rv_type = typename Parser::attribute_type; std::optional rv; rv_type value {}; - if (x3::phrase_parse(first, last, as(p), x3::eps(false), value)) - rv = std::move(value); - return rv; -} - - -template -auto type_parse(It& first, const It last, const Parser& p) { - std::optional rv; - AttributeType value {}; - if (x3::phrase_parse(first, last, as(p), x3::eps(false), value)) + if (p.parse(first, last, value)) rv = std::move(value); return rv; } namespace basic { -template -constexpr auto to(T& arg) { - return [&](auto& ctx) { - using ctx_type = decltype(ctx); - using attr_type = decltype(x3::_attr(std::declval())); - if constexpr (detail::is_boost_iterator) - arg = T { x3::_attr(ctx).begin(), x3::_attr(ctx).end() }; - else - arg = x3::_attr(ctx); - }; -} +template +struct int_parser { + using attribute_type = Attr; -template -class scope_limit {}; - -template -class scope_limit< - LenParser, Subject, - std::enable_if_t::value> -> : - public x3::unary_parser> -{ - using base_type = x3::unary_parser>; - LenParser _lp; -public: - using ctx_type = - decltype(x3::make_context(std::declval())); - using attribute_type = - typename x3::traits::attribute_of::type; - - static bool const has_attribute = true; - - scope_limit(const LenParser& lp, const Subject& subject) : - base_type(subject), _lp(lp) - {} - - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx& rctx, Attr& attr - ) const { - - It iter = first; - typename x3::traits::attribute_of::type len; - if (!_lp.parse(iter, last, ctx, rctx, len)) - return false; - if (iter + len > last) + template + bool parse(It& first, const It last, Attr& attr) const { + constexpr size_t byte_size = sizeof(Attr); + if (std::distance(first, last) < static_cast(byte_size)) return false; - if (!base_type::subject.parse(iter, iter + len, ctx, rctx, attr)) - return false; + using namespace boost::endian; + attr = endian_load( + reinterpret_cast(static_cast(&*first)) + ); + first += sizeof(Attr); - first = iter; return true; } }; -template -class scope_limit< - Size, Subject, - std::enable_if_t> -> : - public x3::unary_parser> -{ - using base_type = x3::unary_parser>; - size_t _limit; -public: - using ctx_type = - decltype(x3::make_context(std::declval())); - using attribute_type = - typename x3::traits::attribute_of::type; +inline constexpr int_parser byte_; +inline constexpr int_parser word_; +inline constexpr int_parser dword_; - static bool const has_attribute = true; - - scope_limit(Size limit, const Subject& subject) : - base_type(subject), _limit(limit) - {} - - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx& rctx, Attr& attr - ) const { - - It iter = first; - if (iter + _limit > last) - return false; - - if (!base_type::subject.parse(iter, iter + _limit, ctx, rctx, attr)) - return false; - - first = iter; - return true; - } -}; - -template -struct scope_limit_gen { - template - auto operator[](const Subject& p) const { - return scope_limit { _lp, x3::as_parser(p) }; - } - LenParser _lp; -}; - -template -struct scope_limit_gen< - Size, - std::enable_if_t> -> { - template - auto operator[](const Subject& p) const { - return scope_limit { limit, x3::as_parser(p) }; - } - Size limit; -}; - -template < - typename Parser, - std::enable_if_t::value, bool> = true -> -scope_limit_gen scope_limit_(const Parser& p) { - return { p }; -} - -template < - typename Size, - std::enable_if_t, bool> = true -> -scope_limit_gen scope_limit_(Size limit) { - return { limit }; -} - -struct verbatim_parser : x3::parser { - using attribute_type = std::string; - static bool const has_attribute = true; - - template - bool parse(It& first, const It last, const Ctx&, RCtx&, Attr& attr) const { - attr = std::string { first, last }; - first = last; - return true; - } -}; - -constexpr auto verbatim_ = verbatim_parser{}; - -struct varint_parser : x3::parser { +struct varint_parser { using attribute_type = int32_t; - static bool const has_attribute = true; - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx&, Attr& attr - ) const { - - It iter = first; - x3::skip_over(iter, last, ctx); + template + bool parse(It& first, const It last, int32_t& attr) const { + auto iter = first; if (iter == last) return false; @@ -262,22 +90,17 @@ struct varint_parser : x3::parser { } }; -constexpr varint_parser varint_{}; +inline constexpr varint_parser varint_; -struct len_prefix_parser : x3::parser { +struct len_prefix_parser { using attribute_type = std::string; - static bool const has_attribute = true; - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx& rctx, Attr& attr - ) const { - It iter = first; - x3::skip_over(iter, last, ctx); + template + bool parse(It& first, const It last, std::string& attr) const { + auto iter = first; - typename x3::traits::attribute_of::type len; - if (x3::big_word.parse(iter, last, ctx, rctx, len)) { + typename decltype(word_)::attribute_type len; + if (word_.parse(iter, last, len)) { if (std::distance(iter, last) < len) return false; } @@ -290,44 +113,25 @@ struct len_prefix_parser : x3::parser { } }; -constexpr len_prefix_parser utf8_ {}; -constexpr len_prefix_parser binary_ {}; - -/* - Boost Spirit incorrectly deduces atribute type for a parser of the form - (eps(a) | parser1) >> (eps(b) | parser) - and we had to create if_ parser to remedy the issue -*/ +inline constexpr len_prefix_parser utf8_ {}; +inline constexpr len_prefix_parser binary_ {}; template -class conditional_parser : - public x3::unary_parser> { +struct conditional_parser { + using subject_attr_type = typename Subject::attribute_type; + using attribute_type = std::optional; - using base_type = x3::unary_parser>; - bool _condition; -public: - using ctx_type = - decltype(x3::make_context(std::declval())); - using subject_attr_type = - typename x3::traits::attribute_of::type; + Subject p; + bool condition; - using attribute_type = boost::optional; - static bool const has_attribute = true; - - conditional_parser(const Subject& s, bool condition) : - base_type(s), _condition(condition) {} - - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx& rctx, Attr& attr - ) const { - if (!_condition) + template + bool parse(It& first, const It last, attribute_type& attr) const { + if (!condition) return true; - It iter = first; + auto iter = first; subject_attr_type sattr {}; - if (!base_type::subject.parse(iter, last, ctx, rctx, sattr)) + if (!p.parse(iter, last, sattr)) return false; attr.emplace(std::move(sattr)); @@ -340,59 +144,155 @@ struct conditional_gen { bool _condition; template - auto operator[](const Subject& p) const { - return conditional_parser { p, _condition }; + conditional_parser operator[](const Subject& p) const { + return { p, _condition }; } }; -inline conditional_gen if_(bool condition) { +constexpr conditional_gen if_(bool condition) { return { condition }; } +struct verbatim_parser { + using attribute_type = std::string; + + template + bool parse(It& first, const It last, std::string& attr) const { + attr = std::string { first, last }; + first = last; + return true; + } +}; + +inline constexpr auto verbatim_ = verbatim_parser{}; + +template +struct seq_parser { + using attribute_type = std::tuple; + + std::tuple parsers; + + template + bool parse(It& first, const It last, attribute_type& attr) const { + return parse_impl( + first, last, attr, std::make_index_sequence{} + ); + } + +private: + template + bool parse_impl( + It& first, const It last, attribute_type& attr, + std::index_sequence + ) const { + auto iter = first; + bool rv = ( + std::get(parsers).parse(iter, last, std::get(attr)) + && ... + ); + if (rv) + first = iter; + return rv; + } +}; + +template +constexpr seq_parser operator>>( + const seq_parser& p1, const P2& p2 +) { + return { std::tuple_cat(p1.parsers, std::make_tuple(p2)) }; +} + +template +constexpr seq_parser operator>>(const P1& p1, const P2& p2) { + return { std::make_tuple(p1, p2) }; +} + +template +struct attr_parser { + using attribute_type = Attr; + + Attr attr; + + template + bool parse(It&, const It, Attr& attr) const { + attr = this->attr; + return true; + } +}; + +template +constexpr attr_parser attr(const Attr& val) { + return { val }; +} + +template +struct plus_parser { + using subject_attr_type = typename Subject::attribute_type; + using attribute_type = std::vector; + + Subject p; + + template + bool parse(It& first, const It last, Attr& attr) const { + bool success = false; + while (first < last) { + subject_attr_type sattr {}; + auto iter = first; + if (!p.parse(iter, last, sattr)) break; + + success = true; + first = iter; + attr.push_back(std::move(sattr)); + } + + return success; + } +}; + +template +constexpr plus_parser

operator+(const P& p) { + return { p }; +} + } // end namespace basic - namespace prop { -namespace basic = boost::mqtt5::decoders::basic; - namespace detail { -template -bool parse_to_prop( - It& iter, const It last, - const Ctx& ctx, RCtx& rctx, Prop& prop -) { +template +bool parse_to_prop(It& iter, const It last, Prop& prop) { using namespace boost::mqtt5::detail; using prop_type = std::remove_reference_t; bool rv = false; if constexpr (std::is_same_v) - rv = x3::byte_.parse(iter, last, ctx, rctx, prop); + rv = basic::byte_.parse(iter, last, prop); else if constexpr (std::is_same_v) - rv = x3::big_word.parse(iter, last, ctx, rctx, prop); + rv = basic::word_.parse(iter, last, prop); else if constexpr (std::is_same_v) - rv = basic::varint_.parse(iter, last, ctx, rctx, prop); + rv = basic::varint_.parse(iter, last, prop); else if constexpr (std::is_same_v) - rv = x3::big_dword.parse(iter, last, ctx, rctx, prop); + rv = basic::dword_.parse(iter, last, prop); else if constexpr (std::is_same_v) - rv = basic::utf8_.parse(iter, last, ctx, rctx, prop); + rv = basic::utf8_.parse(iter, last, prop); else if constexpr (is_optional) { typename prop_type::value_type val; - rv = parse_to_prop(iter, last, ctx, rctx, val); + rv = parse_to_prop(iter, last, val); if (rv) prop.emplace(std::move(val)); } else if constexpr (is_pair) { - rv = parse_to_prop(iter, last, ctx, rctx, prop.first); - rv = parse_to_prop(iter, last, ctx, rctx, prop.second); + rv = parse_to_prop(iter, last, prop.first); + rv = parse_to_prop(iter, last, prop.second); } else if constexpr (is_vector || is_small_vector) { typename std::remove_reference_t::value_type value; - rv = parse_to_prop(iter, last, ctx, rctx, value); + rv = parse_to_prop(iter, last, value); if (rv) prop.push_back(std::move(value)); } @@ -402,28 +302,21 @@ bool parse_to_prop( } // end namespace detail template -class prop_parser : public x3::parser> { -public: +struct prop_parser { using attribute_type = Props; - static bool const has_attribute = true; - template - bool parse( - It& first, const It last, - const Ctx& ctx, RCtx& rctx, Attr& attr - ) const { - - It iter = first; - x3::skip_over(iter, last, ctx); + template + bool parse(It& first, const It last, Props& attr) const { + auto iter = first; if (iter == last) return true; int32_t props_length; - if (!basic::varint_.parse(iter, last, ctx, rctx, props_length)) + if (!basic::varint_.parse(iter, last, props_length)) return false; - const It scoped_last = iter + props_length; + const auto scoped_last = iter + props_length; // attr = Props{}; while (iter < scoped_last) { @@ -433,10 +326,8 @@ public: attr.apply_on( prop_id, - [&rv, &iter, scoped_last, &ctx, &rctx](auto& prop) { - rv = detail::parse_to_prop( - iter, scoped_last, ctx, rctx, prop - ); + [&rv, &iter, scoped_last](auto& prop) { + rv = detail::parse_to_prop(iter, scoped_last, prop); } ); @@ -450,13 +341,11 @@ public: } }; - template constexpr auto props_ = prop_parser {}; } // end namespace prop - } // end namespace boost::mqtt5::decoders #endif // !BOOST_MQTT5_BASE_DECODERS_HPP diff --git a/include/boost/mqtt5/impl/codecs/message_decoders.hpp b/include/boost/mqtt5/impl/codecs/message_decoders.hpp index ecdf7d4..f761179 100644 --- a/include/boost/mqtt5/impl/codecs/message_decoders.hpp +++ b/include/boost/mqtt5/impl/codecs/message_decoders.hpp @@ -32,7 +32,7 @@ using fixed_header = std::tuple< inline std::optional decode_fixed_header( byte_citer& it, const byte_citer last ) { - auto fixed_header_ = x3::byte_ >> basic::varint_; + constexpr auto fixed_header_ = basic::byte_ >> basic::varint_; return type_parse(it, last, fixed_header_); } @@ -41,7 +41,7 @@ using packet_id = uint16_t; inline std::optional decode_packet_id( byte_citer& it ) { - auto packet_id_ = x3::big_word; + constexpr auto packet_id_ = basic::word_; return type_parse(it, it + sizeof(uint16_t), packet_id_); } @@ -58,11 +58,11 @@ using connect_message = std::tuple< inline std::optional decode_connect( uint32_t remain_length, byte_citer& it ) { - auto var_header_ = + constexpr auto var_header_ = basic::utf8_ >> // MQTT - x3::byte_ >> // (num 5) - x3::byte_ >> // conn_flags_ - x3::big_word >> // keep_alive + basic::byte_ >> // (num 5) + basic::byte_ >> // conn_flags_ + basic::word_ >> // keep_alive prop::props_; const byte_citer end = it + remain_length; @@ -124,9 +124,7 @@ using connack_message = std::tuple< inline std::optional decode_connack( uint32_t remain_length, byte_citer& it ) { - auto connack_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> x3::byte_ >> prop::props_ - ]; + constexpr auto connack_ = basic::byte_ >> basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, connack_); } @@ -144,10 +142,10 @@ inline std::optional decode_publish( uint8_t flags = control_byte & 0b1111; auto qos = qos_e((flags >> 1) & 0b11); - auto publish_ = basic::scope_limit_(remain_length)[ - basic::utf8_ >> basic::if_(qos != qos_e::at_most_once)[x3::big_word] >> - x3::attr(flags) >> prop::props_ >> basic::verbatim_ - ]; + auto publish_ = + basic::utf8_ >> basic::if_(qos != qos_e::at_most_once)[basic::word_] >> + basic::attr(flags) >> prop::props_ >> + basic::verbatim_; return type_parse(it, it + remain_length, publish_); } @@ -161,9 +159,7 @@ inline std::optional decode_puback( ) { if (remain_length == 0) return puback_message {}; - auto puback_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto puback_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, puback_); } @@ -177,9 +173,7 @@ inline std::optional decode_pubrec( ) { if (remain_length == 0) return pubrec_message {}; - auto pubrec_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto pubrec_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, pubrec_); } @@ -193,9 +187,7 @@ inline std::optional decode_pubrel( ) { if (remain_length == 0) return pubrel_message {}; - auto pubrel_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto pubrel_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, pubrel_); } @@ -209,9 +201,7 @@ inline std::optional decode_pubcomp( ) { if (remain_length == 0) return pubcomp_message {}; - auto pubcomp_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto pubcomp_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, pubcomp_); } @@ -223,9 +213,7 @@ using subscribe_message = std::tuple< inline std::optional decode_subscribe( uint32_t remain_length, byte_citer& it ) { - auto subscribe_ = basic::scope_limit_(remain_length)[ - prop::props_ >> +(basic::utf8_ >> x3::byte_) - ]; + constexpr auto subscribe_ = prop::props_ >> +(basic::utf8_ >> basic::byte_); return type_parse(it, it + remain_length, subscribe_); } @@ -237,9 +225,7 @@ using suback_message = std::tuple< inline std::optional decode_suback( uint32_t remain_length, byte_citer& it ) { - auto suback_ = basic::scope_limit_(remain_length)[ - prop::props_ >> +x3::byte_ - ]; + constexpr auto suback_ = prop::props_ >> +basic::byte_; return type_parse(it, it + remain_length, suback_); } @@ -251,9 +237,7 @@ using unsubscribe_message = std::tuple< inline std::optional decode_unsubscribe( uint32_t remain_length, byte_citer& it ) { - auto unsubscribe_ = basic::scope_limit_(remain_length)[ - prop::props_ >> +basic::utf8_ - ]; + constexpr auto unsubscribe_ = prop::props_ >> +basic::utf8_; return type_parse(it, it + remain_length, unsubscribe_); } @@ -265,9 +249,7 @@ using unsuback_message = std::tuple< inline std::optional decode_unsuback( uint32_t remain_length, byte_citer& it ) { - auto unsuback_ = basic::scope_limit_(remain_length)[ - prop::props_ >> +x3::byte_ - ]; + constexpr auto unsuback_ = prop::props_ >> +basic::byte_; return type_parse(it, it + remain_length, unsuback_); } @@ -281,9 +263,7 @@ inline std::optional decode_disconnect( ) { if (remain_length == 0) return disconnect_message {}; - auto disconnect_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto disconnect_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, disconnect_); } @@ -297,9 +277,7 @@ inline std::optional decode_auth( ) { if (remain_length == 0) return auth_message {}; - auto auth_ = basic::scope_limit_(remain_length)[ - x3::byte_ >> prop::props_ - ]; + constexpr auto auth_ = basic::byte_ >> prop::props_; return type_parse(it, it + remain_length, auth_); } diff --git a/include/boost/mqtt5/impl/endpoints.hpp b/include/boost/mqtt5/impl/endpoints.hpp index 5ae041b..e3d01b7 100644 --- a/include/boost/mqtt5/impl/endpoints.hpp +++ b/include/boost/mqtt5/impl/endpoints.hpp @@ -8,9 +8,8 @@ #ifndef BOOST_MQTT5_ENDPOINTS_HPP #define BOOST_MQTT5_ENDPOINTS_HPP -#include - #include +#include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include #include @@ -155,16 +153,6 @@ class endpoints { template friend class resolve_op; - template - static constexpr auto to_(T& arg) { - return [&](auto& ctx) { arg = boost::spirit::x3::_attr(ctx); }; - } - - template - static constexpr auto as_(Parser&& p){ - return boost::spirit::x3::rule{} = std::forward(p); - } - public: template endpoints( @@ -202,38 +190,72 @@ public: } void brokers(std::string hosts, uint16_t default_port) { - namespace x3 = boost::spirit::x3; - _servers.clear(); - std::string host, port, path; - // loosely based on RFC 3986 - auto unreserved_ = x3::char_("-a-zA-Z_0-9._~"); - auto digit_ = x3::char_("0-9"); - auto separator_ = x3::char_(','); + for (auto it = hosts.cbegin(), end = hosts.cend(); it != end;) { + skip_spaces(it, end); - auto host_ = as_(+unreserved_)[to_(host)]; - auto port_ = as_(':' >> +digit_)[to_(port)]; - auto path_ = as_(+(x3::char_('/') >> *unreserved_))[to_(path)]; - auto uri_ = *x3::omit[x3::space] >> (host_ >> -port_ >> -path_) >> - (*x3::omit[x3::space] >> x3::omit[separator_ | x3::eoi]); + auto host = std::string(match_while("A-Za-z0-9._~-", it, end)); + if (host.empty()) break; - for (auto b = hosts.begin(); b != hosts.end(); ) { - host.clear(); port.clear(); path.clear(); - if (phrase_parse(b, hosts.end(), uri_, x3::eps(false))) { - _servers.push_back({ - std::move(host), - port.empty() - ? std::to_string(default_port) - : std::move(port), - std::move(path) - }); + std::string port; + if (it < end && *it == ':') { + port = std::string(match_while("0-9", ++it, end)); + if (port.empty()) break; } - else b = hosts.end(); + + std::string path; + if (it < end && *it == '/') + path = std::string(match_while("/A-Za-z0-9._~-", it, end)); + + _servers.push_back({ + std::move(host), + port.empty() + ? std::to_string(default_port) + : std::move(port), + std::move(path) + }); + + skip_spaces(it, end); + if (it == end || *it++ != ',') break; } } +private: + static constexpr void skip_spaces( + byte_citer& it, const byte_citer& end + ) { + match_while(" \t\r\n\f\v", it, end); + }; + + + static constexpr std::string_view match_while( + const char* chs, byte_citer& it, const byte_citer& end + ) { + if (it == end) + return {}; + + auto beg = it; + while (it < end && is_any_of(chs, *it)) ++it; + + return { &*beg, static_cast(it - beg) }; + } + + static constexpr bool is_any_of(const char* chs, char c) { + while (*chs) + if (*(chs + 1) == '-' && *(chs + 2)) { + if (c >= *chs && c <= *(chs + 2)) + return true; + chs += 3; + } + else { + if (c == *chs) + return true; + ++chs; + } + return false; + } }; diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt index eaf1ad6..6bbfe69 100644 --- a/test/cmake_subdir_test/CMakeLists.txt +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -21,12 +21,9 @@ set(deps container core endian - fusion - optional random range smart_ptr - spirit system type_traits @@ -42,10 +39,11 @@ set(deps intrusive # logic # Beast dependency mp11 + optional preprocessor static_assert # static_string # Beast dependency - type_index + # type_index # Beast dependency winapi move function_types @@ -64,12 +62,8 @@ set(deps iterator regex "function" - phoenix pool - proto - thread unordered - variant variant2 describe predef @@ -77,10 +71,8 @@ set(deps lexical_cast numeric/conversion tokenizer - atomic - chrono + fusion exception - ratio ) foreach(dep IN LISTS deps) diff --git a/test/unit/endpoints.cpp b/test/unit/endpoints.cpp index 65a5077..078457b 100644 --- a/test/unit/endpoints.cpp +++ b/test/unit/endpoints.cpp @@ -74,7 +74,7 @@ BOOST_FIXTURE_TEST_CASE(single_host, shared_test_data) { BOOST_FIXTURE_TEST_CASE(multiple_hosts, shared_test_data) { bool finished = false; // "example.invalid" will not be resolved - ep.brokers("127.0.0.1:1001,127.0.0.1/path1, example.invalid, localhost:1002/path1/path-2/path.3_", 1000); + ep.brokers("127.0.0.1:1001,127.0.0.1/~path1, example.invalid, localhost:1002/path1/path-2/path.3_", 1000); asio::co_spawn(ioc, [&]() -> asio::awaitable { for (size_t i = 0; i < 3; ++i) { @@ -90,7 +90,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_hosts, shared_test_data) { BOOST_TEST(!eps.empty()); BOOST_TEST(ap.host == "127.0.0.1"); BOOST_TEST(ap.port == "1000"); - BOOST_TEST(ap.path == "/path1"); + BOOST_TEST(ap.path == "/~path1"); std::tie(ec, eps, ap) = co_await ep.async_next_endpoint(use_nothrow_awaitable); BOOST_TEST(ec == success); diff --git a/vcpkg.json b/vcpkg.json index f8a829d..65fdfed 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,8 +3,7 @@ "version-semver": "0.0.1", "dependencies": [ "boost-asio", - "boost-beast", - "boost-spirit" + "boost-beast" ], "default-features": [], "features": {