include/boost/url/grammar/tuple_rule.hpp

100.0% Lines (15/15) 100.0% Functions (37/38) 100.0% Branches (2/2)
include/boost/url/grammar/tuple_rule.hpp
Line Branch Hits 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
2/2
✓ Branch 2 taken 3510 times.
✓ Branch 3 taken 4542 times.
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
240