text: //
  // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/CPPAlliance/url
  //
  
  #ifndef BOOST_URL_RFC_QUERY_RULE_HPP
  #define BOOST_URL_RFC_QUERY_RULE_HPP
  
  #include <boost/url/detail/config.hpp>
  #include <boost/url/error_code.hpp>
  #include <boost/url/query_param.hpp>
  #include <boost/url/string_view.hpp>
  #include <boost/url/grammar/parse.hpp>
  #include <boost/url/grammar/range.hpp>
  #include <cstddef>
  
  namespace boost {
  namespace urls {
  
  /** Rule for query
  
      @par BNF
      @code
      query           = *( pchar / "/" / "?" )
  
      query-params    = query-param *( "&" query-param )
      query-param     = key [ "=" value ]
      key             = *qpchar
      value           = *( qpchar / "=" )
      qpchar          = unreserved
                      / pct-encoded
                      / "!" / "$" / "'" / "(" / ")"
                      / "*" / "+" / "," / ";"
                      / ":" / "@" / "/" / "?"
      @endcode
  
      @par Specification
      @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
          >3.4. Query (rfc3986)</a>
  
      @see
          @ref query_part_rule.
  */
  struct query_rule
  {
      using value_type = query_param;
      using reference = query_param_view;
  
      grammar::range<query_rule> v;
  
      friend
      void
      tag_invoke(
          grammar::parse_tag const&,
          char const*& it,
          char const* const end,
          error_code& ec,
          query_rule& t) noexcept
      {
          grammar::parse(
              it, end, ec, t.v);
      }
  
      BOOST_URL_DECL
      static
      bool
      begin(
          char const*& it,
          char const* const end,
          error_code& ec,
          reference& t) noexcept;
  
      BOOST_URL_DECL
      static
      bool
      increment(
          char const*& it,
          char const* const end,
          error_code& ec,
          reference& t) noexcept;
  
  private:
      struct key_chars;
      struct value_chars;
  };
  
  //------------------------------------------------
  
  /** Rule for query-part
  
      @par BNF
      @code
      query-part      = [ "?" query ]
  
      query           = *( pchar / "/" / "?" )
      @endcode
  
      @par Specification
      @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
          >3.4. Query (rfc3986)</a>
  
      @see
          @ref query_rule.
  */
  struct query_part_rule
  {
      bool has_query = false;
      query_rule query;
      string_view query_part;
  
      friend
      void
      tag_invoke(
          grammar::parse_tag const&,
          char const*& it,
          char const* const end,
          error_code& ec,
          query_part_rule& t) noexcept
      {
          parse(it, end, ec, t);
      }
  
  private:
      BOOST_URL_DECL
      static
      void
      parse(
          char const*& it,
          char const* const end,
          error_code& ec,
          query_part_rule& t) noexcept;
  
  };
  
  } // urls
  } // boost
  
  #endif
  