GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/tuple_rule.hpp
Date: 2024-08-19 20:08:56
Exec Total Coverage
Lines: 16 16 100.0%
Functions: 40 40 100.0%
Branches: 3 4 75.0%

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