// // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // 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_PARAMS_BASE_HPP #define BOOST_URL_PARAMS_BASE_HPP #include #include #include #include #include #include #include namespace boost { namespace urls { /** Common functionality for containers This base class is used by the library to provide common member functions for containers. This cannot be instantiated directly; Instead, use one of the containers or functions: @par Containers @li @ref params_ref @li @ref params_view @li @ref params_encoded_ref @li @ref params_encoded_view */ class BOOST_URL_DECL params_base { friend class url_view_base; friend class params_ref; friend class params_view; detail::query_ref ref_; encoding_opts opt_; params_base() noexcept; params_base( detail::query_ref const& ref, encoding_opts opt) noexcept; params_base( params_base const&) = default; params_base& operator=( params_base const&) = default; public: /** A Bidirectional iterator to a query parameter Objects of this type allow iteration through the parameters in the query. Any percent-escapes in returned strings are decoded first. The values returned are read-only; changes to parameters must be made through the container instead, if the container supports modification.
The strings produced when iterators are dereferenced belong to the iterator and 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__; #else class iterator; #endif /// @copydoc iterator using const_iterator = iterator; /** The value type Values of this type represent parameters whose strings retain unique ownership by making a copy. @par Example @code params_view::value_type qp( *url_view( "?first=John&last=Doe" ).params().find( "first" ) ); @endcode @see @ref param. */ using value_type = param; /** The reference type This is the type of value returned when iterators of the view are dereferenced. @see @ref param_view. */ using reference = param; /// @copydoc reference using const_reference = param; /** An unsigned integer type to represent sizes. */ using size_type = std::size_t; /** A signed integer type used to represent differences. */ using difference_type = std::ptrdiff_t; //-------------------------------------------- // // Observers // //-------------------------------------------- /** Return the maximum number of characters possible This represents the largest number of characters that are possible in a path, not including any null terminator. @par Exception Safety Throws nothing. */ static constexpr std::size_t max_size() noexcept { return BOOST_URL_MAX_SIZE; } /** Return the referenced character buffer. This function returns the character buffer referenced by the view. The returned string may contain percent escapes. @par Example @code assert( url_view( "?first=John&last=Doe" ).params().buffer() == "?first=John&last=Doe" ); @endcode @par Complexity Constant. @par Exception Safety Throws nothing. */ pct_string_view buffer() const noexcept; /** Return true if there are no params @par Example @code assert( ! url_view( "?key=value" ).params().empty() ); @endcode @par Complexity Constant. @par Exception Safety Throws nothing. */ bool empty() const noexcept; /** Return the number of params @par Example @code assert( url_view( "?key=value").params().size() == 1 ); @endcode @par Complexity Constant. @par Exception Safety Throws nothing. */ std::size_t size() const noexcept; /** Return an iterator to the beginning @par Complexity Linear in the size of the first param. @par Exception Safety Throws nothing. */ iterator begin() const noexcept; /** Return an iterator to the end @par Complexity Constant. @par Exception Safety Throws nothing. */ iterator end() const noexcept; //-------------------------------------------- /** Return true if a matching key exists This function examines the parameters in the container to find a match for the specified key. The comparison is performed as if all escaped characters were decoded first. @par Example @code assert( url_view( "?first=John&last=Doe" ).params().contains( "first" ) ); @endcode @par Complexity Linear in `this->buffer().size()`. @par Exception Safety Throws nothing. @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ bool contains( core::string_view key, ignore_case_param ic = {}) const noexcept; /** Return the number of matching keys This function examines the parameters in the container to find the number of matches for the specified key. The comparison is performed as if all escaped characters were decoded first. @par Example @code assert( url_view( "?first=John&last=Doe" ).params().count( "first" ) == 1 ); @endcode @par Complexity Linear in `this->buffer().size()`. @par Exception Safety Throws nothing. @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ std::size_t count( core::string_view key, ignore_case_param ic = {}) const noexcept; /** Find a matching key This function examines the parameters in the container to find a match for the specified key. The comparison is performed as if all escaped characters were decoded first.
The search starts from the first param and proceeds forward until either the key is found or the end of the range is reached, in which case `end()` is returned. @par Example @code assert( (*url_view( "?first=John&last=Doe" ).params().find( "First", ignore_case )).value == "John" ); @endcode @par Effects @code return this->find( this->begin(), key, ic ); @endcode @par Complexity Linear in `this->buffer().size()`. @return an iterator to the param @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ iterator find( core::string_view key, ignore_case_param ic = {}) const noexcept; /** Find a matching key This function examines the parameters in the container to find a match for the specified key. The comparison is performed as if all escaped characters were decoded first.
The search starts at `from` and proceeds forward until either the key is found or the end of the range is reached, in which case `end()` is returned. @par Example @code url_view u( "?First=John&Last=Doe" ); assert( u.params().find( "first" ) != u.params().find( "first", ignore_case ) ); @endcode @par Complexity Linear in `this->buffer().size()`. @return an iterator to the param @param from The position to begin the search from. This can be `end()`. @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ iterator find( iterator from, core::string_view key, ignore_case_param ic = {}) const noexcept; /** Find a matching key This function examines the parameters in the container to find a match for the specified key. The comparison is performed as if all escaped characters were decoded first.
The search starts from the last param and proceeds backwards until either the key is found or the beginning of the range is reached, in which case `end()` is returned. @par Example @code assert( (*url_view( "?first=John&last=Doe" ).params().find_last( "last" )).value == "Doe" ); @endcode @par Complexity Linear in `this->buffer().size()`. @return an iterator to the param @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ iterator find_last( core::string_view key, ignore_case_param ic = {}) const noexcept; /** Find a matching key This function examines the parameters in the container to find a match for the specified key. The comparison is performed as if all escaped characters were decoded first.
The search starts prior to `before` and proceeds backwards until either the key is found or the beginning of the range is reached, in which case `end()` is returned. @par Example @code url_view u( "?First=John&Last=Doe" ); assert( u.params().find_last( "last" ) != u.params().find_last( "last", ignore_case ) ); @endcode @par Complexity Linear in `this->buffer().size()`. @return an iterator to the param @param before One past the position to begin the search from. This can be `end()`. @param key The key to match. By default, a case-sensitive comparison is used. @param ic An optional parameter. If the value @ref ignore_case is passed here, the comparison is case-insensitive. */ iterator find_last( iterator before, core::string_view key, ignore_case_param ic = {}) const noexcept; private: detail::params_iter_impl find_impl( detail::params_iter_impl, core::string_view, ignore_case_param) const noexcept; detail::params_iter_impl find_last_impl( detail::params_iter_impl, core::string_view, ignore_case_param) const noexcept; }; //------------------------------------------------ /** Format to an output stream Any percent-escapes are emitted as-is; no decoding is performed. @par Complexity Linear in `ps.buffer().size()`. @par Effects @code return os << ps.buffer(); @endcode */ BOOST_URL_DECL std::ostream& operator<<( std::ostream& os, params_base const& qp); } // urls } // boost #include #endif