include/boost/url/grammar/impl/tuple_rule.hpp

100.0% Lines (60/60) 97.7% Functions (253/259)
include/boost/url/grammar/impl/tuple_rule.hpp
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2022 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_IMPL_TUPLE_RULE_HPP
12 #define BOOST_URL_GRAMMAR_IMPL_TUPLE_RULE_HPP
13
14 #include <boost/url/grammar/parse.hpp>
15 #include <boost/mp11/integral.hpp>
16 #include <boost/mp11/list.hpp>
17 #include <boost/mp11/tuple.hpp>
18 #include <type_traits>
19
20 namespace boost {
21 namespace urls {
22 namespace grammar {
23
24 namespace detail {
25
26 // returns a tuple
27 template<
28 bool IsList,
29 class R0, class... Rn>
30 struct parse_sequence
31 {
32 using R = detail::tuple<R0, Rn...>;
33
34 using L = mp11::mp_list<
35 typename R0::value_type,
36 typename Rn::value_type...>;
37
38 using V = mp11::mp_remove<
39 std::tuple<
40 system::result<typename R0::value_type>,
41 system::result<typename Rn::value_type>...>,
42 system::result<void>>;
43
44 template<std::size_t I>
45 using is_void = std::is_same<
46 mp11::mp_at_c<L, I>, void>;
47
48 system::error_code ec;
49 R const& rn;
50 V vn;
51
52 BOOST_URL_CXX14_CONSTEXPR
53 explicit
54 8897 parse_sequence(
55 R const& rn_) noexcept
56 8897 : rn(rn_)
57 8897 , vn(mp11::mp_fill<
58 8897 V, system::error_code>{})
59 {
60 8897 }
61
62 BOOST_URL_CXX14_CONSTEXPR
63 void
64 1528 apply(
65 char const*&,
66 char const*,
67 ...) const noexcept
68 {
69 1528 }
70
71 // for system::result<void>
72 template<
73 std::size_t Ir,
74 std::size_t Iv>
75 BOOST_URL_CXX14_CONSTEXPR
76 void
77 2514 apply(
78 char const*& it,
79 char const* end,
80 mp11::mp_size_t<Ir> const&,
81 mp11::mp_size_t<Iv> const&,
82 mp11::mp_true const&)
83 {
84 system::result<void> rv =
85 2514 grammar::parse(
86 2514 it, end, get<Ir>(rn));
87 2514 if( !rv )
88 {
89 426 ec = rv.error();
90 426 return;
91 }
92 2088 apply(it, end,
93 mp11::mp_size_t<Ir+1>{},
94 mp11::mp_size_t<Iv>{});
95 }
96
97 template<
98 std::size_t Ir,
99 std::size_t Iv>
100 BOOST_URL_CXX14_CONSTEXPR
101 void
102 10934 apply(
103 char const*& it,
104 char const* end,
105 mp11::mp_size_t<Ir> const&,
106 mp11::mp_size_t<Iv> const&,
107 mp11::mp_false const&)
108 {
109 10934 auto& rv = get<Iv>(vn);
110 10934 rv = grammar::parse(
111 10934 it, end, get<Ir>(rn));
112 10934 if( !rv )
113 {
114 6943 ec = rv.error();
115 6943 return;
116 }
117 3991 apply(it, end,
118 mp11::mp_size_t<Ir+1>{},
119 mp11::mp_size_t<Iv+1>{});
120 }
121
122 template<
123 std::size_t Ir = 0,
124 std::size_t Iv = 0>
125 BOOST_URL_CXX14_CONSTEXPR
126 typename std::enable_if<
127 Ir < 1 + sizeof...(Rn)>::type
128 13448 apply(
129 char const*& it,
130 char const* end,
131 mp11::mp_size_t<Ir> const& ir = {},
132 mp11::mp_size_t<Iv> const& iv = {}
133 ) noexcept
134 {
135 13448 apply(it, end, ir, iv, is_void<Ir>{});
136 13448 }
137
138 struct deref
139 {
140 template<class R>
141 BOOST_URL_CXX14_CONSTEXPR
142 auto
143 3857 operator()(R const& r) const ->
144 decltype(*r)
145 {
146 3857 return *r;
147 }
148 };
149
150 BOOST_URL_CXX14_CONSTEXPR
151 auto
152 8897 make_result() noexcept ->
153 system::result<typename implementation_defined::tuple_rule_t<
154 R0, Rn...>::value_type>
155 {
156 8897 if(ec.failed())
157 7369 return ec;
158 return mp11::tuple_transform(
159 1528 deref{}, vn);
160 }
161 };
162
163 // See error_types.hpp for details (#979)
164 #if defined(BOOST_GCC) && BOOST_GCC >= 70000
165 #pragma GCC diagnostic push
166 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
167 #endif
168
169 // returns a value_type
170 template<class R0, class... Rn>
171 struct parse_sequence<false, R0, Rn...>
172 {
173 using R = detail::tuple<R0, Rn...>;
174
175 using L = mp11::mp_list<
176 typename R0::value_type,
177 typename Rn::value_type...>;
178
179 using V = mp11::mp_first<
180 mp11::mp_remove<
181 mp11::mp_list<
182 system::result<typename R0::value_type>,
183 system::result<typename Rn::value_type>...>,
184 system::result<void>>>;
185
186 template<std::size_t I>
187 using is_void = std::is_same<
188 mp11::mp_at_c<L, I>, void>;
189
190 R const& rn;
191 V v;
192
193 BOOST_URL_CXX14_CONSTEXPR
194 explicit
195 29175 parse_sequence(
196 R const& rn_) noexcept
197 29175 : rn(rn_)
198 29175 , v(system::error_code{})
199 {
200 29175 }
201
202 BOOST_URL_CXX14_CONSTEXPR
203 void
204 8573 apply(
205 char const*&,
206 char const*,
207 ...) const noexcept
208 {
209 8573 }
210
211 // for system::result<void>
212 template<
213 std::size_t Ir,
214 std::size_t Iv>
215 BOOST_URL_CXX14_CONSTEXPR
216 void
217 22621 apply(
218 char const*& it,
219 char const* end,
220 mp11::mp_size_t<Ir> const&,
221 mp11::mp_size_t<Iv> const&,
222 mp11::mp_true const&)
223 {
224 system::result<void> rv =
225 22621 grammar::parse(
226 22621 it, end, get<Ir>(rn));
227 22621 if( rv.has_error() )
228 {
229 13991 v = rv.error();
230 13991 return;
231 }
232 8630 apply(it, end,
233 mp11::mp_size_t<Ir+1>{},
234 mp11::mp_size_t<Iv>{});
235 }
236
237 template<
238 std::size_t Ir,
239 std::size_t Iv>
240 BOOST_URL_CXX14_CONSTEXPR
241 void
242 27727 apply(
243 char const*& it,
244 char const* end,
245 mp11::mp_size_t<Ir> const&,
246 mp11::mp_size_t<Iv> const&,
247 mp11::mp_false const&)
248 {
249 27727 v = grammar::parse(
250 27727 it, end, get<Ir>(rn));
251 27727 if( !v )
252 6611 return;
253 21116 apply(it, end,
254 mp11::mp_size_t<Ir+1>{},
255 mp11::mp_size_t<Iv+1>{});
256 }
257
258 template<
259 std::size_t Ir = 0,
260 std::size_t Iv = 0>
261 BOOST_URL_CXX14_CONSTEXPR
262 typename std::enable_if<
263 Ir < 1 + sizeof...(Rn)>::type
264 50348 apply(
265 char const*& it,
266 char const* end,
267 mp11::mp_size_t<Ir> const& ir = {},
268 mp11::mp_size_t<Iv> const& iv = {}
269 ) noexcept
270 {
271 50348 apply(it, end, ir, iv, is_void<Ir>{});
272 50348 }
273
274 BOOST_URL_CXX14_CONSTEXPR
275 V
276 29175 make_result() noexcept
277 {
278 29175 return v;
279 }
280 };
281
282 #if defined(BOOST_GCC) && BOOST_GCC >= 70000
283 #pragma GCC diagnostic pop
284 #endif
285
286 } // detail
287
288 template<
289 class R0,
290 class... Rn>
291 BOOST_URL_CXX14_CONSTEXPR
292 auto
293 38072 implementation_defined::tuple_rule_t<R0, Rn...>::
294 parse(
295 char const*& it,
296 char const* end) const ->
297 system::result<value_type>
298 {
299 detail::parse_sequence<
300 38072 IsList, R0, Rn...> t(this->get());
301 38072 t.apply(it, end);
302 38072 return t.make_result();
303 767 }
304
305 } // grammar
306 } // urls
307 } // boost
308
309 #endif
310