From e4c253e7f30acc2eadafbfd9a5f099457ca0f5f3 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 2 Sep 2022 23:27:33 -0700 Subject: [PATCH] string_token work --- doc/Jamfile | 19 +- doc/qbk/0.main.qbk | 8 +- doc/qbk/5.0.concepts.qbk | 5 +- doc/qbk/5.2.MutableString.qbk | 78 -- doc/qbk/{5.3.Rule.qbk => 5.2.Rule.qbk} | 0 doc/qbk/5.3.StringToken.qbk | 169 ++++ doc/qbk/5.4.StringToken.qbk | 14 - doc/qbk/quickref.xml | 18 +- include/boost/url/authority_view.hpp | 4 +- include/boost/url/decode_view.hpp | 241 +---- include/boost/url/detail/config.hpp | 6 +- include/boost/url/detail/decode_view.hpp | 54 -- include/boost/url/detail/impl/decode_view.ipp | 39 - include/boost/url/grammar.hpp | 1 + .../boost/url/grammar/detail/type_traits.hpp | 83 -- .../url/grammar/impl/string_view_base.ipp | 33 + include/boost/url/grammar/string_token.hpp | 7 +- .../boost/url/grammar/string_view_base.hpp | 888 ++++++++++++++++++ include/boost/url/grammar/type_traits.hpp | 42 - include/boost/url/impl/authority_view.ipp | 16 +- include/boost/url/impl/decode.hpp | 2 +- include/boost/url/impl/decode_view.hpp | 60 -- include/boost/url/impl/decode_view.ipp | 20 - include/boost/url/impl/params_base.ipp | 25 +- include/boost/url/impl/pct_string_view.ipp | 31 +- include/boost/url/impl/segments_base.ipp | 5 +- include/boost/url/impl/url_base.ipp | 4 +- include/boost/url/impl/url_view_base.ipp | 85 +- include/boost/url/params_base.hpp | 11 + include/boost/url/params_ref.hpp | 2 +- include/boost/url/pct_string_view.hpp | 765 +++++---------- include/boost/url/rfc/impl/query_rule.ipp | 1 - include/boost/url/segments_encoded_base.hpp | 2 +- include/boost/url/segments_encoded_view.hpp | 2 +- include/boost/url/segments_view.hpp | 2 +- include/boost/url/src.hpp | 2 +- include/boost/url/url.natvis | 18 +- include/boost/url/url_base.hpp | 46 +- include/boost/url/url_view_base.hpp | 142 ++- test/unit/CMakeLists.txt | 1 + test/unit/Jamfile | 1 + test/unit/authority_view.cpp | 4 +- test/unit/decode_view.cpp | 169 ---- test/unit/doc_container.cpp | 2 +- test/unit/grammar/string_view_base.cpp | 33 + test/unit/grammar/type_traits.cpp | 7 - test/unit/segments_encoded_base.cpp | 2 +- test/unit/segments_encoded_ref.cpp | 4 +- test/unit/segments_encoded_view.cpp | 2 +- test/unit/segments_ref.cpp | 4 +- test/unit/segments_view.cpp | 2 +- test/unit/snippets.cpp | 28 +- test/unit/static_url.cpp | 50 +- test/unit/url.cpp | 74 +- test/unit/url_base.cpp | 156 +-- test/unit/url_view.cpp | 8 +- test/unit/url_view_base.cpp | 28 +- 57 files changed, 1852 insertions(+), 1673 deletions(-) delete mode 100644 doc/qbk/5.2.MutableString.qbk rename doc/qbk/{5.3.Rule.qbk => 5.2.Rule.qbk} (100%) create mode 100644 doc/qbk/5.3.StringToken.qbk delete mode 100644 doc/qbk/5.4.StringToken.qbk delete mode 100644 include/boost/url/detail/decode_view.hpp delete mode 100644 include/boost/url/detail/impl/decode_view.ipp delete mode 100644 include/boost/url/grammar/detail/type_traits.hpp create mode 100644 include/boost/url/grammar/impl/string_view_base.ipp create mode 100644 include/boost/url/grammar/string_view_base.hpp create mode 100644 test/unit/grammar/string_view_base.cpp diff --git a/doc/Jamfile b/doc/Jamfile index f27ffb06..52e0937e 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -21,12 +21,11 @@ docca.reference reference.qbk : xsl/custom-overrides.xsl [ glob-tree-ex ../include/boost/url : *.hpp *.ipp : detail impl ] - #../include/boost/url/segments_base.hpp - #../include/boost/url/segments_encoded_base.hpp - #../include/boost/url/segments_encoded_ref.hpp - #../include/boost/url/segments_encoded_view.hpp - #../include/boost/url/segments_ref.hpp - #../include/boost/url/segments_view.hpp + #../include/boost/url/pct_string_view.hpp + #../include/boost/url/url_view.hpp + #../include/boost/url/url_view_base.hpp + #../include/boost/url/grammar/string_token.hpp + #../include/boost/url/grammar/string_view_base.hpp : PROJECT_NAME=URL PROJECT_BRIEF="URL Library" @@ -39,7 +38,13 @@ docca.reference reference.qbk BOOST_SYMBOL_VISIBLE \\ BOOST_URL_DOCS \\ BOOST_URL_DECL \\ - \"BOOST_STATIC_ASSERT(x)=\" + __cpp_lib_array_constexpr \\ + \"BOOST_CONSTEXPR=constexpr\" \\ + \"BOOST_CXX14_CONSTEXPR=constexpr\" \\ + \"BOOST_STATIC_ASSERT(x)=\" \\ + \"BOOST_URL_STRTOK_TPARAM=class StringToken = string_token::return_string\" \\ + \"BOOST_URL_STRTOK_RETURN=typename StringToken::result_type\" \\ + \"BOOST_URL_STRTOK_ARG(name)=StringToken&& name = {}\" \\ " ABBREVIATE_BRIEF= INLINE_INHERITED_MEMB=YES diff --git a/doc/qbk/0.main.qbk b/doc/qbk/0.main.qbk index 1bd42264..b196a990 100644 --- a/doc/qbk/0.main.qbk +++ b/doc/qbk/0.main.qbk @@ -47,13 +47,19 @@ [def __SemiRegular__ [@https://en.cppreference.com/w/cpp/concepts/semiregular ['SemiRegular]]] [def __Swappable__ [@https://en.cppreference.com/w/cpp/named_req/Swappable ['Swappable]]] [def __CharSet__ [link url.concepts.charset ['CharSet]]] -[def __MutableString__ [link url.concepts.mutablestring ['MutableString]]] [def __Rule__ [link url.concepts.rule ['Rule]]] [def __Rule1__ [link url.concepts.rule ['Rule1]]] [def __Rule2__ [link url.concepts.rule ['Rule2]]] [def __Rules__ [link url.concepts.rule ['Rules]]] + [def __StringToken__ [link url.concepts.stringtoken ['StringToken]]] [def __deduced__ [link url.concepts.stringtoken ['DEDUCED]]] +[def __is_token__ [link url.ref.boost__urls__string_token__is_token `string_token::is_token`]] +[def __append_to__ [link url.ref.boost__urls__string_token__append_to `string_token::append_to`]] +[def __assign_to__ [link url.ref.boost__urls__string_token__assign_to `string_token::assign_to`]] +[def __preserve_size__ [link url.ref.boost__urls__string_token__preserve_size `string_token::preserve_size`]] +[def __append_to__ [link url.ref.boost__urls__string_token__return_string `string_token::return_string`]] + [def __std_swap__ [@https://en.cppreference.com/w/cpp/algorithm/swap `std::swap`]] [def __std_string__ [@https://en.cppreference.com/w/cpp/string/basic_string `std::string`]] diff --git a/doc/qbk/5.0.concepts.qbk b/doc/qbk/5.0.concepts.qbk index 7459d6b1..b1b6f004 100644 --- a/doc/qbk/5.0.concepts.qbk +++ b/doc/qbk/5.0.concepts.qbk @@ -12,8 +12,7 @@ This section describes all of the concepts defined by the library. [include 5.1.CharSet.qbk] -[include 5.2.MutableString.qbk] -[include 5.3.Rule.qbk] -[include 5.4.StringToken.qbk] +[include 5.2.Rule.qbk] +[include 5.3.StringToken.qbk] [endsect] diff --git a/doc/qbk/5.2.MutableString.qbk b/doc/qbk/5.2.MutableString.qbk deleted file mode 100644 index 1acc104a..00000000 --- a/doc/qbk/5.2.MutableString.qbk +++ /dev/null @@ -1,78 +0,0 @@ -[/ - Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - Official repository: https://github.com/boostorg/url -] - -[section MutableString] - -A ['MutableString] nominally represents a modifiable, contiguous -buffer whose `value_type` is char. Objects which satisfy these -requirements may be appended to and assigned to by algorithms -which store the result of applying percent-decoding to various -components of URLs and other things. - -[heading Related Identifiers] - -* __decode_view__ -* [link url.ref.boost__urls__pct_encoded_rule `pct_encoded_rule`] - -[heading Requirements] - -In this table: - -* `T` is a type meeting the requirements of ['MutableString] -* `s` is a possibly-const value of type `T` -* `first`, `last` are __InputIterator__ whose `value_type` is `char` - and form the valid character sequence `[ first, last )` - -[table Valid expressions -[[Expression] [Type] [Semantics, Pre/Post-conditions]] -[ - [ - ``` - T::value_type - ``` - ] - [`char`] - [ - `std::is_same_v< T::value_type, char >` - ] -][ - [ - ``` - s.assign(first,last) - ``` - ] - [] - [ - Assigns the characters in the range `[first, last)` to `s`. - ] -][ - [ - ``` - s.append(first,last) - ``` - ] - [] - [ - Appends the characters in the range `[first, last)` to `s`. - ] -]] - -[heading Exemplar] - -[snippet_mutable_string_exemplar] - -[heading Models] - -* __std_string__ - -[heading See also] - -* __decode_view__ - -[endsect] diff --git a/doc/qbk/5.3.Rule.qbk b/doc/qbk/5.2.Rule.qbk similarity index 100% rename from doc/qbk/5.3.Rule.qbk rename to doc/qbk/5.2.Rule.qbk diff --git a/doc/qbk/5.3.StringToken.qbk b/doc/qbk/5.3.StringToken.qbk new file mode 100644 index 00000000..decbda3e --- /dev/null +++ b/doc/qbk/5.3.StringToken.qbk @@ -0,0 +1,169 @@ +[/ + Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + Official repository: https://github.com/boostorg/url +] + +[section StringToken] + +A string token is an rvalue passed to a function template which +customizes the return type of the function and also controls how +a modifiable character buffer is obtained and presented. The +string token's lifetime extends only for the duration of the +function call in which it appears as a parameter. A string +token cannot be copied, moved, or assigned, and must be +destroyed when the function returns or throws. + +[heading Requirements] + +In this table: + +* `T` is a type meeting the requirements of ['StringToken] +* `t` is an rvalue reference of type T +* `n` is a value of type `std::size_t` + +[table Valid expressions +[[Expression] [Result] [Semantics, Pre/Post-conditions]] +[ + [ + ``` + std::derived_from + ``` + ] + [ + ``` + true + ``` + ] + [ + All string tokens must be publicly and + unambiguously derived from + [link url.ref.boost__urls__string_token__arg `string_token::arg`]. + ] +][ + [ + ``` + T::result_type + ``` + ] + [] + [ + This type determines the return type of functions + which accept a string token. + ] +][ + [ + ``` + t.prepare(n); + ``` + ] + [ + ``` + char* + ``` + ] + [ + This function overrides the virtual function in the base. + It must return a pointer to a character buffer of at least + size `n`, otherwise throw an exception. + ] +][ + [ + ``` + t.result(); + ``` + ] + [ + ``` + T::result_type + ``` + ] + [ + This function is invoked by the algorithm to receive the result + from the string token. + It is only invoked if `prepare` returned successfuly and the + string token was not destroyed. + ] +]] + + + +[heading Algorithm Requirements] + +When an algorithm accepts a string token, it must meet these requirements: + +* `prepare` is called only once or not at all, +* `result` is only called after `prepare` returns successfully, and +* The string token is destroyed when the algorithm completes or if + an exception is thrown. + +String tokens cannot be reused. + + + +[heading Exemplars] + +String token prototype: + +``` +struct StringToken : string_token::arg +{ + using result_type = std::string; + + char* prepare( std::size_t n ) override; + + result_type result(); +}; +``` + +Algorithm prototype: + +``` +namespace detail { + +// Algorithm implementation may be placed +// out of line, and written as an ordinary +// function (no template required). + +void algorithm_impl( string_token::arg& token ) +{ + std::size_t n = 0; + + // calculate space needed in `n` + + // acquire a destination buffer + char* dest = token.prepare( n ); + + // write the characters to the buffer +} + +} // detail + +// public interface is a function template, +// defaulting to return `std::string`. + +template< class StringToken = string_token::return_string > +auto +algorithm( StringToken&& token = {} ) -> + typename StringToken::result_type +{ + // invoke the algorithm with the token + algorithm_impl( token ); + + // return the result from the token + return token.result(); +} + +``` + +Models + +* __append_to__ +* __assign_to__ +* __preserve_size__ +* __append_to__ + +[endsect] diff --git a/doc/qbk/5.4.StringToken.qbk b/doc/qbk/5.4.StringToken.qbk deleted file mode 100644 index 4582eb26..00000000 --- a/doc/qbk/5.4.StringToken.qbk +++ /dev/null @@ -1,14 +0,0 @@ -[/ - Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - Official repository: https://github.com/boostorg/url -] - -[section StringToken] - -A ['StringToken]... - -[endsect] diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml index 06570caf..8674618c 100644 --- a/doc/qbk/quickref.xml +++ b/doc/qbk/quickref.xml @@ -42,8 +42,8 @@ param_pct_view param_view params_base - params_const_encoded_view params_encoded_base + params_encoded_ref params_encoded_view params_ref params_view @@ -203,7 +203,6 @@ Type Traits is_charset - is_mutable_string is_rule @@ -220,17 +219,18 @@ range recycled recycled_ptr + string_view_base unsigned_rule StringToken - append_to - arg - assign_to - is_token - preserve_size - return_string + append_to + arg + assign_to + is_token + preserve_size + return_string @@ -253,8 +253,8 @@ Concepts CharSet - MutableString Rule + StringToken diff --git a/include/boost/url/authority_view.hpp b/include/boost/url/authority_view.hpp index 4156dfe2..d264a333 100644 --- a/include/boost/url/authority_view.hpp +++ b/include/boost/url/authority_view.hpp @@ -257,7 +257,7 @@ public: >3.2. Authority (rfc3986) */ string_view - string() const noexcept + buffer() const noexcept { return string_view(data(), size()); } @@ -1195,7 +1195,7 @@ public: std::ostream& os, authority_view const& a) { - return os << a.string(); + return os << a.buffer(); } }; diff --git a/include/boost/url/decode_view.hpp b/include/boost/url/decode_view.hpp index e655e2d2..418e3161 100644 --- a/include/boost/url/decode_view.hpp +++ b/include/boost/url/decode_view.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +20,24 @@ namespace boost { namespace urls { +//------------------------------------------------ + +#ifndef BOOST_URL_DOCS +class decode_view; + +namespace detail { + +// unchecked +template +decode_view +make_decode_view( + Args&&... args) noexcept; + +} // detail +#endif + +//------------------------------------------------ + /** A reference to a valid, percent-encoded string These views reference strings in parts of URLs @@ -43,17 +60,6 @@ namespace urls { @li Accessing the encoded character buffer @li Comparison to encoded or plain strings - However, in order to access the string as a - as a contiguous character buffer with - with percent-decoding applied, the caller - must explicitly opt-in to an operation that - is potentially allocating. These operations - are: - - @li Conversion to `std::string` - @li Appending to an existing character buffer - @li Assigning to an existing character buffer - These objects can only be constructed from strings that have a valid percent-encoding, otherwise construction fails. The caller is @@ -69,18 +75,21 @@ class decode_view std::size_t dn_ = 0; bool plus_to_space_ = true; - friend struct detail::make_decode_view_t; +#ifndef BOOST_URL_DOCS + template + friend + decode_view + detail::make_decode_view( + Args&&... args) noexcept; +#endif - friend detail::access; - friend class url_base; - - // unchecked constructor + // unchecked BOOST_URL_DECL explicit decode_view( string_view s, std::size_t n, - decode_opts opt = {}) noexcept; + decode_opts opt) noexcept; public: /** The value type @@ -140,6 +149,9 @@ public: this->empty() == true @endcode + @par Complexity + Constant. + @par Exception Safety Throws nothing. */ @@ -306,25 +318,6 @@ public: reference back() const noexcept; - /** Return the encoded string - - @par Example - @code - assert( decode_view( "Program%20Files" ).encoded() == "Program%20Files" ); - @endcode - - @par Complexity - Constant. - - @par Exception Safety - Throws nothing. - */ - string_view - encoded() const noexcept - { - return {p_, n_}; - } - /** Return the decoding options */ decode_opts @@ -335,163 +328,6 @@ public: return opt; } - /** Copy a decoded substring to another character string - - This function copies a substring to the - character array pointed to by the - destination char string, where `rcount` - is the smaller of `count` and - `size() - pos`. - - @par Exception Safety - Strong guarantee. - Exceptions thrown on invalid positions. - - @par Preconditions - @code - pos > size() - @endcode - - @throw std::out_of_range `pos > size()` - - @param dest pointer to the destination character string - @param count requested substring length - @param pos position of the first character - - @return Number of characters copied - */ - BOOST_URL_DECL - size_type - copy( - char* dest, - size_type count, - size_type pos = 0) const; - - /** Append the range with percent-decoded applied to an existing string - - This function applies percent-decoding to each character - in the referenced buffer and appends it to `s` which - must satisfy the requirements of MutableString. - In particular this expression must be valid: - @code - s.append( this->begin(), this->end() ); - @endcode - - Depending on the implementation of `MutableString` - this allows the caller to recycle capacity that - resides in an already-existing container when - applying percent-decoding, as shown in this example: - - @par Example - @code - void f( decode_view s ) - { - thread_local static std::string tmp; - - // Existing capacity of `tmp` will be reused first. - // If this function is called repeatedly, then the - // following three lines will almost never perform a - // memory allocation: - - tmp = "The decoded value is '"; - s.append_to( tmp ); - tmp += "'\n"; - - std::cout << tmp; - } - @endcode - - @par Mandates - @code - is_mutable_string_v< MutableString > - @endcode - - @par Complexity - Linear in `this->size()`, plus `s.append( this->begin(), this->end() )`. - - @return A string representing the - entire contents of the decoded range. - */ - template - MutableString& - append_to( - MutableString& s) const; - - /** Assign the range with percent-decoded applied to an existing string - - This function applies percent-decoding to each character - in the referenced buffer and assigns it to `s` which - must satisfy the requirements of MutableString. - In particular this expression must be valid: - @code - s.assign( this->begin(), this->end() ); - @endcode - - @par Example - @code - void f( decode_view s ) - { - thread_local static std::string tmp; - - // Existing capacity of `tmp` will be reused first. - // If this function is called repeatedly, then the - // following line will almost never perform a - // memory allocation: - - s.assign_to( tmp ); - - std::cout << tmp << "\n"; - } - @endcode - - @par Mandates - @code - is_mutable_string_v< MutableString > - @endcode - - Depending on the implementation of `MutableString` - this allows the caller to recycle capacity that - resides in an already-existing container when - applying percent-decoding, as shown in this example: - - @par Complexity - Linear in `this->size()`, plus `s.assign( this->begin(), this->end() )`. - - @return A string representing the - entire contents of the decoded range. - */ - template - MutableString& - assign_to( - MutableString& s) const; - - /** Return a std::string with percent-decoding applied - - This function applies percent-decoding to the - referenced character buffer, returning the result - as a `std::string`. - - @par Complexity - Linear in `size()`. - - @par Exception Safety - Memory allocations may throw. - */ - std::string - to_string() const - { - std::string r; - assign_to(r); - return r; - } - - /// @copydoc to_string() - explicit - operator std::string() const - { - return to_string(); - } - //-------------------------------------------- // // Comparison @@ -1165,6 +1001,23 @@ operator<<( std::ostream& os, decode_view const& s); +//------------------------------------------------ + +#ifndef BOOST_URL_DOCS +namespace detail { +template +decode_view +make_decode_view( + Args&&... args) noexcept +{ + return decode_view( + std::forward(args)...); +} +} // detail +#endif + +//------------------------------------------------ + } // urls } // boost diff --git a/include/boost/url/detail/config.hpp b/include/boost/url/detail/config.hpp index 089d82e1..567c4123 100644 --- a/include/boost/url/detail/config.hpp +++ b/include/boost/url/detail/config.hpp @@ -74,13 +74,13 @@ #endif #ifndef BOOST_URL_STRTOK_TPARAM -#define BOOST_URL_STRTOK_TPARAM(T) class T = string_token::return_string +#define BOOST_URL_STRTOK_TPARAM class StringToken = string_token::return_string #endif #ifndef BOOST_URL_STRTOK_RETURN -#define BOOST_URL_STRTOK_RETURN(T) typename T::result_type +#define BOOST_URL_STRTOK_RETURN typename StringToken::result_type #endif #ifndef BOOST_URL_STRTOK_ARG -#define BOOST_URL_STRTOK_ARG(T, name) T&& name = {} +#define BOOST_URL_STRTOK_ARG(name) StringToken&& token = {} #endif #if BOOST_WORKAROUND( BOOST_GCC_VERSION, < 80000 ) || \ diff --git a/include/boost/url/detail/decode_view.hpp b/include/boost/url/detail/decode_view.hpp deleted file mode 100644 index 47773b73..00000000 --- a/include/boost/url/detail/decode_view.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) 2022 Alan Freitas (alandefreitas@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/boostorg/url -// - -#ifndef BOOST_URL_DETAIL_DECODE_VIEW_HPP -#define BOOST_URL_DETAIL_DECODE_VIEW_HPP - -#include -#include - -namespace boost { -namespace urls { - -class decode_view; - -namespace detail { - -struct access -{ - // construct unchecked decode_view - BOOST_URL_DECL - static - decode_view - construct( - string_view s, - std::size_t n, - decode_opts const& opt = {}) noexcept; -}; - -//------------------------------------------------ - -struct make_decode_view_t -{ - template - decode_view - operator()(Args&&... args) const; -}; - -constexpr -make_decode_view_t -make_decode_view{}; - -//------------------------------------------------ - -} // detail -} // urls -} // boost - -#endif diff --git a/include/boost/url/detail/impl/decode_view.ipp b/include/boost/url/detail/impl/decode_view.ipp deleted file mode 100644 index f1892722..00000000 --- a/include/boost/url/detail/impl/decode_view.ipp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2022 Alan Freitas (alandefreitas@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/boostorg/url -// - -#ifndef BOOST_URL_DETAIL_IMPL_DECODE_VIEW_IPP -#define BOOST_URL_DETAIL_IMPL_DECODE_VIEW_IPP - -#include -#include - -namespace boost { -namespace urls { - -class decode_view; - -namespace detail { - -// construct unchecked decode_view -decode_view -access:: -construct( - string_view s, - std::size_t n, - decode_opts const& opt) noexcept -{ - // AFREITAS: move that inline - return decode_view(s, n, opt); -} - -} // detail -} // urls -} // boost - -#endif diff --git a/include/boost/url/grammar.hpp b/include/boost/url/grammar.hpp index 78c718a4..a2aaea7d 100644 --- a/include/boost/url/grammar.hpp +++ b/include/boost/url/grammar.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/url/grammar/detail/type_traits.hpp b/include/boost/url/grammar/detail/type_traits.hpp deleted file mode 100644 index b4c21adb..00000000 --- a/include/boost/url/grammar/detail/type_traits.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/boostorg/url -// - -#ifndef BOOST_URL_GRAMMAR_DETAIL_TYPE_TRAITS_HPP -#define BOOST_URL_GRAMMAR_DETAIL_TYPE_TRAITS_HPP - -#include - -namespace boost { -namespace urls { -namespace grammar { -namespace detail { - -// input iter exemplar -struct input_it_ex { - // InputIterator - - // 1. Iterator - - // 1.1 Type defs - using value_type = char; - using difference_type = std::ptrdiff_t; - using reference = char&; - using pointer = char*; - using iterator_category = std::input_iterator_tag; - - // 1.2 CopyConstructible - input_it_ex(input_it_ex const&); - - // 1.3 CopyAssignable - input_it_ex& - operator=(input_it_ex const&); - - // 1.4 Destructible - ~input_it_ex(); - - // 1.5 Swappable - friend - void swap( - input_it_ex&, - input_it_ex&); - - // 1.6 Expressions - reference - operator*() const; - - input_it_ex& - operator++(); - - input_it_ex - operator++(int); - - // 1.7 Default constructible (GCC11/MSVC14.2) - input_it_ex(); - - // 2. EqualityComparable - friend - bool operator==( - input_it_ex const&, - input_it_ex const&); - - friend - bool operator!=( - input_it_ex const&, - input_it_ex const&); - - // 3. Expressions - pointer - operator->(); -}; - -} // detail -} // grammar -} // urls -} // boost - -#endif diff --git a/include/boost/url/grammar/impl/string_view_base.ipp b/include/boost/url/grammar/impl/string_view_base.ipp new file mode 100644 index 00000000..bfa411c5 --- /dev/null +++ b/include/boost/url/grammar/impl/string_view_base.ipp @@ -0,0 +1,33 @@ +// +// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url +// + +#ifndef BOOST_URL_IMPL_STRING_VIEW_BASE_IPP +#define BOOST_URL_IMPL_STRING_VIEW_BASE_IPP + +#include +#include + +namespace boost { +namespace urls { +namespace grammar { + +std::ostream& +operator<<( + std::ostream& os, + string_view_base const& s) +{ + return os << string_view(s); +} + +} // grammar +} // urls +} // boost + +#endif + diff --git a/include/boost/url/grammar/string_token.hpp b/include/boost/url/grammar/string_token.hpp index 876e5e55..fa77d478 100644 --- a/include/boost/url/grammar/string_token.hpp +++ b/include/boost/url/grammar/string_token.hpp @@ -19,8 +19,6 @@ namespace boost { namespace urls { - -namespace grammar { namespace string_token { /** Base class for string tokens, and algorithm parameters @@ -338,9 +336,10 @@ preserve_size( #endif } // string_token -} // grammar -namespace string_token = grammar::string_token; +namespace grammar { +namespace string_token = ::boost::urls::string_token; +} // grammar } // urls } // boost diff --git a/include/boost/url/grammar/string_view_base.hpp b/include/boost/url/grammar/string_view_base.hpp new file mode 100644 index 00000000..09d149f6 --- /dev/null +++ b/include/boost/url/grammar/string_view_base.hpp @@ -0,0 +1,888 @@ +// +// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url +// + +#ifndef BOOST_URL_GRAMMAR_STRING_VIEW_BASE_HPP +#define BOOST_URL_GRAMMAR_STRING_VIEW_BASE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace urls { +namespace grammar { + +/** Common functionality for string views + + This base class is used to provide common + member functions for reference types that + behave like string views. This cannot be + instantiated directly; Instead, derive + from the type and provide constructors + which offer any desired preconditions + and invariants. +*/ +class string_view_base +{ +protected: + /** The referenced character buffer + */ + string_view s_; + + /** Constructor + */ + constexpr + string_view_base( + string_view s) noexcept + : s_(s) + { + } + + /** Swap + */ + // VFALCO No idea why this fails in msvc + /*BOOST_CXX14_CONSTEXPR*/ void swap( + string_view_base& s ) noexcept + { + std::swap(s_, s.s_); + } + + /** Constructor + */ + string_view_base() = default; + + /** Constructor + */ + string_view_base( + string_view_base const&) = default; + + /** Assignment + */ + string_view_base& operator=( + string_view_base const&) = default; + +public: + /// The character traits + typedef std::char_traits traits_type; + /// The value type + typedef char value_type; + /// The pointer type + typedef char* pointer; + /// The const pointer type + typedef char const* const_pointer; + /// The reference type + typedef char& reference; + /// The const reference type + typedef char const& const_reference; + /// The const iterator type + typedef char const* const_iterator; + /// The iterator type + typedef const_iterator iterator; + /// The const reverse iterator type + typedef std::reverse_iterator< + const_iterator> const_reverse_iterator; + /// The reverse iterator type + typedef const_reverse_iterator reverse_iterator; + /// The size type + typedef std::size_t size_type; + /// The difference type + typedef std::ptrdiff_t difference_type; + + /// A constant used to represent "no position" + static constexpr std::size_t npos = string_view::npos; + + //-------------------------------------------- + + /** Conversion + */ + operator + string_view() const noexcept + { + return s_; + } + + /** Conversion + */ +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + operator + std::string_view() const noexcept + { + return std::string_view(s_); + } +#endif + + /** Conversion + + Conversion to std::string is explicit + because assigning to string using an + implicit constructor will not preserve + capacity. + */ + explicit + operator + std::string() const noexcept + { + return std::string(s_); + } + + //-------------------------------------------- + + // iterator support + + /** Return an iterator to the beginning + + See `string_view::begin` + */ + BOOST_CONSTEXPR const_iterator begin() const noexcept + { + return s_.begin(); + } + + /** Return an iterator to the end + + See `string_view::end` + */ + BOOST_CONSTEXPR const_iterator end() const noexcept + { + return s_.end(); + } + + /** Return an iterator to the beginning + + See `string_view::cbegin` + */ + BOOST_CONSTEXPR const_iterator cbegin() const noexcept + { + return s_.cbegin(); + } + + /** Return an iterator to the end + + See `string_view::cend` + */ + BOOST_CONSTEXPR const_iterator cend() const noexcept + { + return s_.cend(); + } + + /** Return a reverse iterator to the end + + See `string_view::rbegin` + */ +#ifdef __cpp_lib_array_constexpr + constexpr +#endif + const_reverse_iterator rbegin() const noexcept + { + return s_.rbegin(); + } + + /** Return a reverse iterator to the beginning + + See `string_view::rend` + */ +#ifdef __cpp_lib_array_constexpr + constexpr +#endif + const_reverse_iterator rend() const noexcept + { + return s_.rend(); + } + + /** Return a reverse iterator to the end + + See `string_view::crbegin` + */ +#ifdef __cpp_lib_array_constexpr + constexpr +#endif + const_reverse_iterator crbegin() const noexcept + { + return s_.crbegin(); + } + + /** Return a reverse iterator to the beginning + + See `string_view::crend` + */ +#ifdef __cpp_lib_array_constexpr + constexpr +#endif + const_reverse_iterator crend() const noexcept + { + return s_.crend(); + } + + // capacity + + /** Return the size + + See `string_view::size` + */ + BOOST_CONSTEXPR size_type size() const noexcept + { + return s_.size(); + } + + /** Return the size + + See `string_view::length` + */ + BOOST_CONSTEXPR size_type length() const noexcept + { + return s_.length(); + } + + /** Return the maximum allowed size + + See `string_view::max_size` + */ + BOOST_CONSTEXPR size_type max_size() const noexcept + { + return s_.max_size(); + } + + /** Return true if the string is empty + + See `string_view::size` + */ + BOOST_CONSTEXPR bool empty() const noexcept + { + return s_.empty(); + } + + // element access + + /** Access a character + + See `string_view::operator[]` + */ + BOOST_CXX14_CONSTEXPR const_reference + operator[]( size_type pos ) const noexcept + { + return s_[pos]; + } + + /** Access a character + + See `string_view::at` + */ + BOOST_CXX14_CONSTEXPR const_reference + at( size_type pos ) const + { + return s_.at(pos); + } + + /** Return the first character + + See `string_view::front` + */ + BOOST_CXX14_CONSTEXPR const_reference + front() const noexcept + { + return s_.front(); + } + + /** Return the last character + + See `string_view::back` + */ + BOOST_CXX14_CONSTEXPR const_reference + back() const noexcept + { + return s_.back(); + } + + /** Return a pointer to the character buffer + + See `string_view::data` + */ + BOOST_CONSTEXPR const_pointer + data() const noexcept + { + return s_.data(); + } + + // string operations + + /** Copy the characters to another buffer + + See `string_view::copy` + */ + BOOST_CXX14_CONSTEXPR size_type copy( + char* s, size_type n, size_type pos = 0 ) const + { + return s_.copy(s, n, pos); + } + + /** Return a view to part of the string + + See `string_view::substr` + */ + BOOST_CXX14_CONSTEXPR string_view substr( + size_type pos = 0, size_type n = string_view::npos ) const + { + return s_.substr(pos, n); + } + + // comparison + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CXX14_CONSTEXPR int + compare( string_view str ) const noexcept + { + return s_.compare(str); + } + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CONSTEXPR int compare( + size_type pos1, size_type n1, string_view str ) const + { + return s_.compare(pos1, n1, str); + } + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CONSTEXPR int compare( + size_type pos1, size_type n1, string_view str, + size_type pos2, size_type n2 ) const + { + return s_.compare(pos1, n1, str, pos2, n2); + } + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CONSTEXPR int compare( + char const* s ) const noexcept + { + return s_.compare(s); + } + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CONSTEXPR int compare( + size_type pos1, size_type n1, char const* s ) const + { + return s_.compare(pos1, n1, s); + } + + /** Return the result of comparing to another string + + See `string_view::compare` + */ + BOOST_CONSTEXPR int compare( + size_type pos1, size_type n1, + char const* s, size_type n2 ) const + { + return s_.compare(pos1, n1, s, n2); + } + + // starts_with + + /** Return true if a matching prefix exists + + See `string_view::starts_with` + */ + BOOST_CONSTEXPR bool starts_with( + string_view x ) const noexcept + { + return s_.starts_with(x); + } + + /** Return true if a matching prefix exists + + See `string_view::starts_with` + */ + BOOST_CONSTEXPR bool starts_with( + char x ) const noexcept + { + return s_.starts_with(x); + } + + /** Return true if a matching prefix exists + + See `string_view::starts_with` + */ + BOOST_CONSTEXPR bool starts_with( + char const* x ) const noexcept + { + return s_.starts_with(x); + } + + // ends_with + + /** Return true if a matching suffix exists + + See `string_view::ends_with` + */ + BOOST_CONSTEXPR bool ends_with( + string_view x ) const noexcept + { + return s_.ends_with(x); + } + + /** Return true if a matching suffix exists + + See `string_view::ends_with` + */ + BOOST_CONSTEXPR bool ends_with( + char x ) const noexcept + { + return s_.ends_with(x); + } + + /** Return true if a matching suffix exists + + See `string_view::ends_with` + */ + BOOST_CONSTEXPR bool ends_with( + char const* x ) const noexcept + { + return s_.ends_with(x); + } + + // find + + /** Return the position of matching characters + + See `string_view::find` + */ + BOOST_CONSTEXPR size_type find( + string_view str, size_type pos = 0 ) const noexcept + { + return s_.find(str, pos); + } + + /** Return the position of matching characters + + See `string_view::find` + */ + BOOST_CXX14_CONSTEXPR size_type find( + char c, size_type pos = 0 ) const noexcept + { + return s_.find(c, pos); + } + + /** Return the position of matching characters + + See `string_view::find` + */ + BOOST_CXX14_CONSTEXPR size_type find( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.find(s, pos, n); + } + + /** Return the position of matching characters + + See `string_view::find` + */ + BOOST_CONSTEXPR size_type find( + char const* s, size_type pos = 0 ) const noexcept + { + return s_.find(s, pos); + } + + // rfind + + /** Return the position of matching characters + + See `string_view::rfind` + */ + BOOST_CONSTEXPR size_type rfind( + string_view str, size_type pos = string_view::npos ) const noexcept + { + return s_.rfind(str, pos); + } + + /** Return the position of matching characters + + See `string_view::rfind` + */ + BOOST_CXX14_CONSTEXPR size_type rfind( + char c, size_type pos = string_view::npos ) const noexcept + { + return s_.rfind(c, pos); + } + + /** Return the position of matching characters + + See `string_view::rfind` + */ + BOOST_CXX14_CONSTEXPR size_type rfind( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.rfind(s, pos, n); + } + + /** Return the position of matching characters + + See `string_view::rfind` + */ + BOOST_CONSTEXPR size_type rfind( + char const* s, size_type pos = string_view::npos ) const noexcept + { + return s_.rfind(s, pos); + } + + // find_first_of + + /** Return the position of the first match + + See `string_view::find_first_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_of( + string_view str, size_type pos = 0 ) const noexcept + { + return s_.find_first_of(str, pos); + } + + /** Return the position of the first match + + See `string_view::find_first_of` + */ + BOOST_CONSTEXPR size_type find_first_of( + char c, size_type pos = 0 ) const noexcept + { + return s_.find_first_of(c, pos); + } + + /** Return the position of the first match + + See `string_view::find_first_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_of( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.find_first_of(s, pos, n); + } + + /** Return the position of the first match + + See `string_view::find_first_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_of( + char const* s, size_type pos = 0 ) const noexcept + { + return s_.find_first_of(s, pos); + } + + // find_last_of + + /** Return the position of the last match + + See `string_view::find_last_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_of( + string_view str, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_of(str, pos); + } + + /** Return the position of the last match + + See `string_view::find_last_of` + */ + BOOST_CONSTEXPR size_type find_last_of( + char c, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_of(c, pos); + } + + /** Return the position of the last match + + See `string_view::find_last_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_of( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.find_last_of(s, pos, n); + } + + /** Return the position of the last match + + See `string_view::find_last_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_of( + char const* s, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_of(s, pos); + } + + // find_first_not_of + + /** Return the position of the first non-match + + See `string_view::find_first_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_not_of( + string_view str, size_type pos = 0 ) const noexcept + { + return s_.find_first_not_of(str, pos); + } + + /** Return the position of the first non-match + + See `string_view::find_first_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_not_of( + char c, size_type pos = 0 ) const noexcept + { + return s_.find_first_not_of(c, pos); + } + + /** Return the position of the first non-match + + See `string_view::find_first_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_not_of( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.find_first_not_of(s, pos, n); + } + + /** Return the position of the first non-match + + See `string_view::find_first_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_first_not_of( + char const* s, size_type pos = 0 ) const noexcept + { + return s_.find_first_not_of(s, pos); + } + + // find_last_not_of + + /** Return the position of the last non-match + + See `string_view::find_last_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_not_of( + string_view str, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_not_of(str, pos); + } + + /** Return the position of the last non-match + + See `string_view::find_last_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_not_of( + char c, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_not_of(c, pos); + } + + /** Return the position of the last non-match + + See `string_view::find_last_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_not_of( + char const* s, size_type pos, size_type n ) const noexcept + { + return s_.find_last_not_of(s, pos, n); + } + + /** Return the position of the last non-match + + See `string_view::find_last_not_of` + */ + BOOST_CXX14_CONSTEXPR size_type find_last_not_of( + char const* s, size_type pos = string_view::npos ) const noexcept + { + return s_.find_last_not_of(s, pos); + } + + // contains + + /** Return true if matching characters are found + + See `string_view::contains` + */ + BOOST_CONSTEXPR bool contains( string_view sv ) const noexcept + { + return s_.contains(sv); + } + + /** Return true if matching characters are found + + See `string_view::contains` + */ + BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept + { + return s_.contains(c); + } + + /** Return true if matching characters are found + + See `string_view::contains` + */ + BOOST_CONSTEXPR bool contains( char const* s ) const noexcept + { + return s_.contains(s); + } + + // relational operators +#ifndef BOOST_URL_DOCS +private: + template + using is_match = std::integral_constant::value && + std::is_convertible::value && ( + (std::is_base_of::type>::value && + std::is_convertible::value) || + (std::is_base_of::type>::value && + std::is_convertible::value))>; +public: +#endif + + /** Comparison + + These functions perform a lexicographical + comparison of the contents of two strings. + At least one of the strings must be + derived from @ref string_view_base, with + the other string being convertible to + @ref string_view. + + @par Complexity + Linear in `s1.size() + s2.size()`. + + @par Exception Safety + Throws nothing. + + @param s1, s2 The strings to compare. + */ +#ifdef BOOST_URL_DOCS + /**@{*/ + template + friend bool operator==(String1 s1, String2 s2) noexcept; + template + friend bool operator!=(String1 s1, String2 s2) noexcept; + template + friend bool operator<=(String1 s1, String2 s2) noexcept; + template + friend bool operator< (String1 s1, String2 s2) noexcept; + template + friend bool operator> (String1 s1, String2 s2) noexcept; + template + friend bool operator>=(String1 s1, String2 s2) noexcept; + /**@}*/ +#else + + template + BOOST_CXX14_CONSTEXPR friend auto operator==( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) == string_view(s1); + } + + template + BOOST_CXX14_CONSTEXPR friend auto operator!=( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) != string_view(s1); + } + + template + BOOST_CXX14_CONSTEXPR friend auto operator<( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) < string_view(s1); + } + + template + BOOST_CXX14_CONSTEXPR friend auto operator<=( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) <= string_view(s1); + } + + template + BOOST_CXX14_CONSTEXPR friend auto operator>( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) > string_view(s1); + } + + template + BOOST_CXX14_CONSTEXPR friend auto operator>=( + S0 const& s0, S1 const& s1) noexcept -> + typename std::enable_if< + is_match::value, bool>::type + { + return string_view(s0) >= string_view(s1); + } +#endif + + //-------------------------------------------- + + /** Return the hash of this value + */ + friend + std::size_t + hash_value( + string_view_base const& s) noexcept + { + return hash_value(s.s_); + } + + BOOST_URL_DECL + friend + std::ostream& + operator<<( + std::ostream& os, + string_view_base const& s); +}; + +//------------------------------------------------ + +/** Format a string to an output stream +*/ +BOOST_URL_DECL +std::ostream& +operator<<( + std::ostream& os, + string_view_base const& s); + +} // grammar +} // urls +} // boost + +#endif diff --git a/include/boost/url/grammar/type_traits.hpp b/include/boost/url/grammar/type_traits.hpp index 51de58fa..6bd2c170 100644 --- a/include/boost/url/grammar/type_traits.hpp +++ b/include/boost/url/grammar/type_traits.hpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -20,47 +19,6 @@ namespace boost { namespace urls { namespace grammar { -//------------------------------------------------ - -/** Alias for `std::true_type` if `T` satisfies __MutableString__ -*/ -#ifdef BOOST_URL_DOCS -template -using is_mutable_string = __see_below__; -#else -template -struct is_mutable_string : std::false_type {}; - -template -struct is_mutable_string() - .append( - std::declval(), - std::declval()) - ), - // T::assign(I, I) - decltype( - std::declval() - .assign( - std::declval(), - std::declval()) - ), - // std::is_same_v - decltype( - std::declval() = - typename std::integral_constant< - bool, std::is_same< - typename T::value_type, char >::value>{} - )>> - : std::true_type -{ -}; -#endif - -//------------------------------------------------ - /** Determine if T meets the requirements of Rule This is an alias for `std::true_type` if diff --git a/include/boost/url/impl/authority_view.ipp b/include/boost/url/impl/authority_view.ipp index cb64f96a..fcc9f2c1 100644 --- a/include/boost/url/impl/authority_view.ipp +++ b/include/boost/url/impl/authority_view.ipp @@ -97,7 +97,7 @@ userinfo() const { decode_opts opt; opt.plus_to_space = false; - return encoded_userinfo().decode_to_string(opt); + return encoded_userinfo().decode(opt); } pct_string_view @@ -120,7 +120,7 @@ user() const { decode_opts opt; opt.plus_to_space = false; - return encoded_user().decode_to_string(opt); + return encoded_user().decode(opt); } pct_string_view @@ -156,7 +156,7 @@ password() const { decode_opts opt; opt.plus_to_space = false; - return encoded_password().decode_to_string(opt); + return encoded_password().decode(opt); } pct_string_view @@ -191,9 +191,9 @@ encoded_password() const noexcept /* host_type host_type() // ipv4, ipv6, ipvfuture, name -std::string host() // return encoded_host().decode_to_string() +std::string host() // return encoded_host().decode() pct_string_view encoded_host() // return host part, as-is -std::string host_address() // return encoded_host_address().decode_to_string() +std::string host_address() // return encoded_host_address().decode() pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets ipv4_address host_ipv4_address() // return ipv4_address or {} @@ -209,7 +209,7 @@ host() const { decode_opts opt; opt.plus_to_space = false; - return encoded_host().decode_to_string(opt); + return encoded_host().decode(opt); } pct_string_view @@ -227,7 +227,7 @@ host_address() const { decode_opts opt; opt.plus_to_space = false; - return encoded_host_address().decode_to_string(opt); + return encoded_host_address().decode(opt); } pct_string_view @@ -313,7 +313,7 @@ host_name() const { decode_opts opt; opt.plus_to_space = false; - return encoded_host_name().decode_to_string(opt); + return encoded_host_name().decode(opt); } pct_string_view diff --git a/include/boost/url/impl/decode.hpp b/include/boost/url/impl/decode.hpp index 0807f58a..d2db5b45 100644 --- a/include/boost/url/impl/decode.hpp +++ b/include/boost/url/impl/decode.hpp @@ -35,7 +35,7 @@ decode( detail::validate_encoding(s, opt, allowed); if (rn.has_error()) return rn.error(); - return detail::access::construct(s, *rn, opt); + return detail::make_decode_view(s, *rn, opt); } } // urls diff --git a/include/boost/url/impl/decode_view.hpp b/include/boost/url/impl/decode_view.hpp index faf84894..e344f2a8 100644 --- a/include/boost/url/impl/decode_view.hpp +++ b/include/boost/url/impl/decode_view.hpp @@ -166,66 +166,6 @@ back() const noexcept -> return *--end(); } -template -MutableString& -decode_view:: -assign_to( - MutableString& s) const -{ - // If you get a compiler error here, it means that - // your String type is missing the necessary append - // or assign member functions, or that your - // value_type is not char! - // - // This function should only be used - // if the container `MutableString` has the - // member function `assign(iterator, iterator)`. - BOOST_STATIC_ASSERT( - grammar::is_mutable_string< - MutableString>::value); - s.assign(begin(), end()); - return s; -} - -template -MutableString& -decode_view:: -append_to( - MutableString& s) const -{ - // If you get a compiler error here, it means that - // your String type is missing the necessary append - // or assign member functions, or that your - // value_type is not char! - // - // This function should only be used - // if the container `MutableString` has the - // member function `append(iterator, iterator)`. - static_assert( - grammar::is_mutable_string< - MutableString>::value, - "MutableString requirements not met"); - - s.append(begin(), end()); - return s; -} - -//------------------------------------------------ - -namespace detail { - -template -decode_view -make_decode_view_t:: -operator()(Args&&... args) const -{ - return decode_view( - std::forward( - args)...); -} - -} // detail - } // urls } // boost diff --git a/include/boost/url/impl/decode_view.ipp b/include/boost/url/impl/decode_view.ipp index b4368b66..7b9ef529 100644 --- a/include/boost/url/impl/decode_view.ipp +++ b/include/boost/url/impl/decode_view.ipp @@ -65,26 +65,6 @@ decode_view( s, opt).value(BOOST_URL_POS); } -//------------------------------------------------ - -auto -decode_view:: -copy( - char* dest, - size_type count, - size_type pos) const -> - size_type -{ - if( pos > size() ) - detail::throw_invalid_argument(); - std::size_t rlen = (std::min)(count, size() - pos); - auto first = std::next(begin(), pos); - auto last = std::next(first, rlen); - while (first != last) - *dest++ = *first++; - return rlen; -} - namespace detail { template diff --git a/include/boost/url/impl/params_base.ipp b/include/boost/url/impl/params_base.ipp index e3f70ab4..c55d1edb 100644 --- a/include/boost/url/impl/params_base.ipp +++ b/include/boost/url/impl/params_base.ipp @@ -24,22 +24,25 @@ dereference() const { if(! valid_) { - // VFALCO This could be better, - // we should never shrink size() for - // a recycled std::string, because - // otherwise when we resize it larger - // we will again have to value-init (?) - // the new chars. - param_pct_view qp = it_.dereference(); + // VFALCO This could be done with + // one string instead of two. key_.acquire(); value_.acquire(); - (*qp.key).assign_to(*key_); + decode_opts opt; + opt.plus_to_space = true; + param_pct_view qp = it_.dereference(); + qp.key.decode(opt, + string_token::preserve_size(*key_)); has_value_ = qp.has_value; if(has_value_) - (*qp.value).assign_to(*value_); + qp.value.decode(opt, + string_token::preserve_size(*value_)); valid_ = true; - } - return { *key_, *value_, has_value_ }; + }; + return { + string_view(key_->data(), it_.dk), + string_view(value_->data(), it_.dv), + has_value_}; } params_base:: diff --git a/include/boost/url/impl/pct_string_view.ipp b/include/boost/url/impl/pct_string_view.ipp index e551338b..7ed620bc 100644 --- a/include/boost/url/impl/pct_string_view.ipp +++ b/include/boost/url/impl/pct_string_view.ipp @@ -30,6 +30,18 @@ make_pct_string_view( } // detail +void +pct_string_view:: +decode_impl( + string_token::arg& dest, + decode_opts const& opt) const +{ + auto p = dest.prepare(dn_); + if(dn_ > 0) + detail::decode_unchecked( + p, p + dn_, s_, opt); +} + //------------------------------------------------ pct_string_view:: @@ -43,25 +55,6 @@ pct_string_view( //------------------------------------------------ -std::string -pct_string_view:: -decode_to_string( - decode_opts const& opt) const -{ - std::string s; - if(dn_ > 0) - { - s.resize(dn_); - detail::decode_unchecked( - &s[0], - &s[0] + s.size(), - s_, opt); - } - return s; -} - -//------------------------------------------------ - result make_pct_string_view( string_view s) noexcept diff --git a/include/boost/url/impl/segments_base.ipp b/include/boost/url/impl/segments_base.ipp index 08122dda..e2403ff0 100644 --- a/include/boost/url/impl/segments_base.ipp +++ b/include/boost/url/impl/segments_base.ipp @@ -31,7 +31,10 @@ dereference() const // we will again have to value-init (?) // the new chars. s_.acquire(); - (*it_.dereference()).assign_to(*s_); + decode_opts opt; + opt.plus_to_space = false; + it_.dereference().decode(opt, + string_token::assign_to(*s_)); valid_ = true; } return *s_; diff --git a/include/boost/url/impl/url_base.ipp b/include/boost/url/impl/url_base.ipp index 151ffded..c842615d 100644 --- a/include/boost/url/impl/url_base.ipp +++ b/include/boost/url/impl/url_base.ipp @@ -506,9 +506,9 @@ set_encoded_password( /* host_type host_type() // ipv4, ipv6, ipvfuture, name -std::string host() // return encoded_host().decode_to_string() +std::string host() // return encoded_host().decode() pct_string_view encoded_host() // return host part, as-is -std::string host_address() // return encoded_host_address().decode_to_string() +std::string host_address() // return encoded_host_address().decode() pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets ipv4_address host_ipv4_address() // return ipv4_address or {} diff --git a/include/boost/url/impl/url_view_base.ipp b/include/boost/url/impl/url_view_base.ipp index 1adbd3cc..a4c33f0c 100644 --- a/include/boost/url/impl/url_view_base.ipp +++ b/include/boost/url/impl/url_view_base.ipp @@ -201,15 +201,6 @@ has_userinfo() const noexcept return true; } -std::string -url_view_base:: -userinfo() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_userinfo().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_userinfo() const noexcept @@ -229,15 +220,6 @@ encoded_userinfo() const noexcept return detail::make_pct_string_view(s); } -std::string -url_view_base:: -user() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_user().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_user() const noexcept @@ -271,15 +253,6 @@ has_password() const noexcept return false; } -std::string -url_view_base:: -password() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_password().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_password() const noexcept @@ -312,9 +285,9 @@ encoded_password() const noexcept /* host_type host_type() // ipv4, ipv6, ipvfuture, name -std::string host() // return encoded_host().decode_to_string() +std::string host() // return encoded_host().decode() pct_string_view encoded_host() // return host part, as-is -std::string host_address() // return encoded_host_address().decode_to_string() +std::string host_address() // return encoded_host_address().decode() pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets ipv4_address host_ipv4_address() // return ipv4_address or {} @@ -324,15 +297,6 @@ std::string host_name() // return decoded name or "" pct_string_view encoded_host_name() // return encoded host name or "" */ -std::string -url_view_base:: -host() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_host().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_host() const noexcept @@ -342,15 +306,6 @@ encoded_host() const noexcept u_.decoded_[id_host]); } -std::string -url_view_base:: -host_address() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_host_address().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_host_address() const noexcept @@ -428,15 +383,6 @@ host_ipvfuture() const noexcept return s; } -std::string -url_view_base:: -host_name() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_host_name().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_host_name() const noexcept @@ -509,15 +455,6 @@ encoded_origin() const noexcept // //---------------------------------------------------------- -std::string -url_view_base:: -path() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_path().decode_to_string(opt); -} - pct_string_view url_view_base:: encoded_path() const noexcept @@ -573,15 +510,6 @@ encoded_query() const noexcept return s.substr(1); } -std::string -url_view_base:: -query() const -{ - decode_opts opt; - opt.plus_to_space = true; - return encoded_query().decode_to_string(opt); -} - params_encoded_view url_view_base:: encoded_params() const noexcept @@ -648,15 +576,6 @@ encoded_fragment() const noexcept s, u_.decoded_[id_frag]); } -std::string -url_view_base:: -fragment() const -{ - decode_opts opt; - opt.plus_to_space = false; - return encoded_fragment().decode_to_string(opt); -} - //------------------------------------------------ pct_string_view diff --git a/include/boost/url/params_base.hpp b/include/boost/url/params_base.hpp index cd94707e..dd3f337c 100644 --- a/include/boost/url/params_base.hpp +++ b/include/boost/url/params_base.hpp @@ -66,6 +66,17 @@ public: become invalidated when that particular iterator is incremented, decremented, or destroyed. + + @note + + The implementation may use temporary, + recycled storage to store decoded + strings. These iterators are meant + to be used ephemerally. That is, for + short durations such as within a + function scope. Do not store + iterators with static storage + duration or as long-lived objects. */ #ifdef BOOST_URL_DOCS using iterator = __see_below__; diff --git a/include/boost/url/params_ref.hpp b/include/boost/url/params_ref.hpp index 384cab6e..b084f715 100644 --- a/include/boost/url/params_ref.hpp +++ b/include/boost/url/params_ref.hpp @@ -137,7 +137,7 @@ public: @endcode @par Complexity - Linear in `other.string().size()`. + Linear in `other.buffer().size()`. @par Exception Safety Strong guarantee. diff --git a/include/boost/url/pct_string_view.hpp b/include/boost/url/pct_string_view.hpp index 06aa2535..b32cd37d 100644 --- a/include/boost/url/pct_string_view.hpp +++ b/include/boost/url/pct_string_view.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -52,9 +54,20 @@ make_pct_string_view( plus a few odds and ends to make it nice. */ +/** A reference to a valid percent-encoded string + + Objects of this type behave like a + @ref string_view and have the same interface, + but offer an additional invariant: they can + only be constructed from strings containing + valid percent-escapes. + Attempting construction from a string + containing invalid or malformed percent + escapes results in an exception. +*/ class pct_string_view final + : public grammar::string_view_base { - string_view s_; std::size_t dn_ = 0; #ifndef BOOST_URL_DOCS @@ -74,7 +87,8 @@ class pct_string_view final char const* p, std::size_t n, std::size_t dn) noexcept - : s_(p, n) + : string_view_base( + string_view(p, n)) , dn_(dn) { } @@ -83,42 +97,74 @@ class pct_string_view final pct_string_view( string_view s, std::size_t dn) noexcept - : s_(s) + : string_view_base(s) , dn_(dn) { } + BOOST_URL_DECL + void + decode_impl( + string_token::arg& dest, + decode_opts const& opt) const; + public: - // types - typedef std::char_traits traits_type; - typedef char value_type; - typedef char* pointer; - typedef char const* const_pointer; - typedef char& reference; - typedef char const& const_reference; - typedef char const* const_iterator; - typedef const_iterator iterator; - typedef std::reverse_iterator< - const_iterator> const_reverse_iterator; - typedef const_reverse_iterator reverse_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - static constexpr std::size_t npos = string_view::npos; - - //-------------------------------------------- - /** Constructor + + Default constructed string are empty. + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. */ constexpr pct_string_view() = default; /** Constructor + + The copy will reference the same + underlying character buffer. + Ownership is not transferred. + + @par Postconditions + @code + this->data() == other.data() + @endcode + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. + + @par other The string to copy. */ constexpr pct_string_view( - pct_string_view const&) = default; + pct_string_view const& other) = default; /** Constructor + + The newly constructed string will + reference the specified character + buffer. Ownership is not transferred. + + @par Postconditions + @code + this->data() == s + @endcode + + @par Complexity + Linear in `std::strlen(s)`. + + @par Exception Safety + Exceptions thrown on invalid input. + + @throw system_error + The string contains an invalid percent encoding. + + @param s The string to construct from. */ pct_string_view( char const* s) @@ -133,6 +179,26 @@ public: std::nullptr_t) = delete; /** Constructor + + The newly constructed string will + reference the specified character + buffer. Ownership is not transferred. + + @par Postconditions + @code + this->data() == s && this->size() == len + @endcode + + @par Complexity + Linear in `len`. + + @par Exception Safety + Exceptions thrown on invalid input. + + @throw system_error + The string contains an invalid percent encoding. + + @param s, len The string to construct from. */ pct_string_view( char const* s, @@ -143,6 +209,26 @@ public: } /** Constructor + + The newly constructed string will + reference the specified character + buffer. Ownership is not transferred. + + @par Postconditions + @code + this->data() == first && this->data() + this->size() == last + @endcode + + @par Complexity + Linear in `len`. + + @par Exception Safety + Exceptions thrown on invalid input. + + @throw system_error + The string contains an invalid percent encoding. + + @param first, last The string to construct from. */ #ifdef BOOST_URL_DOCS pct_string_view( @@ -165,8 +251,25 @@ public: /** Constructor + The newly constructed string will + reference the specified character + buffer. Ownership is not transferred. + + @par Postconditions + @code + this->data() == s.data() && this->size() == s.size() + @endcode + + @par Complexity + Linear in `s.size()`. + @par Exception Safety Exceptions thrown on invalid input. + + @throw system_error + The string contains an invalid percent encoding. + + @param s The string to construct from. */ BOOST_URL_DECL pct_string_view( @@ -174,13 +277,28 @@ public: /** Assignment + The copy will reference the same + underlying character buffer. + Ownership is not transferred. + + @par Postconditions + @code + this->data() == other.data() + @endcode + @par Complexity Constant. + + @par Exception Safety + Throws nothing. + + @par other The string to copy. */ pct_string_view& operator=( - pct_string_view const&) = default; + pct_string_view const& other) = default; friend + BOOST_URL_DECL result make_pct_string_view( string_view s) noexcept; @@ -188,6 +306,17 @@ public: //-------------------------------------------- /** Return the decoded size + + This function returns the number of + characters in the resulting string if + percent escapes were converted into + ordinary characters. + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. */ std::size_t decoded_size() const noexcept @@ -195,7 +324,21 @@ public: return dn_; } - /** Return a decoding view + /** Return the string as a range of decoded characters + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. + + @param opt The options to use for decoding + percent escapes. If this parameter is + omitted, default settings are used. + + @see + @ref decode_opts, + @ref decode_view. */ decode_view decoded( @@ -205,7 +348,16 @@ public: s_, dn_, opt); } - /** Return a decoding view + /** Return the string as a range of decoded characters + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. + + @see + @ref decode_view. */ decode_view operator*() const noexcept @@ -214,44 +366,60 @@ public: } /** Return the string with percent-decoding - */ - BOOST_URL_DECL - std::string - decode_to_string( - decode_opts const& opt = {}) const; - //-------------------------------------------- + This function converts percent escapes + in the string into ordinary characters + and returns the result. + When called with no arguments, the + return type is `std::string`. + Otherwise, the return type and style + of output is determined by which string + token is passed. - /** Conversion + @par Example + @code + assert( pct_string_view( "Program%20Files" ).decode() == "Program Files" ); + @endcode + + @par Complexity + Linear in `this->size()`. + + @par Exception Safety + Calls to allocate may throw. + String tokens may throw exceptions. + + @param opt The options for encoding. If + this parameter is omitted, the default + options will be used. + + @param token An optional string token. + If this parameter is omitted, then + a new `std::string` is returned. + Otherwise, the function return type + will be the result type of the token. + + @see + @ref decode_opts, + @ref string_token::return_string. */ - operator - string_view() const noexcept + template + BOOST_URL_STRTOK_RETURN + decode( + decode_opts opt = {}, + BOOST_URL_STRTOK_ARG(token)) const { - return s_; - } +/* If you get a compile error here, it + means that the token you passed does + not meet the requirements stated + in the documentation. +*/ + static_assert( + string_token::is_token< + StringToken>::value, + "Type requirements not met"); - /** Conversion - */ -#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) - operator - std::string_view() const noexcept - { - return std::string_view(s_); - } -#endif - - /** Conversion - - Conversion to std::string is explicit - because assigning to string using an - implicit constructor will not preserve - capacity. - */ - explicit - operator - std::string() const noexcept - { - return std::string(s_); + decode_impl(token, opt); + return token.result(); } #ifndef BOOST_URL_DOCS @@ -265,472 +433,17 @@ public: //-------------------------------------------- - // iterator support - - BOOST_CONSTEXPR const_iterator begin() const noexcept - { - return s_.begin(); - } - - BOOST_CONSTEXPR const_iterator end() const noexcept - { - return s_.end(); - } - - BOOST_CONSTEXPR const_iterator cbegin() const noexcept - { - return s_.cbegin(); - } - - BOOST_CONSTEXPR const_iterator cend() const noexcept - { - return s_.cend(); - } - -#ifdef __cpp_lib_array_constexpr - constexpr -#endif - const_reverse_iterator rbegin() const noexcept - { - return s_.rbegin(); - } - -#ifdef __cpp_lib_array_constexpr - constexpr -#endif - const_reverse_iterator rend() const noexcept - { - return s_.rend(); - } - -#ifdef __cpp_lib_array_constexpr - constexpr -#endif - const_reverse_iterator crbegin() const noexcept - { - return s_.crbegin(); - } - -#ifdef __cpp_lib_array_constexpr - constexpr -#endif - const_reverse_iterator crend() const noexcept - { - return s_.crend(); - } - - // capacity - - BOOST_CONSTEXPR size_type size() const noexcept - { - return s_.size(); - } - - BOOST_CONSTEXPR size_type length() const noexcept - { - return s_.length(); - } - - BOOST_CONSTEXPR size_type max_size() const noexcept - { - return s_.max_size(); - } - - BOOST_CONSTEXPR bool empty() const noexcept - { - return s_.empty(); - } - - // element access - - BOOST_CXX14_CONSTEXPR const_reference - operator[]( size_type pos ) const noexcept - { - return s_[pos]; - } - - BOOST_CXX14_CONSTEXPR const_reference - at( size_type pos ) const - { - return s_.at(pos); - } - - BOOST_CXX14_CONSTEXPR const_reference - front() const noexcept - { - return s_.front(); - } - - BOOST_CXX14_CONSTEXPR const_reference - back() const noexcept - { - return s_.back(); - } - - BOOST_CONSTEXPR const_pointer - data() const noexcept - { - return s_.data(); - } - - // string operations - - BOOST_CXX14_CONSTEXPR size_type copy( - char* s, size_type n, size_type pos = 0 ) const - { - return s_.copy(s, n, pos); - } - - BOOST_CXX14_CONSTEXPR string_view substr( - size_type pos = 0, size_type n = string_view::npos ) const - { - return s_.substr(pos, n); - } - - // comparison - - BOOST_CXX14_CONSTEXPR int - compare( string_view str ) const noexcept - { - return s_.compare(str); - } - - BOOST_CONSTEXPR int compare( - size_type pos1, size_type n1, string_view str ) const - { - return s_.compare(pos1, n1, str); - } - - BOOST_CONSTEXPR int compare( - size_type pos1, size_type n1, string_view str, - size_type pos2, size_type n2 ) const - { - return s_.compare(pos1, n1, str, pos2, n2); - } - - BOOST_CONSTEXPR int compare( - char const* s ) const noexcept - { - return s_.compare(s); - } - - BOOST_CONSTEXPR int compare( - size_type pos1, size_type n1, char const* s ) const - { - return s_.compare(pos1, n1, s); - } - - BOOST_CONSTEXPR int compare( - size_type pos1, size_type n1, - char const* s, size_type n2 ) const - { - return s_.compare(pos1, n1, s, n2); - } - - // starts_with - - BOOST_CONSTEXPR bool starts_with( - string_view x ) const noexcept - { - return s_.starts_with(x); - } - - BOOST_CONSTEXPR bool starts_with( - char x ) const noexcept - { - return s_.starts_with(x); - } - - BOOST_CONSTEXPR bool starts_with( - char const* x ) const noexcept - { - return s_.starts_with(x); - } - - // ends_with - - BOOST_CONSTEXPR bool ends_with( - string_view x ) const noexcept - { - return s_.ends_with(x); - } - - BOOST_CONSTEXPR bool ends_with( - char x ) const noexcept - { - return s_.ends_with(x); - } - - BOOST_CONSTEXPR bool ends_with( - char const* x ) const noexcept - { - return s_.ends_with(x); - } - - // find - - BOOST_CONSTEXPR size_type find( - string_view str, size_type pos = 0 ) const noexcept - { - return s_.find(str, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find( - char c, size_type pos = 0 ) const noexcept - { - return s_.find(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.find(s, pos, n); - } - - BOOST_CONSTEXPR size_type find( - char const* s, size_type pos = 0 ) const noexcept - { - return s_.find(s, pos); - } - - // rfind - - BOOST_CONSTEXPR size_type rfind( - string_view str, size_type pos = string_view::npos ) const noexcept - { - return s_.rfind(str, pos); - } - - BOOST_CXX14_CONSTEXPR size_type rfind( - char c, size_type pos = string_view::npos ) const noexcept - { - return s_.rfind(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type rfind( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.rfind(s, pos, n); - } - - BOOST_CONSTEXPR size_type rfind( - char const* s, size_type pos = string_view::npos ) const noexcept - { - return s_.rfind(s, pos); - } - - // find_first_of - - BOOST_CXX14_CONSTEXPR size_type find_first_of( - string_view str, size_type pos = 0 ) const noexcept - { - return s_.find_first_of(str, pos); - } - - BOOST_CONSTEXPR size_type find_first_of( - char c, size_type pos = 0 ) const noexcept - { - return s_.find_first_of(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_first_of( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.find_first_of(s, pos, n); - } - - BOOST_CXX14_CONSTEXPR size_type find_first_of( - char const* s, size_type pos = 0 ) const noexcept - { - return s_.find_first_of(s, pos); - } - - // find_last_of - - BOOST_CXX14_CONSTEXPR size_type find_last_of( - string_view str, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_of(str, pos); - } - - BOOST_CONSTEXPR size_type find_last_of( - char c, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_of(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_last_of( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.find_last_of(s, pos, n); - } - - BOOST_CXX14_CONSTEXPR size_type find_last_of( - char const* s, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_of(s, pos); - } - - // find_first_not_of - - BOOST_CXX14_CONSTEXPR size_type find_first_not_of( - string_view str, size_type pos = 0 ) const noexcept - { - return s_.find_first_not_of(str, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_first_not_of( - char c, size_type pos = 0 ) const noexcept - { - return s_.find_first_not_of(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_first_not_of( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.find_first_not_of(s, pos, n); - } - - BOOST_CXX14_CONSTEXPR size_type find_first_not_of( - char const* s, size_type pos = 0 ) const noexcept - { - return s_.find_first_not_of(s, pos); - } - - // find_last_not_of - - BOOST_CXX14_CONSTEXPR size_type find_last_not_of( - string_view str, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_not_of(str, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_last_not_of( - char c, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_not_of(c, pos); - } - - BOOST_CXX14_CONSTEXPR size_type find_last_not_of( - char const* s, size_type pos, size_type n ) const noexcept - { - return s_.find_last_not_of(s, pos, n); - } - - BOOST_CXX14_CONSTEXPR size_type find_last_not_of( - char const* s, size_type pos = string_view::npos ) const noexcept - { - return s_.find_last_not_of(s, pos); - } - - // contains - - BOOST_CONSTEXPR bool contains( string_view sv ) const noexcept - { - return s_.contains(sv); - } - - BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept - { - return s_.contains(c); - } - - BOOST_CONSTEXPR bool contains( char const* s ) const noexcept - { - return s_.contains(s); - } - - // relational operators - - template - using is_match = std::integral_constant::value && - std::is_convertible::value && ( - std::is_same::type, - pct_string_view>::value || - std::is_same::type, - pct_string_view>::value)>; - - template - BOOST_CXX14_CONSTEXPR friend auto operator==( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) == string_view(s1); - } - - template - BOOST_CXX14_CONSTEXPR friend auto operator!=( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) != string_view(s1); - } - - template - BOOST_CXX14_CONSTEXPR friend auto operator<( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) < string_view(s1); - } - - template - BOOST_CXX14_CONSTEXPR friend auto operator<=( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) <= string_view(s1); - } - - template - BOOST_CXX14_CONSTEXPR friend auto operator>( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) > string_view(s1); - } - - template - BOOST_CXX14_CONSTEXPR friend auto operator>=( - S0 const& s0, S1 const& s1) noexcept -> - typename std::enable_if< - is_match::value, bool>::type - { - return string_view(s0) >= string_view(s1); - } - - //-------------------------------------------- - - inline friend std::size_t hash_value( - pct_string_view const& s) noexcept - { - return hash_value(s.s_); - } - // VFALCO No idea why this fails in msvc + /** Swap + */ /*BOOST_CXX14_CONSTEXPR*/ void swap( pct_string_view& s ) noexcept { - std::swap(s_, s.s_); + string_view_base::swap(s); std::swap(dn_, s.dn_); } }; -inline -std::ostream& -operator<<( - std::ostream& os, - pct_string_view const& s) -{ - return os << string_view(s); -} - //------------------------------------------------ #ifndef BOOST_URL_DOCS @@ -746,7 +459,6 @@ ref(pct_string_view& s) noexcept } template -inline pct_string_view make_pct_string_view( Args&&... args) noexcept @@ -761,7 +473,24 @@ make_pct_string_view( //------------------------------------------------ /** Return a validated percent-encoded string + + This function attempts to construct a + percent-encoded string from a character + buffer. Upon success, the valid string + is returned. Otherwise the result contains + an error code. The new string will reference + the existing character buffer. Ownership + is not transferred. + + @par Complexity + Linear in `s.size()`. + + @par Exception Safety + Throws nothing. + + @par s The string to construct from. */ +BOOST_URL_DECL result make_pct_string_view( string_view s) noexcept; diff --git a/include/boost/url/rfc/impl/query_rule.ipp b/include/boost/url/rfc/impl/query_rule.ipp index b29c5cc8..961a648e 100644 --- a/include/boost/url/rfc/impl/query_rule.ipp +++ b/include/boost/url/rfc/impl/query_rule.ipp @@ -11,7 +11,6 @@ #define BOOST_URL_RFC_IMPL_QUERY_RULE_IPP #include -#include #include #include #include diff --git a/include/boost/url/segments_encoded_base.hpp b/include/boost/url/segments_encoded_base.hpp index 6c2c2033..176a8e40 100644 --- a/include/boost/url/segments_encoded_base.hpp +++ b/include/boost/url/segments_encoded_base.hpp @@ -86,7 +86,7 @@ public: @par Example @code - segments_encoded_view::value_type ps( *url_view( "/path/to/file.txt" ).encoded_segments().back() ); + segments_encoded_base::value_type ps( url_view( "/path/to/file.txt" ).encoded_segments().back() ); @endcode */ using value_type = std::string; diff --git a/include/boost/url/segments_encoded_view.hpp b/include/boost/url/segments_encoded_view.hpp index 7a55fae9..dba26e3c 100644 --- a/include/boost/url/segments_encoded_view.hpp +++ b/include/boost/url/segments_encoded_view.hpp @@ -40,7 +40,7 @@ namespace urls { segments_encoded_view ps = u.encoded_segments(); - assert( ps.buffer().data() == u.string().data() ); + assert( ps.buffer().data() == u.buffer().data() ); @endcode Strings produced when elements are returned diff --git a/include/boost/url/segments_view.hpp b/include/boost/url/segments_view.hpp index b971bb2c..a99b2d1e 100644 --- a/include/boost/url/segments_view.hpp +++ b/include/boost/url/segments_view.hpp @@ -36,7 +36,7 @@ namespace urls { segments_view ps = u.segments(); - assert( ps.buffer().data() == u.string().data() ); + assert( ps.buffer().data() == u.buffer().data() ); @endcode The strings produced when iterators are diff --git a/include/boost/url/src.hpp b/include/boost/url/src.hpp index fe1bb6dd..ff599f1d 100644 --- a/include/boost/url/src.hpp +++ b/include/boost/url/src.hpp @@ -36,7 +36,6 @@ in a translation unit of the program. #include #include #include -#include #include #include #include @@ -86,6 +85,7 @@ in a translation unit of the program. #include #include #include +#include //------------------------------------------------ // diff --git a/include/boost/url/url.natvis b/include/boost/url/url.natvis index ddbc1fbd..97a0d70a 100644 --- a/include/boost/url/url.natvis +++ b/include/boost/url/url.natvis @@ -39,10 +39,6 @@ {s_} - - {s_} [{n_}] - - {cs_,[offset_[id_end]]s} @@ -84,4 +80,18 @@ + + {s_} [{n_}] + + + + nullptr + {p_->t} + + + {p_->refs} + + + + diff --git a/include/boost/url/url_base.hpp b/include/boost/url/url_base.hpp index e12df59c..9873dfb0 100644 --- a/include/boost/url/url_base.hpp +++ b/include/boost/url/url_base.hpp @@ -106,6 +106,12 @@ public: //-------------------------------------------- /** Return the encoded URL as a null-terminated string + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. */ char const* c_str() const noexcept @@ -117,6 +123,12 @@ public: This does not include the null terminator, which is always present. + + @par Complexity + Constant. + + @par Exception Safety + Throws nothing. */ std::size_t capacity() const noexcept @@ -178,7 +190,7 @@ public: @par Example @code - assert( url("http://www.example.com/index.htm" ).remove_scheme().string() == "//www.example.com/index.htm" ); + assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" ); @endcode @par Postconditions @@ -262,7 +274,7 @@ public: @par Example @code - assert( url( "http://example.com/echo.cgi" ).set_scheme( scheme::wss ).string() == "wss://example.com/echo.cgi" ); + assert( url( "http://example.com/echo.cgi" ).set_scheme( scheme::wss ).buffer() == "wss://example.com/echo.cgi" ); @endcode @par Complexity @@ -302,7 +314,7 @@ public: @par Example @code - assert( url( "http://example.com/echo.cgi" ).remove_authority().string() == "http:/echo.cgi" ); + assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" ); @endcode @par Postconditions @@ -856,7 +868,7 @@ public: @par Example @code - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); @endcode @par Postconditions @@ -935,7 +947,7 @@ public: @par Example @code - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); @endcode @par Postconditions @@ -1013,7 +1025,7 @@ public: @par Example @code - assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); @endcode @par Postconditions @@ -1112,7 +1124,7 @@ public: @par Example @code - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); @endcode @par Postconditions @@ -1193,7 +1205,7 @@ public: @par Example @code - assert( url("http://www.example.com").set_host_address( ipv4_address( "127.0.0.1" ) ).string() == "http://127.0.0.1" ); + assert( url("http://www.example.com").set_host_address( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" ); @endcode @par Complexity @@ -1313,7 +1325,7 @@ public: @par Example @code - assert( url().set_host_ipvfuture( "v42.bis" ).string() == "//[v42.bis]" ); + assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" ); @endcode @par Complexity @@ -1590,7 +1602,7 @@ public: @par Example @code - assert( url( "http://www.example.com/index.htm" ).remove_origin().string() == "/index.htm" ); + assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" ); @endcode @par Postconditions @@ -1629,7 +1641,7 @@ public: @code url u( "path/to/file.txt" ); assert( u.set_path_absolute( true ) ); - assert( u.string() == "/path/to/file.txt" ); + assert( u.buffer() == "/path/to/file.txt" ); @endcode @par Postconditions @@ -1921,7 +1933,7 @@ public: @par Example @code - assert( url( "http://www.example.com?id=42" ).remove_query().string() == "http://www.example.com" ); + assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" ); @endcode @par Postconditions @@ -2172,7 +2184,7 @@ public: @par Example @code - assert( url( "?first=john&last=doe#anchor" ).remove_fragment().string() == "?first=john&last=doe" ); + assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" ); @endcode @par Postconditions @@ -2487,19 +2499,19 @@ public: @code url base1( "/one/two/three" ); base1.resolve("four"); - assert( base1.string() == "/one/two/four" ); + assert( base1.buffer() == "/one/two/four" ); url base2( "http://example.com/" ) base2.resolve("/one"); - assert( base2.string() == "http://example.com/one" ); + assert( base2.buffer() == "http://example.com/one" ); url base3( "http://example.com/one" ); base3.resolve("/two"); - assert( base3.string() == "http://example.com/two" ); + assert( base3.buffer() == "http://example.com/two" ); url base4( "http://a/b/c/d;p?q" ); base4.resolve("g#s"); - assert( base4.string() == "http://a/b/c/g#s" ); + assert( base4.buffer() == "http://a/b/c/g#s" ); @endcode @par BNF diff --git a/include/boost/url/url_view_base.hpp b/include/boost/url/url_view_base.hpp index beedb55f..785f991e 100644 --- a/include/boost/url/url_view_base.hpp +++ b/include/boost/url/url_view_base.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -215,7 +216,7 @@ public: Throws nothing. */ string_view - string() const noexcept + buffer() const noexcept { return string_view( data(), size()); @@ -243,7 +244,7 @@ public: sp = u.persist(); assert( sp->data() != s.data() ); // different buffer - assert( sp->string() == s); // same contents + assert( sp->buffer() == s); // same contents // s is destroyed and thus u // becomes invalid, but sp remains valid. @@ -572,6 +573,14 @@ public: Any percent-escapes in the string are decoded first. + @note + This function uses the string token + return type customization. Depending on + the token passed, the return type and + behavior of the function can be different. + See @ref string_token::return_string + for more information. + @par Example @code assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" ); @@ -583,6 +592,12 @@ public: @par Exception Safety Calls to allocate may throw. + @return When called with no arguments, + a value of type `std::string` is + returned. Otherwise, the return type + and meaning depends on the string token + passed to the function. + @par BNF @code userinfo = user [ ":" [ password ] ] @@ -603,9 +618,16 @@ public: @ref password, @ref user. */ - BOOST_URL_DECL - std::string - userinfo() const; + template + BOOST_URL_STRTOK_RETURN + userinfo( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_userinfo().decode( + opt, std::move(token)); + } /** Return the userinfo @@ -694,9 +716,16 @@ public: @ref password, @ref userinfo. */ - BOOST_URL_DECL - std::string - user() const; + template + BOOST_URL_STRTOK_RETURN + user( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_user().decode( + opt, std::move(token)); + } /** Return the user @@ -826,9 +855,16 @@ public: @ref user, @ref userinfo. */ - BOOST_URL_DECL - std::string - password() const; + template + BOOST_URL_STRTOK_RETURN + password( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_password().decode( + opt, std::move(token)); + } /** Return the password @@ -945,9 +981,16 @@ public: @li 3.2.2. Host (rfc3986) */ - BOOST_URL_DECL - std::string - host() const; + template + BOOST_URL_STRTOK_RETURN + host( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_host().decode( + opt, std::move(token)); + } /** Return the host @@ -1034,9 +1077,16 @@ public: @li 3.2.2. Host (rfc3986) */ - BOOST_URL_DECL - std::string - host_address() const; + template + BOOST_URL_STRTOK_RETURN + host_address( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_host_address().decode( + opt, std::move(token)); + } /** Return the host @@ -1248,9 +1298,16 @@ public: @li 3.2.2. Host (rfc3986) */ - BOOST_URL_DECL - std::string - host_name() const; + template + BOOST_URL_STRTOK_RETURN + host_name( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_host_name().decode( + opt, std::move(token)); + } /** Return the host name @@ -1573,9 +1630,16 @@ public: @ref encoded_segments. @ref segments. */ - BOOST_URL_DECL - std::string - path() const; + template + BOOST_URL_STRTOK_RETURN + path( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_path().decode( + opt, std::move(token)); + } /** Return the path @@ -1808,9 +1872,16 @@ public: @ref has_query, @ref params. */ - BOOST_URL_DECL - std::string - query() const; + template + BOOST_URL_STRTOK_RETURN + query( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = true; + return encoded_query().decode( + opt, std::move(token)); + } /** Return the query @@ -2059,9 +2130,16 @@ public: @ref encoded_fragment, @ref has_fragment. */ - BOOST_URL_DECL - std::string - fragment() const; + template + BOOST_URL_STRTOK_RETURN + fragment( + BOOST_URL_STRTOK_ARG(token)) const + { + decode_opts opt; + opt.plus_to_space = false; + return encoded_fragment().decode( + opt, std::move(token)); + } /** Return the fragment @@ -2528,7 +2606,7 @@ public: std::ostream& os, url_view_base const& u) { - return os << u.string(); + return os << u.buffer(); } }; @@ -2551,11 +2629,11 @@ public: @par Effects @code - return os << u.string(); + return os << u.buffer(); @endcode @par Complexity - Linear in `u.string().size()` + Linear in `u.buffer().size()` @par Exception Safety Basic guarantee. diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 76c4929b..ab33f77e 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -78,6 +78,7 @@ set(BOOST_URL_TESTS_FILES grammar/range_rule.cpp grammar/recycled.cpp grammar/string_token.cpp + grammar/string_view_base.cpp grammar/token_rule.cpp grammar/tuple_rule.cpp grammar/type_traits.cpp diff --git a/test/unit/Jamfile b/test/unit/Jamfile index 8e51ad01..b34c1894 100644 --- a/test/unit/Jamfile +++ b/test/unit/Jamfile @@ -77,6 +77,7 @@ local SOURCES = grammar/range_rule.cpp grammar/recycled.cpp grammar/string_token.cpp + grammar/string_view_base.cpp grammar/token_rule.cpp grammar/tuple_rule.cpp grammar/type_traits.cpp diff --git a/test/unit/authority_view.cpp b/test/unit/authority_view.cpp index ba385082..fede61b8 100644 --- a/test/unit/authority_view.cpp +++ b/test/unit/authority_view.cpp @@ -63,8 +63,8 @@ public: { string_view s = "xyz"; authority_view a = parse_authority(s).value(); - BOOST_TEST_EQ(a.string(), s); - BOOST_TEST_EQ(a.string().data(), s.data()); + BOOST_TEST_EQ(a.buffer(), s); + BOOST_TEST_EQ(a.buffer().data(), s.data()); } } diff --git a/test/unit/decode_view.cpp b/test/unit/decode_view.cpp index 67063772..9772ba0b 100644 --- a/test/unit/decode_view.cpp +++ b/test/unit/decode_view.cpp @@ -38,7 +38,6 @@ struct decode_view_test decode_view s; BOOST_TEST_EQ(s, ""); BOOST_TEST_EQ(s.size(), 0u); - BOOST_TEST_EQ(s.encoded().size(), 0u); } // decode_view(char const*) @@ -46,7 +45,6 @@ struct decode_view_test decode_view s(str.data()); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } // decode_view(char const*, bool plus_to_space) @@ -55,7 +53,6 @@ struct decode_view_test s(str.data(), no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } // decode_view(string_view) @@ -63,7 +60,6 @@ struct decode_view_test decode_view s(str); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } // decode_view(string_view, bool plus_to_space) @@ -71,7 +67,6 @@ struct decode_view_test decode_view s(str, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) @@ -81,7 +76,6 @@ struct decode_view_test decode_view s(std_str); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } // decode_view(string_view, bool plus_to_space) @@ -90,7 +84,6 @@ struct decode_view_test decode_view s(std_str, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } #endif @@ -100,7 +93,6 @@ struct decode_view_test decode_view s(ss); BOOST_TEST_EQ(s, dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } // decode_view(string_view, bool plus_to_space) @@ -109,7 +101,6 @@ struct decode_view_test decode_view s(ss, no_plus_opt); BOOST_TEST_EQ(s, no_plus_dec_str); BOOST_TEST_EQ(s.size(), dn); - BOOST_TEST_EQ(s.encoded().size(), str.size()); } } @@ -149,12 +140,6 @@ struct decode_view_test decode_view s(str); BOOST_TEST_EQ(s.back(), 't'); } - - // encoded().data() - { - decode_view s(str); - BOOST_TEST_EQ(s.encoded().data(), str.data()); - } } void @@ -166,24 +151,6 @@ struct decode_view_test BOOST_TEST_EQ(s.size(), dn); } - // encoded().size() - { - decode_view s(str); - BOOST_TEST_EQ(s.encoded().size(), str.size()); - } - - // encoded().length() - { - decode_view s(str); - BOOST_TEST_EQ(s.encoded().length(), str.size()); - } - - // encoded().max_size() - { - decode_view s(str); - BOOST_TEST_GT(s.encoded().max_size(), 0u); - } - // empty() { decode_view s; @@ -194,18 +161,6 @@ struct decode_view_test } } - void - testCopy() - { - // copy() - { - decode_view s(str); - std::string out(s.size(), ' '); - s.copy(&out[0], s.size()); - BOOST_TEST_EQ(s, dec_str); - } - } - void testCompare() { @@ -300,56 +255,6 @@ struct decode_view_test } } - void - testConversion() - { - // to_string() - { - decode_view s(str); - BOOST_TEST_EQ(s.to_string(), dec_str); - } - - // append_to() - { - decode_view s(str); - std::string o = "init "; - s.append_to(o); - - std::string exp = std::string("init "); - exp.append(dec_str.data(), dec_str.size()); - - BOOST_TEST_EQ(o, exp); - } - - // assign_to() - { - decode_view s(str); - std::string o = "init "; - s.assign_to(o); - BOOST_TEST_EQ(o, dec_str); - } - - // pass it to a function taking a string_view - { - auto f = [this](string_view sv) - { - BOOST_TEST(sv == dec_str); - }; - decode_view s(str); - f(s.to_string()); - } - - // pass it to a function taking a char* - { - auto f = [this](char const* sv) - { - BOOST_TEST(sv == dec_str); - }; - decode_view s(str); - f(s.to_string().c_str()); - } - } - void testStream() { @@ -371,78 +276,6 @@ struct decode_view_test // no warning about object slicing ss << ds; } - - { - auto break_stuff = - [this](urls::string_view const& a) { - urls::string_view b{}; - b = a; - BOOST_TEST_EQ(b.size(), dn); - }; - break_stuff(decode_view{str}.to_string()); - } - - { -#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) - struct A - { - A( std::string_view s) - { - boost::ignore_unused(s); - } - - A( std::string_view s, std::size_t dn ) - { - BOOST_TEST_EQ(s.size(), dn); - boost::ignore_unused(s, dn); - } - }; - A a1(decode_view{str}.to_string(), dn); - A a2(std::string_view(decode_view{str}.to_string()), dn); - A a3 = std::string_view(decode_view{str}.to_string()); - // https://en.cppreference.com/w/cpp/language/copy_initialization#Notes - // A a4 = decode_view{str}.to_string(); - boost::ignore_unused(a1, a2, a3); -#endif - struct B - { - B( urls::string_view s) - { - boost::ignore_unused(s); - } - - B( urls::string_view s, std::size_t dn ) - { - BOOST_TEST_EQ(s.size(), dn); - boost::ignore_unused(s, dn); - } - }; - B b1(decode_view{str}.to_string(), dn); - B b2(string_view( - decode_view{str}.to_string()), dn); - B b3 = string_view( - decode_view{str}.to_string()); - // https://en.cppreference.com/w/cpp/language/copy_initialization#Notes - // B b4 = decode_view{str}.to_string(); - boost::ignore_unused(b1, b2, b3); - } - - { -#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) - auto f1 = []( std::string_view ) {}; - f1(decode_view{str}.to_string()); -#endif - auto f2 = []( urls::string_view ) {}; - f2(decode_view{str}.to_string()); - - auto f3 = []( std::string const& ) {}; - f3(decode_view{str}.to_string()); - - auto f4 = []( std::basic_string, - std::allocator> const&) {}; - f4(decode_view{str}.to_string()); - } } void @@ -452,9 +285,7 @@ struct decode_view_test testIter(); testAccessors(); testObservers(); - testCopy(); testCompare(); - testConversion(); testStream(); testPR127Cases(); } diff --git a/test/unit/doc_container.cpp b/test/unit/doc_container.cpp index 93bb7f17..9114db74 100644 --- a/test/unit/doc_container.cpp +++ b/test/unit/doc_container.cpp @@ -25,7 +25,7 @@ struct doc_container_test { std::list< std::string > seq; for( auto s : u.encoded_segments() ) - seq.push_back( s.decode_to_string() ); + seq.push_back( s.decode() ); return seq; } //] diff --git a/test/unit/grammar/string_view_base.cpp b/test/unit/grammar/string_view_base.cpp new file mode 100644 index 00000000..bad3306d --- /dev/null +++ b/test/unit/grammar/string_view_base.cpp @@ -0,0 +1,33 @@ +// +// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url +// + +// Test that header file is self-contained. +#include + +#include "test_suite.hpp" + +namespace boost { +namespace urls { +namespace grammar { + +struct string_view_base_test +{ + void + run() + { + } +}; + +TEST_SUITE( + string_view_base_test, + "boost.url.grammar.string_view_base"); + +} // grammar +} // urls +} // boost diff --git a/test/unit/grammar/type_traits.cpp b/test/unit/grammar/type_traits.cpp index f7d0afe1..63aff861 100644 --- a/test/unit/grammar/type_traits.cpp +++ b/test/unit/grammar/type_traits.cpp @@ -24,13 +24,6 @@ struct type_traits_test void run() { -#ifdef __cpp_lib_concepts - BOOST_TEST(std::input_iterator); -#endif - BOOST_TEST(is_mutable_string::value); - BOOST_TEST_NOT(is_mutable_string::value); - BOOST_TEST_NOT(is_mutable_string>::value); - BOOST_TEST_NOT(is_mutable_string::value); } }; diff --git a/test/unit/segments_encoded_base.cpp b/test/unit/segments_encoded_base.cpp index 5edb1d40..d5f4f025 100644 --- a/test/unit/segments_encoded_base.cpp +++ b/test/unit/segments_encoded_base.cpp @@ -26,7 +26,7 @@ struct segments_encoded_base_test { // value_type { - segments_encoded_base::value_type ps( *url_view( "/path/to/file.txt" ).encoded_segments().back() ); + segments_encoded_base::value_type ps( url_view( "/path/to/file.txt" ).encoded_segments().back() ); ignore_unused(ps); } diff --git a/test/unit/segments_encoded_ref.cpp b/test/unit/segments_encoded_ref.cpp index 8c6fcabf..2105c8a3 100644 --- a/test/unit/segments_encoded_ref.cpp +++ b/test/unit/segments_encoded_ref.cpp @@ -97,8 +97,8 @@ struct segments_encoded_ref_test Type ps1(ps0); BOOST_TEST_EQ(&ps0.url(), &ps1.url()); BOOST_TEST_EQ( - ps0.url().string().data(), - ps1.url().string().data()); + ps0.url().buffer().data(), + ps1.url().buffer().data()); } // operator=(segments_encoded_ref) diff --git a/test/unit/segments_encoded_view.cpp b/test/unit/segments_encoded_view.cpp index 59cfc5a0..e54b8d7c 100644 --- a/test/unit/segments_encoded_view.cpp +++ b/test/unit/segments_encoded_view.cpp @@ -219,7 +219,7 @@ struct segments_const_encoded_view_test segments_encoded_view ps = u.encoded_segments(); - assert( ps.buffer().data() == u.string().data() ); + assert( ps.buffer().data() == u.buffer().data() ); ignore_unused(ps); } diff --git a/test/unit/segments_ref.cpp b/test/unit/segments_ref.cpp index e27c7669..7c6d5ce2 100644 --- a/test/unit/segments_ref.cpp +++ b/test/unit/segments_ref.cpp @@ -99,8 +99,8 @@ struct segments_ref_test Type ps(ps0); BOOST_TEST_EQ(&ps0.url(), &ps.url()); BOOST_TEST_EQ( - ps0.url().string().data(), - ps.url().string().data()); + ps0.url().buffer().data(), + ps.url().buffer().data()); } // operator=(segments_ref) diff --git a/test/unit/segments_view.cpp b/test/unit/segments_view.cpp index 67a3685e..5041eacd 100644 --- a/test/unit/segments_view.cpp +++ b/test/unit/segments_view.cpp @@ -209,7 +209,7 @@ struct segments_view_test segments_view ps = u.segments(); - assert( ps.buffer().data() == u.string().data() ); + assert( ps.buffer().data() == u.buffer().data() ); ignore_unused(ps); } diff --git a/test/unit/snippets.cpp b/test/unit/snippets.cpp index dbc97b7a..649bc165 100644 --- a/test/unit/snippets.cpp +++ b/test/unit/snippets.cpp @@ -35,7 +35,7 @@ using_url_views() //[snippet_accessing_1 url_view u( "https://user:pass@example.com:443/path/to/my%2dfile.txt?id=42&name=John%20Doe+Jingleheimer%2DSchmidt#page%20anchor" ); assert(u.scheme() == "https"); - assert(u.authority().string() == "user:pass@example.com:443"); + assert(u.authority().buffer() == "user:pass@example.com:443"); assert(u.userinfo() == "user:pass"); assert(u.user() == "user"); assert(u.password() == "pass"); @@ -320,7 +320,7 @@ parsing_urls() assert( r1.has_value() ); url dest; resolve(r1.value(), r0.value(), dest); - assert(dest.string() == "https://www.example.com/path/to/file.txt"); + assert(dest.buffer() == "https://www.example.com/path/to/file.txt"); //] boost::ignore_unused(dest); } @@ -377,7 +377,7 @@ parsing_components() string_view s = "https://user:pass@example.com:443/path/to/my%2dfile.txt?id=42&name=John%20Doe+Jingleheimer%2DSchmidt#page%20anchor"; url_view u( s ); assert(u.scheme() == "https"); - assert(u.authority().string() == "user:pass@example.com:443"); + assert(u.authority().buffer() == "user:pass@example.com:443"); assert(u.path() == "/path/to/my-file.txt"); assert(u.query() == "id=42&name=John Doe Jingleheimer-Schmidt"); assert(u.fragment() == "page anchor"); @@ -449,7 +449,7 @@ parsing_authority() { //[snippet_parsing_authority_1 url_view u( "https:///path/to_resource" ); - assert( u.authority().string() == ""); + assert( u.authority().buffer() == ""); assert( u.has_authority() ); assert( u.path() == "/path/to_resource" ); //] @@ -570,7 +570,7 @@ parsing_authority() //[snippet_parsing_authority_10a url_view u( "https:///path/to_resource" ); assert( u.has_authority() ); - assert( u.authority().string().empty() ); + assert( u.authority().buffer().empty() ); assert( u.path() == "/path/to_resource" ); //] } @@ -605,7 +605,7 @@ parsing_authority() { //[snippet_parsing_authority_10f url_view u( "mailto://John.Doe@example.com" ); - assert( u.authority().string() == "John.Doe@example.com" ); + assert( u.authority().buffer() == "John.Doe@example.com" ); assert( u.path().empty() ); //] } @@ -1072,14 +1072,14 @@ using_modifying() v.set_host("my website.com"); v.set_path("my file.txt"); v.set_query("id=42&name=John Doe"); - assert(v.string() == "https://my%20website.com/my%20file.txt?id=42&name=John%20Doe"); + assert(v.buffer() == "https://my%20website.com/my%20file.txt?id=42&name=John%20Doe"); //] //[snippet_modifying_4 v.set_scheme("http"); - assert(v.string() == "http://my%20website.com/my%20file.txt?id=42&name=John%20Doe"); + assert(v.buffer() == "http://my%20website.com/my%20file.txt?id=42&name=John%20Doe"); v.set_encoded_host("www.my%20example.com"); - assert(v.string() == "http://my%20example.com/my%20file.txt?id=42&name=John%20Doe"); + assert(v.buffer() == "http://my%20example.com/my%20file.txt?id=42&name=John%20Doe"); //] @@ -1260,10 +1260,10 @@ modifying_path() //[snippet_modifying_path_3 url u("https://www.boost.org/./a/../b"); u.normalize(); - assert(u.string() == "https://www.boost.org/b"); + assert(u.buffer() == "https://www.boost.org/b"); //] BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "https://www.boost.org/b"); + BOOST_TEST_EQ(u.buffer(), "https://www.boost.org/b"); BOOST_TEST_EQ(u.encoded_segments().size(), 1u); } { @@ -1316,7 +1316,7 @@ modifying_path() // "//path" will be considered the authority component url_view u3("https://path/to/file.txt"); assert(u3.has_authority()); - assert(u3.authority().string() == "path"); + assert(u3.authority().buffer() == "path"); assert(u3.is_path_absolute()); assert(u3.path() == "/to/file.txt"); //] @@ -1387,7 +1387,7 @@ modifying_path() //[snippet_modifying_path_9_10 url u1("https:path/to/file.txt" ); u1.set_encoded_path("//path/to/file.txt"); - assert(u1.string() == "https:/.//path/to/file.txt"); + assert(u1.buffer() == "https:/.//path/to/file.txt"); //] } { @@ -1396,7 +1396,7 @@ modifying_path() url u = parse_uri_reference("to/file.txt").value(); segments_ref segs = u.segments(); segs.insert(segs.begin(), "path"); - assert(u.string() == "path/to/file.txt"); + assert(u.buffer() == "path/to/file.txt"); //] BOOST_TEST_NOT(u.has_scheme()); BOOST_TEST_NOT(u.has_authority()); diff --git a/test/unit/static_url.cpp b/test/unit/static_url.cpp index ca592fc8..62c2ea67 100644 --- a/test/unit/static_url.cpp +++ b/test/unit/static_url.cpp @@ -31,7 +31,7 @@ public: { StaticUrl u; BOOST_TEST_EQ(*u.c_str(), '\0'); - BOOST_TEST(u.string().empty()); + BOOST_TEST(u.buffer().empty()); } url c1 = parse_uri("http://1").value(); @@ -43,18 +43,18 @@ public: { { StaticUrl u(c1); - BOOST_TEST_EQ(u.string(), c1.string()); - BOOST_TEST_NE(u.c_str(), c1.string().data()); + BOOST_TEST_EQ(u.buffer(), c1.buffer()); + BOOST_TEST_NE(u.c_str(), c1.buffer().data()); } { StaticUrl u(c2); - BOOST_TEST_EQ(u.string(), c2.string()); - BOOST_TEST_NE(u.c_str(), c2.string().data()); + BOOST_TEST_EQ(u.buffer(), c2.buffer()); + BOOST_TEST_NE(u.c_str(), c2.buffer().data()); } { StaticUrl u(c3); - BOOST_TEST_EQ(u.string(), c3.string()); - BOOST_TEST_NE(u.c_str(), c3.string().data()); + BOOST_TEST_EQ(u.buffer(), c3.buffer()); + BOOST_TEST_NE(u.c_str(), c3.buffer().data()); } { // different sizes @@ -67,18 +67,18 @@ public: { { StaticUrl u(std::move(c1)); - BOOST_TEST_EQ(u.string(), c1.string()); - BOOST_TEST_NE(u.c_str(), c1.string().data()); + BOOST_TEST_EQ(u.buffer(), c1.buffer()); + BOOST_TEST_NE(u.c_str(), c1.buffer().data()); } { StaticUrl u(std::move(c2)); - BOOST_TEST_EQ(u.string(), c2.string()); - BOOST_TEST_NE(u.c_str(), c2.string().data()); + BOOST_TEST_EQ(u.buffer(), c2.buffer()); + BOOST_TEST_NE(u.c_str(), c2.buffer().data()); } { StaticUrl u(std::move(c3)); - BOOST_TEST_EQ(u.string(), c3.string()); - BOOST_TEST_NE(u.c_str(), c3.string().data()); + BOOST_TEST_EQ(u.buffer(), c3.buffer()); + BOOST_TEST_NE(u.c_str(), c3.buffer().data()); } } @@ -87,20 +87,20 @@ public: { StaticUrl u(c4); u = c1; - BOOST_TEST_EQ(u.string(), c1.string()); - BOOST_TEST_NE(u.c_str(), c1.string().data()); + BOOST_TEST_EQ(u.buffer(), c1.buffer()); + BOOST_TEST_NE(u.c_str(), c1.buffer().data()); } { StaticUrl u(c4); u = c2; - BOOST_TEST_EQ(u.string(), c2.string()); - BOOST_TEST_NE(u.c_str(), c2.string().data()); + BOOST_TEST_EQ(u.buffer(), c2.buffer()); + BOOST_TEST_NE(u.c_str(), c2.buffer().data()); } { StaticUrl u(c4); u = c3; - BOOST_TEST_EQ(u.string(), c3.string()); - BOOST_TEST_NE(u.c_str(), c3.string().data()); + BOOST_TEST_EQ(u.buffer(), c3.buffer()); + BOOST_TEST_NE(u.c_str(), c3.buffer().data()); } { // different sizes @@ -115,20 +115,20 @@ public: { StaticUrl u(c4); u = std::move(c1); - BOOST_TEST_EQ(u.string(), c1.string()); - BOOST_TEST_NE(u.c_str(), c1.string().data()); + BOOST_TEST_EQ(u.buffer(), c1.buffer()); + BOOST_TEST_NE(u.c_str(), c1.buffer().data()); } { StaticUrl u(c4); u = std::move(c2); - BOOST_TEST_EQ(u.string(), c2.string()); - BOOST_TEST_NE(u.c_str(), c2.string().data()); + BOOST_TEST_EQ(u.buffer(), c2.buffer()); + BOOST_TEST_NE(u.c_str(), c2.buffer().data()); } { StaticUrl u(c4); u = std::move(c3); - BOOST_TEST_EQ(u.string(), c3.string()); - BOOST_TEST_NE(u.c_str(), c3.string().data()); + BOOST_TEST_EQ(u.buffer(), c3.buffer()); + BOOST_TEST_NE(u.c_str(), c3.buffer().data()); } } diff --git a/test/unit/url.cpp b/test/unit/url.cpp index 3f232524..5edfe427 100644 --- a/test/unit/url.cpp +++ b/test/unit/url.cpp @@ -96,7 +96,7 @@ struct url_test { url u(before); f(u); - auto s = u.string(); + auto s = u.buffer(); BOOST_TEST_EQ(s, after); } @@ -117,13 +117,13 @@ struct url_test { url u = parse_uri_reference("x://y/z?q#f").value(); url u2(u); - BOOST_TEST_EQ(u2.string(), u.string()); + BOOST_TEST_EQ(u2.buffer(), u.buffer()); } { url u = parse_uri_reference("x://y/z?q#f").value(); url u2 = parse_relative_ref("./").value(); u2 = u; - BOOST_TEST_EQ(u2.string(), u.string()); + BOOST_TEST_EQ(u2.buffer(), u.buffer()); } // move @@ -131,14 +131,14 @@ struct url_test url u = parse_uri_reference("x://y/z?q#f").value(); url u2(std::move(u)); BOOST_TEST(u.empty()); - BOOST_TEST_EQ(u2.string(), "x://y/z?q#f"); + BOOST_TEST_EQ(u2.buffer(), "x://y/z?q#f"); } { url u = parse_uri_reference("x://y/z?q#f").value(); url u2 = parse_relative_ref("./").value(); u2 = std::move(u); BOOST_TEST(u.empty()); - BOOST_TEST_EQ(u2.string(), "x://y/z?q#f"); + BOOST_TEST_EQ(u2.buffer(), "x://y/z?q#f"); } // url(string_view) @@ -201,7 +201,7 @@ struct url_test string_view s1, string_view s2) { url u = parse_uri_reference(s1).value(); - BOOST_TEST_EQ(u.remove_origin().string(), s2); + BOOST_TEST_EQ(u.remove_origin().buffer(), s2); BOOST_TEST(u.encoded_origin().empty()); BOOST_TEST(! u.has_authority()); }; @@ -231,37 +231,37 @@ struct url_test BOOST_TEST(! u.is_path_absolute()); BOOST_TEST(u.set_path_absolute(false)); BOOST_TEST(! u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), ""); + BOOST_TEST_EQ(u.buffer(), ""); BOOST_TEST(u.set_path_absolute(true)); BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "/"); + BOOST_TEST_EQ(u.buffer(), "/"); } { url u = parse_relative_ref("/").value(); BOOST_TEST(u.is_path_absolute()); BOOST_TEST(u.set_path_absolute(true)); BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "/"); + BOOST_TEST_EQ(u.buffer(), "/"); BOOST_TEST(u.set_path_absolute(false)); BOOST_TEST(! u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), ""); + BOOST_TEST_EQ(u.buffer(), ""); } { url u = parse_relative_ref("//").value(); BOOST_TEST(! u.is_path_absolute()); BOOST_TEST(u.set_path_absolute(true)); BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "///"); + BOOST_TEST_EQ(u.buffer(), "///"); BOOST_TEST(u.set_path_absolute(false)); BOOST_TEST(! u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "//"); + BOOST_TEST_EQ(u.buffer(), "//"); } { url u = parse_relative_ref("//x/y").value(); BOOST_TEST(u.is_path_absolute()); BOOST_TEST(! u.set_path_absolute(false)); BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "//x/y"); + BOOST_TEST_EQ(u.buffer(), "//x/y"); } { url u = parse_uri("x:y").value(); @@ -270,10 +270,10 @@ struct url_test BOOST_TEST(! u.is_path_absolute()); BOOST_TEST(u.set_path_absolute(true)); BOOST_TEST(u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "x:/y"); + BOOST_TEST_EQ(u.buffer(), "x:/y"); BOOST_TEST(u.set_path_absolute(false)); BOOST_TEST(! u.is_path_absolute()); - BOOST_TEST_EQ(u.string(), "x:y"); + BOOST_TEST_EQ(u.buffer(), "x:y"); } // set_encoded_path @@ -282,23 +282,23 @@ struct url_test url u = parse_uri("x://y/path/to/file.txt?q#f").value(); u.set_encoded_path(""); BOOST_TEST_EQ(u.encoded_path(), "/"); - BOOST_TEST_EQ(u.string(), "x://y/?q#f"); + BOOST_TEST_EQ(u.buffer(), "x://y/?q#f"); } { // path-abempty url u = parse_uri("x://y/path/to/file.txt?q#f").value(); u.set_encoded_path("/x"); BOOST_TEST_EQ(u.encoded_path(), "/x"); - BOOST_TEST_EQ(u.string(), "x://y/x?q#f"); + BOOST_TEST_EQ(u.buffer(), "x://y/x?q#f"); u.set_encoded_path("x/"); - BOOST_TEST_EQ(u.string(), "x://y/x/?q#f"); + BOOST_TEST_EQ(u.buffer(), "x://y/x/?q#f"); } { // path-absolute url u = parse_relative_ref("/path/to/file.txt").value(); u.set_encoded_path("/home/file.txt"); BOOST_TEST_EQ(u.encoded_path(), "/home/file.txt"); - BOOST_TEST_EQ(u.string(), "/home/file.txt"); + BOOST_TEST_EQ(u.buffer(), "/home/file.txt"); u.set_encoded_path("//home/file.txt"); equal(u, { "", "home", "file.txt" }); BOOST_TEST_EQ(u.encoded_path(), "/.//home/file.txt"); @@ -310,21 +310,21 @@ struct url_test url u = parse_uri("x:mailto").value(); u.set_encoded_path("file.txt"); BOOST_TEST_EQ(u.encoded_path(), "file.txt"); - BOOST_TEST_EQ(u.string(), "x:file.txt"); + BOOST_TEST_EQ(u.buffer(), "x:file.txt"); u.set_encoded_path(":file.txt"); BOOST_TEST_EQ(u.encoded_path(), ":file.txt"); - BOOST_TEST_EQ(u.string(), "x::file.txt"); + BOOST_TEST_EQ(u.buffer(), "x::file.txt"); // to path-absolute u.set_encoded_path("/file.txt"); BOOST_TEST_EQ(u.encoded_path(), "/file.txt"); - BOOST_TEST_EQ(u.string(), "x:/file.txt"); + BOOST_TEST_EQ(u.buffer(), "x:/file.txt"); } { // path-noscheme url u = parse_relative_ref("mailto").value(); u.set_encoded_path("file.txt"); BOOST_TEST_EQ(u.encoded_path(), "file.txt"); - BOOST_TEST_EQ(u.string(), "file.txt"); + BOOST_TEST_EQ(u.buffer(), "file.txt"); u.set_encoded_path(":file.txt"); BOOST_TEST_EQ(u.encoded_path(), "./:file.txt"); u.set_encoded_path("http:index.htm"); @@ -341,7 +341,7 @@ struct url_test url u = parse_uri_reference(s0).value(); u.set_encoded_path(arg); BOOST_TEST( - u.string() == match); + u.buffer() == match); }; check( "", @@ -382,7 +382,7 @@ struct url_test { url u = parse_uri_reference(s0).value(); u.set_path(arg); - BOOST_TEST_EQ(u.string(), match); + BOOST_TEST_EQ(u.buffer(), match); }; check( "", @@ -501,21 +501,21 @@ struct url_test url u; u.set_encoded_fragment(""); BOOST_TEST(u.has_fragment()); - BOOST_TEST_EQ(u.string(), "#"); + BOOST_TEST_EQ(u.buffer(), "#"); BOOST_TEST_EQ(u.encoded_fragment(), ""); } { url u; u.set_encoded_fragment("x"); BOOST_TEST(u.has_fragment()); - BOOST_TEST_EQ(u.string(), "#x"); + BOOST_TEST_EQ(u.buffer(), "#x"); BOOST_TEST_EQ(u.encoded_fragment(), "x"); } { url u; u.set_encoded_fragment("%41"); BOOST_TEST(u.has_fragment()); - BOOST_TEST_EQ(u.string(), "#%41"); + BOOST_TEST_EQ(u.buffer(), "#%41"); BOOST_TEST_EQ(u.encoded_fragment(), "%41"); BOOST_TEST_EQ(u.fragment(), "A"); } @@ -538,7 +538,7 @@ struct url_test url u; u.set_fragment(f); BOOST_TEST(u.has_fragment()); - BOOST_TEST_EQ(u.string(), h); + BOOST_TEST_EQ(u.buffer(), h); BOOST_TEST_EQ(u.encoded_fragment(), ef); BOOST_TEST_EQ(u.fragment(), f); }; @@ -593,7 +593,7 @@ struct url_test f(u); equal(u.segments(), init); equal(u.encoded_segments(), init); - BOOST_TEST_EQ(u.string(), s1); + BOOST_TEST_EQ(u.buffer(), s1); } void @@ -647,7 +647,7 @@ struct url_test u.segments() = init; equal(u.segments(), init); //equal(u.encoded_segments(), init); - BOOST_TEST_EQ(u.string(), s1); + BOOST_TEST_EQ(u.buffer(), s1); } }; @@ -757,14 +757,14 @@ struct url_test result rv = resolve(ub, ur, u); if(! BOOST_TEST( rv.has_value() )) return; - BOOST_TEST_EQ(u.string(), m); + BOOST_TEST_EQ(u.buffer(), m); // in place resolution url base( ub ); rv = base.resolve( ur ); if(! BOOST_TEST( rv.has_value() )) return; - BOOST_TEST_EQ(base.string(), m); + BOOST_TEST_EQ(base.buffer(), m); }; check("g:h" , "g:h"); @@ -873,7 +873,7 @@ struct url_test BOOST_TEST_EQ(u1.compare(u2), 0); BOOST_TEST_EQ(u1, u2); u1.normalize(); - BOOST_TEST_EQ(u1.string(), after); + BOOST_TEST_EQ(u1.buffer(), after); std::hash h; BOOST_TEST_EQ(h(u1), h(u2)); h = std::hash(10); @@ -1025,11 +1025,11 @@ struct url_test url u1( "http://a.com"); url u2( "http://b.com"); swap(u1, u2); - BOOST_TEST_EQ(u1.string(), "http://b.com"); - BOOST_TEST_EQ(u2.string(), "http://a.com"); + BOOST_TEST_EQ(u1.buffer(), "http://b.com"); + BOOST_TEST_EQ(u2.buffer(), "http://a.com"); swap(u1, u1); - BOOST_TEST_EQ(u1.string(), "http://b.com"); + BOOST_TEST_EQ(u1.buffer(), "http://b.com"); } //-------------------------------------------- diff --git a/test/unit/url_base.cpp b/test/unit/url_base.cpp index 0669fc0e..b33b9914 100644 --- a/test/unit/url_base.cpp +++ b/test/unit/url_base.cpp @@ -37,7 +37,7 @@ struct url_base_test { url u(before); f(u); - auto s = u.string(); + auto s = u.buffer(); BOOST_TEST_EQ(s, after); } @@ -55,7 +55,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.remove_scheme().string() == s2); + BOOST_TEST(u.remove_scheme().buffer() == s2); BOOST_TEST(u.scheme_id() == scheme::none); BOOST_TEST(u.scheme().empty()); }; @@ -66,7 +66,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s2)); - BOOST_TEST(u.set_scheme(s1).string() == s3); + BOOST_TEST(u.set_scheme(s1).buffer() == s3); BOOST_TEST_EQ(u.scheme(), s1); BOOST_TEST_EQ(u.scheme_id(), id); }; @@ -76,7 +76,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_scheme(id).string() == s2); + BOOST_TEST(u.set_scheme(id).buffer() == s2); BOOST_TEST_EQ(u.scheme_id(), id); }; @@ -156,7 +156,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST_EQ(u.remove_authority().string(), s2); + BOOST_TEST_EQ(u.remove_authority().buffer(), s2); BOOST_TEST(u.encoded_authority().empty()); BOOST_TEST(! u.has_authority()); BOOST_TEST(! u.has_userinfo()); @@ -170,7 +170,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_encoded_authority(s2).string() == s3); + BOOST_TEST(u.set_encoded_authority(s2).buffer() == s3); BOOST_TEST_EQ(u.encoded_authority(), s2); BOOST_TEST(u.has_authority()); }; @@ -299,7 +299,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST_EQ(u.remove_userinfo().string(), s2); + BOOST_TEST_EQ(u.remove_userinfo().buffer(), s2); BOOST_TEST(u.encoded_userinfo().empty()); BOOST_TEST(u.userinfo().empty()); BOOST_TEST(! u.has_userinfo()); @@ -310,7 +310,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST_EQ(u.set_userinfo(s2).string(), s3); + BOOST_TEST_EQ(u.set_userinfo(s2).buffer(), s3); }; auto const enc = [](string_view s1, @@ -318,7 +318,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_encoded_userinfo(s2).string() == s3); + BOOST_TEST(u.set_encoded_userinfo(s2).buffer() == s3); BOOST_TEST_EQ(u.encoded_userinfo(), s2); BOOST_TEST(u.has_userinfo()); }; @@ -618,7 +618,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.remove_password().string() == s2); + BOOST_TEST(u.remove_password().buffer() == s2); BOOST_TEST_EQ(u.encoded_password(), ""); BOOST_TEST_EQ(u.password(), ""); }; @@ -629,7 +629,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_password(s2).string() == s3); + BOOST_TEST(u.set_password(s2).buffer() == s3); }; auto const enc = []( @@ -639,7 +639,7 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u = url(s1)); BOOST_TEST(u.set_encoded_password( - s2).string() == s3); + s2).buffer() == s3); BOOST_TEST_EQ(u.encoded_password(), s2); BOOST_TEST(u.has_userinfo()); }; @@ -785,8 +785,8 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host(s)); BOOST_TEST_EQ(u.host_type(), ht); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); switch(ht) { case host_type::none: @@ -799,7 +799,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipv6: BOOST_TEST_EQ(u.encoded_host(), s); @@ -808,7 +808,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(u.host_address())); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipvfuture: BOOST_TEST_EQ(u.encoded_host(), s); @@ -817,7 +817,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), u.host_address()); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::name: BOOST_TEST_EQ(u.host_address(), s); @@ -825,7 +825,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), s); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; } }; @@ -838,8 +838,8 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_encoded_host(s)); BOOST_TEST_EQ(u.host_type(), ht); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); switch(ht) { case host_type::none: @@ -852,7 +852,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipv6: BOOST_TEST_EQ(u.encoded_host(), s); @@ -861,7 +861,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(u.host_address())); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipvfuture: BOOST_TEST_EQ(u.encoded_host(), s); @@ -870,15 +870,15 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), u.host_address()); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::name: - BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode_to_string()); + BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode()); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); - BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode_to_string()); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; } }; @@ -891,8 +891,8 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host_address(s)); BOOST_TEST_EQ(u.host_type(), ht); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); switch(ht) { case host_type::none: @@ -905,7 +905,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipv6: BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); @@ -914,7 +914,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s)); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipvfuture: BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); @@ -923,7 +923,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), s); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::name: BOOST_TEST_EQ(u.host_address(), s); @@ -931,7 +931,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), s); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; } }; @@ -944,8 +944,8 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_encoded_host_address(s)); BOOST_TEST_EQ(u.host_type(), ht); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); switch(ht) { case host_type::none: @@ -958,7 +958,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipv6: BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); @@ -967,7 +967,7 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s)); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::ipvfuture: BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); @@ -976,15 +976,15 @@ struct url_base_test BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), s); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; case host_type::name: - BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode_to_string()); + BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode()); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); - BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode_to_string()); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); break; } }; @@ -996,15 +996,15 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host_address(ipv4_address(s))); BOOST_TEST_EQ(u.host_type(), host_type::ipv4); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), s); BOOST_TEST_EQ(u.host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s)); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); }; auto const set_host_ipv6 = []( @@ -1014,15 +1014,15 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host_address(ipv6_address(s))); BOOST_TEST_EQ(u.host_type(), host_type::ipv6); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); BOOST_TEST_EQ(u.host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s)); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); }; auto const set_host_ipvfuture = []( @@ -1032,15 +1032,15 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host_ipvfuture(s)) BOOST_TEST_EQ(u.host_type(), host_type::ipvfuture); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), bracketed(s)); BOOST_TEST_EQ(u.host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), s); BOOST_TEST_EQ(u.host_name(), ""); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); }; auto const set_host_name = []( @@ -1050,15 +1050,15 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_host_name(s)) BOOST_TEST_EQ(u.host_type(), host_type::name); - BOOST_TEST_EQ(u.string(), s1); + BOOST_TEST_EQ(u.buffer(), s1); BOOST_TEST_EQ(u.host(), s); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); BOOST_TEST_EQ(u.host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), s); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); }; auto const set_encoded_host_name = []( @@ -1068,19 +1068,19 @@ struct url_base_test url u; BOOST_TEST_NO_THROW(u.set_encoded_host_name(s)) BOOST_TEST_EQ(u.host_type(), host_type::name); - BOOST_TEST_EQ(u.string(), s1); - BOOST_TEST_EQ(u.host(), u.encoded_host().decode_to_string()); + BOOST_TEST_EQ(u.buffer(), s1); + BOOST_TEST_EQ(u.host(), u.encoded_host().decode()); auto rv = parse_ipv4_address(s); if(! rv) BOOST_TEST_EQ(u.encoded_host(), s); else BOOST_TEST_EQ(u.host(), rv->to_string()); - BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode_to_string()); + BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode()); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); - BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode_to_string()); - BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode_to_string()); + BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode()); + BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode()); }; set_host("", "//", host_type::name); @@ -1166,7 +1166,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.remove_port().string() == s2); + BOOST_TEST(u.remove_port().buffer() == s2); BOOST_TEST(! u.has_port()); BOOST_TEST(u.port().empty()); BOOST_TEST_EQ(u.port_number(), 0); @@ -1177,7 +1177,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_port(n).string() == s2); + BOOST_TEST(u.set_port(n).buffer() == s2); BOOST_TEST(u.has_port()); BOOST_TEST_EQ(u.port_number(), n); }; @@ -1188,7 +1188,7 @@ struct url_base_test { url u; BOOST_TEST_NO_THROW(u = url(s1)); - BOOST_TEST(u.set_port(s2).string() == s3); + BOOST_TEST(u.set_port(s2).buffer() == s3); BOOST_TEST(u.has_port()); BOOST_TEST_EQ(u.port_number(), n); BOOST_TEST_EQ(u.port(), s2); @@ -1352,21 +1352,21 @@ struct url_base_test url u; u.set_encoded_query(""); BOOST_TEST(u.has_query()); - BOOST_TEST_EQ(u.string(), "?"); + BOOST_TEST_EQ(u.buffer(), "?"); BOOST_TEST_EQ(u.encoded_query(), ""); } { url u; u.set_encoded_query("x"); BOOST_TEST(u.has_query()); - BOOST_TEST_EQ(u.string(), "?x"); + BOOST_TEST_EQ(u.buffer(), "?x"); BOOST_TEST_EQ(u.encoded_query(), "x"); } { url u; u.set_encoded_query("%41"); BOOST_TEST(u.has_query()); - BOOST_TEST_EQ(u.string(), "?%41"); + BOOST_TEST_EQ(u.buffer(), "?%41"); BOOST_TEST_EQ(u.encoded_query(), "%41"); BOOST_TEST_EQ(u.query(), "A"); } @@ -1389,7 +1389,7 @@ struct url_base_test url u; u.set_query(q); BOOST_TEST(u.has_query()); - BOOST_TEST_EQ(u.string(), us); + BOOST_TEST_EQ(u.buffer(), us); BOOST_TEST_EQ(u.query(), q); }; good("", "?"); @@ -1403,7 +1403,7 @@ struct url_base_test url u; u.set_query(""); u.set_query(""); - BOOST_TEST_EQ(u.string(), "?"); + BOOST_TEST_EQ(u.buffer(), "?"); } } @@ -1496,13 +1496,13 @@ struct url_base_test // remove_scheme { - assert( url("http://www.example.com/index.htm" ).remove_scheme().string() == "//www.example.com/index.htm" ); + assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" ); } // set_scheme { assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https ); - assert( url( "http://example.com/echo.cgi" ).set_scheme( scheme::wss ).string() == "wss://example.com/echo.cgi" ); + assert( url( "http://example.com/echo.cgi" ).set_scheme( scheme::wss ).buffer() == "wss://example.com/echo.cgi" ); } //---------------------------------------- @@ -1513,7 +1513,7 @@ struct url_base_test // remove_authority { - assert( url( "http://example.com/echo.cgi" ).remove_authority().string() == "http:/echo.cgi" ); + assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" ); } // set_encoded_authority @@ -1577,27 +1577,27 @@ struct url_base_test // set_host { - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); } // set_encoded_host { - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); } // set_host_address { - assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); } // set_encoded_host_address { - assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).string() == "http://127.0.0.1" ); + assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); } // set_host_address { - assert( url("http://www.example.com").set_host_address( ipv4_address( "127.0.0.1" ) ).string() == "http://127.0.0.1" ); + assert( url("http://www.example.com").set_host_address( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" ); } // set_host_address @@ -1607,7 +1607,7 @@ struct url_base_test // set_host_ipvfuture { - assert( url().set_host_ipvfuture( "v42.bis" ).string() == "//[v42.bis]" ); + assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" ); } // set_host_name @@ -1645,7 +1645,7 @@ struct url_base_test // remove_origin { - assert( url( "http://www.example.com/index.htm" ).remove_origin().string() == "/index.htm" ); + assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" ); } //---------------------------------------- @@ -1658,7 +1658,7 @@ struct url_base_test { url u( "path/to/file.txt" ); assert( u.set_path_absolute( true ) ); - assert( u.string() == "/path/to/file.txt" ); + assert( u.buffer() == "/path/to/file.txt" ); } // set_path @@ -1705,7 +1705,7 @@ struct url_base_test // remove_query { - assert( url( "http://www.example.com?id=42" ).remove_query().string() == "http://www.example.com" ); + assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" ); } // set_query @@ -1740,7 +1740,7 @@ struct url_base_test // remove_fragment { - assert( url( "?first=john&last=doe#anchor" ).remove_fragment().string() == "?first=john&last=doe" ); + assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" ); } // set_fragment diff --git a/test/unit/url_view.cpp b/test/unit/url_view.cpp index b70cefa6..9da441b8 100644 --- a/test/unit/url_view.cpp +++ b/test/unit/url_view.cpp @@ -89,8 +89,8 @@ public: { string_view s = "/index.htm"; url_view u = parse_relative_ref(s).value(); - BOOST_TEST_EQ(u.string(), s); - BOOST_TEST_EQ(u.string().data(), s.data()); + BOOST_TEST_EQ(u.buffer(), s); + BOOST_TEST_EQ(u.buffer().data(), s.data()); } // persist() @@ -105,7 +105,7 @@ public: sp = u.persist(); assert( sp->data() != s.data() ); // different buffer - assert( sp->string() == s); // same contents + assert( sp->buffer() == s); // same contents // s is destroyed and thus u // becomes invalid, but sp remains valid. @@ -187,7 +187,7 @@ public: BOOST_TEST_EQ( u.encoded_authority(), m); BOOST_TEST_EQ( - u.authority().string(), m); + u.authority().buffer(), m); } //()); }; diff --git a/test/unit/url_view_base.cpp b/test/unit/url_view_base.cpp index 9944b71e..09566790 100644 --- a/test/unit/url_view_base.cpp +++ b/test/unit/url_view_base.cpp @@ -48,17 +48,17 @@ struct url_view_base_test BOOST_TEST_NO_THROW(u = url_view(su)); BOOST_TEST_EQ(u.host_type(), host_type::ipv4); BOOST_TEST_EQ(u.host(), - u.encoded_host().decode_to_string()); + u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), s); BOOST_TEST_EQ(u.host_address(), - u.encoded_host_address().decode_to_string()); + u.encoded_host_address().decode()); BOOST_TEST_EQ(u.encoded_host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s)); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); BOOST_TEST_EQ(u.encoded_host_name(), ""); - BOOST_TEST_EQ(u.authority().string(), sa); + BOOST_TEST_EQ(u.authority().buffer(), sa); }; auto const ipv6 = []( @@ -70,17 +70,17 @@ struct url_view_base_test BOOST_TEST_NO_THROW(u = url_view(su)); BOOST_TEST_EQ(u.host_type(), host_type::ipv6); BOOST_TEST_EQ(u.host(), - u.encoded_host().decode_to_string()); + u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), sa); BOOST_TEST_EQ(u.host_address(), - u.encoded_host_address().decode_to_string()); + u.encoded_host_address().decode()); BOOST_TEST_EQ(u.encoded_host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s)); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), ""); BOOST_TEST_EQ(u.encoded_host_name(), ""); - BOOST_TEST_EQ(u.authority().string(), sa); + BOOST_TEST_EQ(u.authority().buffer(), sa); }; auto const ipvfut = []( @@ -92,17 +92,17 @@ struct url_view_base_test BOOST_TEST_NO_THROW(u = url_view(su)); BOOST_TEST_EQ(u.host_type(), host_type::ipvfuture); BOOST_TEST_EQ(u.host(), - u.encoded_host().decode_to_string()); + u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), sa); BOOST_TEST_EQ(u.host_address(), - u.encoded_host_address().decode_to_string()); + u.encoded_host_address().decode()); BOOST_TEST_EQ(u.encoded_host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), s); BOOST_TEST_EQ(u.host_name(), ""); BOOST_TEST_EQ(u.encoded_host_name(), ""); - BOOST_TEST_EQ(u.authority().string(), sa); + BOOST_TEST_EQ(u.authority().buffer(), sa); }; auto const name = []( @@ -114,18 +114,18 @@ struct url_view_base_test BOOST_TEST_NO_THROW(u = url_view(su)); BOOST_TEST_EQ(u.host_type(), host_type::name); BOOST_TEST_EQ(u.host(), - u.encoded_host().decode_to_string()); + u.encoded_host().decode()); BOOST_TEST_EQ(u.encoded_host(), s); BOOST_TEST_EQ(u.host_address(), - u.encoded_host_address().decode_to_string()); + u.encoded_host_address().decode()); BOOST_TEST_EQ(u.encoded_host_address(), s); BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address()); BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address()); BOOST_TEST_EQ(u.host_ipvfuture(), ""); BOOST_TEST_EQ(u.host_name(), - u.encoded_host_name().decode_to_string()); + u.encoded_host_name().decode()); BOOST_TEST_EQ(u.encoded_host_name(), s); - BOOST_TEST_EQ(u.authority().string(), sa); + BOOST_TEST_EQ(u.authority().buffer(), sa); }; ipv4("0.0.0.0"); @@ -174,7 +174,7 @@ struct url_view_base_test sp = u.persist(); assert( sp->data() != s.data() ); // different buffer - assert( sp->string() == s); // same contents + assert( sp->buffer() == s); // same contents // s is destroyed and thus u // becomes invalid, but sp remains valid.