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