GCC Code Coverage Report


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