Line data Source code
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 7836 : tuple_rule_t(
50 : R0 const& r0,
51 : Rn const&... rn) noexcept
52 : : empty_value<
53 : detail::tuple<R0, Rn...>>(
54 : empty_init,
55 7836 : r0, rn...)
56 : {
57 7836 : }
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 7836 : 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 7836 : 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 8107 : parse(
160 : char const*& it,
161 : char const* end) const
162 : {
163 8107 : auto rv = this->get().parse(it, end);
164 8107 : if(rv.error())
165 3352 : return rv.error();
166 4755 : return {}; // void
167 113 : }
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
|