GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/tuple_rule.hpp
Date: 2024-03-15 19:37:09
Exec Total Coverage
Lines: 15 15 100.0%
Functions: 39 39 100.0%
Branches: 2 2 100.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 template<
87 class R0,
88 class... Rn>
89 class tuple_rule_t
90 : empty_value<
91 detail::tuple<R0, Rn...>>
92 {
93 using T = mp11::mp_remove<
94 std::tuple<
95 typename R0::value_type,
96 typename Rn::value_type...>,
97 void>;
98 static constexpr bool IsList =
99 mp11::mp_size<T>::value != 1;
100
101 public:
102 using value_type =
103 mp11::mp_eval_if_c<IsList,
104 T, mp11::mp_first, T>;
105
106 template<
107 class R0_,
108 class... Rn_>
109 friend
110 constexpr
111 auto
112 tuple_rule(
113 R0_ const& r0,
114 Rn_ const&... rn) noexcept ->
115 tuple_rule_t<R0_, Rn_...>;
116
117 system::result<value_type>
118 parse(
119 char const*& it,
120 char const* end) const;
121
122 private:
123 constexpr
124 8340 tuple_rule_t(
125 R0 const& r0,
126 Rn const&... rn) noexcept
127 : empty_value<
128 detail::tuple<R0, Rn...>>(
129 empty_init,
130 8340 r0, rn...)
131 {
132 8340 }
133 };
134
135 template<
136 class R0,
137 class... Rn>
138 constexpr
139 auto
140 8340 tuple_rule(
141 R0 const& r0,
142 Rn const&... rn) noexcept ->
143 tuple_rule_t<
144 R0, Rn...>
145 {
146 8340 return { r0, rn... };
147 }
148 #endif
149
150 #ifndef BOOST_URL_DOCS
151 namespace detail {
152
153 template<class Rule>
154 struct squelch_rule_t
155 : empty_value<Rule>
156 {
157 using value_type = void;
158
159 constexpr
160 11406 squelch_rule_t(
161 Rule const& r) noexcept
162 : empty_value<Rule>(
163 11406 empty_init, r)
164 {
165 11406 }
166
167 system::result<value_type>
168 8051 parse(
169 char const*& it,
170 char const* end) const
171 {
172 8164 auto rv = this->get().parse(it, end);
173
2/2
✓ Branch 2 taken 3100 times.
✓ Branch 3 taken 4184 times.
8051 if(rv.error())
174 3325 return rv.error();
175 4726 return {}; // void
176 }
177 };
178
179 } // detail
180 #endif
181
182 /** Squelch the value of a rule
183
184 This function returns a new rule which
185 matches the specified rule, and converts
186 its value type to `void`. This is useful
187 for matching delimiters in a grammar,
188 where the value for the delimiter is not
189 needed.
190
191 @par Value Type
192 @code
193 using value_type = void;
194 @endcode
195
196 @par Example 1
197 With `squelch`:
198 @code
199 system::result< std::tuple< decode_view, core::string_view > > rv = parse(
200 "www.example.com:443",
201 tuple_rule(
202 pct_encoded_rule(unreserved_chars + '-' + '.'),
203 squelch( delim_rule( ':' ) ),
204 token_rule( digit_chars ) ) );
205 @endcode
206
207 @par Example 2
208 Without `squelch`:
209 @code
210 system::result< std::tuple< decode_view, core::string_view, core::string_view > > rv = parse(
211 "www.example.com:443",
212 tuple_rule(
213 pct_encoded_rule(unreserved_chars + '-' + '.'),
214 delim_rule( ':' ),
215 token_rule( digit_chars ) ) );
216 @endcode
217
218 @param r The rule to squelch
219
220 @see
221 @ref delim_rule,
222 @ref digit_chars,
223 @ref parse,
224 @ref tuple_rule,
225 @ref token_rule,
226 @ref decode_view,
227 @ref pct_encoded_rule,
228 @ref unreserved_chars.
229 */
230 template<class Rule>
231 constexpr
232 #ifdef BOOST_URL_DOCS
233 __implementation_defined__
234 #else
235 detail::squelch_rule_t<Rule>
236 #endif
237 11406 squelch( Rule const& r ) noexcept
238 {
239 11406 return { r };
240 }
241
242 } // grammar
243 } // urls
244 } // boost
245
246 #include <boost/url/grammar/impl/tuple_rule.hpp>
247
248 #endif
249