LCOV - code coverage report
Current view: top level - url/grammar - tuple_rule.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 15 15
Test Date: 2026-02-13 15:53:22 Functions: 100.0 % 40 40

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
       3              : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/url
       9              : //
      10              : 
      11              : #ifndef BOOST_URL_GRAMMAR_TUPLE_RULE_HPP
      12              : #define BOOST_URL_GRAMMAR_TUPLE_RULE_HPP
      13              : 
      14              : #include <boost/url/detail/config.hpp>
      15              : #include <boost/url/error_types.hpp>
      16              : #include <boost/url/grammar/error.hpp>
      17              : #include <boost/url/grammar/detail/tuple.hpp>
      18              : #include <boost/url/grammar/type_traits.hpp>
      19              : #include <boost/mp11/algorithm.hpp>
      20              : #include <boost/core/detail/static_assert.hpp>
      21              : #include <boost/core/empty_value.hpp>
      22              : #include <tuple>
      23              : 
      24              : namespace boost {
      25              : namespace urls {
      26              : namespace grammar {
      27              : 
      28              : namespace implementation_defined {
      29              : template<
      30              :     class R0,
      31              :     class... Rn>
      32              : class tuple_rule_t
      33              :     : empty_value<
      34              :         detail::tuple<R0, Rn...>>
      35              : {
      36              :     using T = mp11::mp_remove<
      37              :         std::tuple<
      38              :             typename R0::value_type,
      39              :             typename Rn::value_type...>,
      40              :         void>;
      41              :     static constexpr bool IsList =
      42              :         mp11::mp_size<T>::value != 1;
      43              : 
      44              : public:
      45              :     using value_type =
      46              :         mp11::mp_eval_if_c<IsList,
      47              :             T, mp11::mp_first, T>;
      48              : 
      49              :     constexpr
      50         8321 :     tuple_rule_t(
      51              :         R0 const& r0,
      52              :         Rn const&... rn) noexcept
      53              :         : empty_value<
      54              :             detail::tuple<R0, Rn...>>(
      55              :                 empty_init,
      56         8321 :                 r0, rn...)
      57              :     {
      58         8321 :     }
      59              : 
      60              :     BOOST_URL_CXX14_CONSTEXPR
      61              :     system::result<value_type>
      62              :     parse(
      63              :         char const*& it,
      64              :         char const* end) const;
      65              : 
      66              : };
      67              : } // implementation_defined
      68              : 
      69              : /** Match a series of rules in order
      70              : 
      71              :     This matches a series of rules in the
      72              :     order specified. Upon success the input
      73              :     is adjusted to point to the first
      74              :     unconsumed character. There is no
      75              :     implicit specification of linear white
      76              :     space between each rule.
      77              : 
      78              :     @par Value Type
      79              :     @code
      80              :     using value_type = __see_below__;
      81              :     @endcode
      82              : 
      83              :     The sequence rule usually returns a
      84              :     `std::tuple` containing the the `value_type`
      85              :     of each corresponding rule in the sequence,
      86              :     except that `void` values are removed.
      87              :     However, if there is exactly one non-void
      88              :     value type `T`, then the sequence rule
      89              :     returns `system::result<T>` instead of
      90              :     `system::result<tuple<...>>`.
      91              : 
      92              :     @par Example
      93              :     Rules are used with the function @ref parse.
      94              :     @code
      95              :     system::result< std::tuple< unsigned char, unsigned char, unsigned char, unsigned char > > rv =
      96              :         parse( "192.168.0.1",
      97              :             tuple_rule(
      98              :                 dec_octet_rule,
      99              :                 squelch( delim_rule('.') ),
     100              :                 dec_octet_rule,
     101              :                 squelch( delim_rule('.') ),
     102              :                 dec_octet_rule,
     103              :                 squelch( delim_rule('.') ),
     104              :                 dec_octet_rule ) );
     105              :     @endcode
     106              : 
     107              :     @par BNF
     108              :     @code
     109              :     sequence     = rule1 rule2 rule3...
     110              :     @endcode
     111              : 
     112              :     @par Specification
     113              :     @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#section-3.1"
     114              :         >3.1.  Concatenation (rfc5234)</a>
     115              : 
     116              :     @param r0 The first rule to match
     117              :     @param rn A list of one or more rules to match
     118              :     @return The sequence rule
     119              : 
     120              :     @see
     121              :         @ref dec_octet_rule,
     122              :         @ref delim_rule,
     123              :         @ref parse,
     124              :         @ref squelch.
     125              : */
     126              : template<
     127              :     BOOST_URL_CONSTRAINT(Rule) R0,
     128              :     BOOST_URL_CONSTRAINT(Rule)... Rn>
     129              : constexpr
     130              : auto
     131         8321 : tuple_rule(
     132              :     R0 const& r0,
     133              :     Rn const&... rn) noexcept ->
     134              :         implementation_defined::tuple_rule_t<
     135              :             R0, Rn...>
     136              : {
     137              :     BOOST_CORE_STATIC_ASSERT(
     138              :         mp11::mp_all<
     139              :             is_rule<R0>,
     140              :             is_rule<Rn>...>::value);
     141         8321 :     return { r0, rn... };
     142              : }
     143              : 
     144              : namespace implementation_defined {
     145              : 
     146              : template<class Rule>
     147              : struct squelch_rule_t
     148              :     : empty_value<Rule>
     149              : {
     150              :     using value_type = void;
     151              : 
     152              :     constexpr
     153        12323 :     squelch_rule_t(
     154              :         Rule const& r) noexcept
     155              :         : empty_value<Rule>(
     156        12323 :             empty_init, r)
     157              :     {
     158        12323 :     }
     159              : 
     160              :     BOOST_URL_CXX14_CONSTEXPR
     161              :     system::result<value_type>
     162         8819 :     parse(
     163              :         char const*& it,
     164              :         char const* end) const
     165              :     {
     166         8819 :         auto rv = this->get().parse(it, end);
     167         8819 :         if(rv.error())
     168         3735 :             return rv.error();
     169         5084 :         return {}; // void
     170              :     }
     171              : };
     172              : 
     173              : } // implementation_defined
     174              : 
     175              : /** Squelch the value of a rule
     176              : 
     177              :     This function returns a new rule which
     178              :     matches the specified rule, and converts
     179              :     its value type to `void`. This is useful
     180              :     for matching delimiters in a grammar,
     181              :     where the value for the delimiter is not
     182              :     needed.
     183              : 
     184              :     @par Value Type
     185              :     @code
     186              :     using value_type = void;
     187              :     @endcode
     188              : 
     189              :     @par Example 1
     190              :     With `squelch`:
     191              :     @code
     192              :     system::result< std::tuple< decode_view, core::string_view > > rv = parse(
     193              :         "www.example.com:443",
     194              :         tuple_rule(
     195              :             pct_encoded_rule(unreserved_chars + '-' + '.'),
     196              :             squelch( delim_rule( ':' ) ),
     197              :             token_rule( digit_chars ) ) );
     198              :     @endcode
     199              : 
     200              :     @par Example 2
     201              :     Without `squelch`:
     202              :     @code
     203              :     system::result< std::tuple< decode_view, core::string_view, core::string_view > > rv = parse(
     204              :         "www.example.com:443",
     205              :         tuple_rule(
     206              :             pct_encoded_rule(unreserved_chars + '-' + '.'),
     207              :             delim_rule( ':' ),
     208              :             token_rule( digit_chars ) ) );
     209              :     @endcode
     210              : 
     211              :     @param r The rule to squelch
     212              :     @return The squelched rule
     213              : 
     214              :     @see
     215              :         @ref delim_rule,
     216              :         @ref digit_chars,
     217              :         @ref parse,
     218              :         @ref tuple_rule,
     219              :         @ref token_rule,
     220              :         @ref decode_view,
     221              :         @ref pct_encoded_rule,
     222              :         @ref unreserved_chars.
     223              : */
     224              : template<BOOST_URL_CONSTRAINT(Rule) R>
     225              : constexpr
     226              : BOOST_URL_IMPLEMENTATION_DEFINED(implementation_defined::squelch_rule_t<R>)
     227        12323 : squelch( R const& r ) noexcept
     228              : {
     229              :     BOOST_CORE_STATIC_ASSERT(is_rule<R>::value);
     230        12323 :     return { r };
     231              : }
     232              : 
     233              : } // grammar
     234              : } // urls
     235              : } // boost
     236              : 
     237              : #include <boost/url/grammar/impl/tuple_rule.hpp>
     238              : 
     239              : #endif
        

Generated by: LCOV version 2.3