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

100.0% Lines (60/60) 97.7% Functions (253/259) 93.8% Branches (15/16)
include/boost/url/grammar/impl/tuple_rule.hpp
Line Branch 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 3945 parse_sequence(
55 R const& rn_) noexcept
56 3945 : rn(rn_)
57 3945 , vn(mp11::mp_fill<
58 3945 V, system::error_code>{})
59 {
60 3945 }
61
62 BOOST_URL_CXX14_CONSTEXPR
63 void
64 1255 apply(
65 char const*&,
66 char const*,
67 ...) const noexcept
68 {
69 1255 }
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 1694 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
1/1
✓ Branch 1 taken 1694 times.
1694 grammar::parse(
86 1694 it, end, get<Ir>(rn));
87
2/2
✓ Branch 1 taken 419 times.
✓ Branch 2 taken 1275 times.
1694 if( !rv )
88 {
89 419 ec = rv.error();
90 419 return;
91 }
92 1275 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 5179 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 5179 auto& rv = get<Iv>(vn);
110
1/1
✓ Branch 1 taken 1853 times.
5179 rv = grammar::parse(
111 5179 it, end, get<Ir>(rn));
112
2/2
✓ Branch 1 taken 2271 times.
✓ Branch 2 taken 2908 times.
5179 if( !rv )
113 {
114 2271 ec = rv.error();
115 2271 return;
116 }
117 2908 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 6873 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 6873 apply(it, end, ir, iv, is_void<Ir>{});
136 6873 }
137
138 struct deref
139 {
140 template<class R>
141 BOOST_URL_CXX14_CONSTEXPR
142 auto
143 2777 operator()(R const& r) const ->
144 decltype(*r)
145 {
146 2777 return *r;
147 }
148 };
149
150 BOOST_URL_CXX14_CONSTEXPR
151 auto
152 3945 make_result() noexcept ->
153 system::result<typename implementation_defined::tuple_rule_t<
154 R0, Rn...>::value_type>
155 {
156
2/2
✓ Branch 1 taken 2690 times.
✓ Branch 2 taken 1255 times.
3945 if(ec.failed())
157 2690 return ec;
158 return mp11::tuple_transform(
159 1255 deref{}, vn);
160 }
161 };
162
163 // returns a value_type
164 template<class R0, class... Rn>
165 struct parse_sequence<false, R0, Rn...>
166 {
167 using R = detail::tuple<R0, Rn...>;
168
169 using L = mp11::mp_list<
170 typename R0::value_type,
171 typename Rn::value_type...>;
172
173 using V = mp11::mp_first<
174 mp11::mp_remove<
175 mp11::mp_list<
176 system::result<typename R0::value_type>,
177 system::result<typename Rn::value_type>...>,
178 system::result<void>>>;
179
180 template<std::size_t I>
181 using is_void = std::is_same<
182 mp11::mp_at_c<L, I>, void>;
183
184 R const& rn;
185 V v;
186
187 BOOST_URL_CXX14_CONSTEXPR
188 explicit
189 8110 parse_sequence(
190 R const& rn_) noexcept
191 8110 : rn(rn_)
192 8110 , v(system::error_code{})
193 {
194 8110 }
195
196 BOOST_URL_CXX14_CONSTEXPR
197 void
198 3752 apply(
199 char const*&,
200 char const*,
201 ...) const noexcept
202 {
203 3752 }
204
205 // for system::result<void>
206 template<
207 std::size_t Ir,
208 std::size_t Iv>
209 BOOST_URL_CXX14_CONSTEXPR
210 void
211 7125 apply(
212 char const*& it,
213 char const* end,
214 mp11::mp_size_t<Ir> const&,
215 mp11::mp_size_t<Iv> const&,
216 mp11::mp_true const&)
217 {
218 system::result<void> rv =
219
2/2
✓ Branch 1 taken 7044 times.
✓ Branch 1 taken 81 times.
7125 grammar::parse(
220 7125 it, end, get<Ir>(rn));
221
2/2
✓ Branch 1 taken 3316 times.
✓ Branch 2 taken 3809 times.
7125 if( !rv )
222 {
223 3316 v = rv.error();
224 3316 return;
225 }
226 3809 apply(it, end,
227 mp11::mp_size_t<Ir+1>{},
228 mp11::mp_size_t<Iv>{});
229 }
230
231 template<
232 std::size_t Ir,
233 std::size_t Iv>
234 BOOST_URL_CXX14_CONSTEXPR
235 void
236 6682 apply(
237 char const*& it,
238 char const* end,
239 mp11::mp_size_t<Ir> const&,
240 mp11::mp_size_t<Iv> const&,
241 mp11::mp_false const&)
242 {
243
1/2
✓ Branch 1 taken 191 times.
✗ Branch 1 not taken.
6682 v = grammar::parse(
244 6682 it, end, get<Ir>(rn));
245
2/2
✓ Branch 1 taken 1042 times.
✓ Branch 2 taken 5640 times.
6682 if( !v )
246 1042 return;
247 5640 apply(it, end,
248 mp11::mp_size_t<Ir+1>{},
249 mp11::mp_size_t<Iv+1>{});
250 }
251
252 template<
253 std::size_t Ir = 0,
254 std::size_t Iv = 0>
255 BOOST_URL_CXX14_CONSTEXPR
256 typename std::enable_if<
257 Ir < 1 + sizeof...(Rn)>::type
258 13807 apply(
259 char const*& it,
260 char const* end,
261 mp11::mp_size_t<Ir> const& ir = {},
262 mp11::mp_size_t<Iv> const& iv = {}
263 ) noexcept
264 {
265 13807 apply(it, end, ir, iv, is_void<Ir>{});
266 13807 }
267
268 BOOST_URL_CXX14_CONSTEXPR
269 V
270 8110 make_result() noexcept
271 {
272 8110 return v;
273 }
274 };
275
276 } // detail
277
278 template<
279 class R0,
280 class... Rn>
281 BOOST_URL_CXX14_CONSTEXPR
282 auto
283 12055 implementation_defined::tuple_rule_t<R0, Rn...>::
284 parse(
285 char const*& it,
286 char const* end) const ->
287 system::result<value_type>
288 {
289 detail::parse_sequence<
290 12055 IsList, R0, Rn...> t(this->get());
291 12055 t.apply(it, end);
292 12055 return t.make_result();
293 767 }
294
295 } // grammar
296 } // urls
297 } // boost
298
299 #endif
300