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

100.0% Lines (60/60) 98.2% Functions (275/280) 93.8% Branches (15/16)
libs/url/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 //
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_IMPL_TUPLE_RULE_HPP
11 #define BOOST_URL_GRAMMAR_IMPL_TUPLE_RULE_HPP
12
13 #include <boost/url/grammar/parse.hpp>
14 #include <boost/mp11/integral.hpp>
15 #include <boost/mp11/list.hpp>
16 #include <boost/mp11/tuple.hpp>
17 #include <type_traits>
18
19 namespace boost {
20 namespace urls {
21 namespace grammar {
22
23 namespace detail {
24
25 // returns a tuple
26 template<
27 bool IsList,
28 class R0, class... Rn>
29 struct parse_sequence
30 {
31 using R = detail::tuple<R0, Rn...>;
32
33 using L = mp11::mp_list<
34 typename R0::value_type,
35 typename Rn::value_type...>;
36
37 using V = mp11::mp_remove<
38 std::tuple<
39 system::result<typename R0::value_type>,
40 system::result<typename Rn::value_type>...>,
41 system::result<void>>;
42
43 template<std::size_t I>
44 using is_void = std::is_same<
45 mp11::mp_at_c<L, I>, void>;
46
47 system::error_code ec;
48 R const& rn;
49 V vn;
50
51 explicit
52 3630 parse_sequence(
53 R const& rn_) noexcept
54 3630 : rn(rn_)
55 3630 , vn(mp11::mp_fill<
56 3630 V, system::error_code>{})
57 {
58 3630 }
59
60 void
61 1181 apply(
62 char const*&,
63 char const*,
64 ...) const noexcept
65 {
66 1181 }
67
68 // for system::result<void>
69 template<
70 std::size_t Ir,
71 std::size_t Iv>
72 void
73 1488 apply(
74 char const*& it,
75 char const* end,
76 mp11::mp_size_t<Ir> const&,
77 mp11::mp_size_t<Iv> const&,
78 mp11::mp_true const&)
79 {
80 system::result<void> rv =
81
1/1
✓ Branch 1 taken 1488 times.
1488 grammar::parse(
82 1488 it, end, get<Ir>(rn));
83
2/2
✓ Branch 1 taken 352 times.
✓ Branch 2 taken 1136 times.
1488 if( !rv )
84 {
85 352 ec = rv.error();
86 352 return;
87 }
88 1136 apply(it, end,
89 mp11::mp_size_t<Ir+1>{},
90 mp11::mp_size_t<Iv>{});
91 }
92
93 template<
94 std::size_t Ir,
95 std::size_t Iv>
96 void
97 4851 apply(
98 char const*& it,
99 char const* end,
100 mp11::mp_size_t<Ir> const&,
101 mp11::mp_size_t<Iv> const&,
102 mp11::mp_false const&)
103 {
104 4851 auto& rv = get<Iv>(vn);
105
1/1
✓ Branch 1 taken 1699 times.
4851 rv = grammar::parse(
106 4851 it, end, get<Ir>(rn));
107
2/2
✓ Branch 1 taken 2097 times.
✓ Branch 2 taken 2754 times.
4851 if( !rv )
108 {
109 2097 ec = rv.error();
110 2097 return;
111 }
112 2754 apply(it, end,
113 mp11::mp_size_t<Ir+1>{},
114 mp11::mp_size_t<Iv+1>{});
115 }
116
117 template<
118 std::size_t Ir = 0,
119 std::size_t Iv = 0>
120 typename std::enable_if<
121 Ir < 1 + sizeof...(Rn)>::type
122 6339 apply(
123 char const*& it,
124 char const* end,
125 mp11::mp_size_t<Ir> const& ir = {},
126 mp11::mp_size_t<Iv> const& iv = {}
127 ) noexcept
128 {
129 6339 apply(it, end, ir, iv, is_void<Ir>{});
130 6339 }
131
132 struct deref
133 {
134 template<class R>
135 auto
136 2623 operator()(R const& r) const ->
137 decltype(*r)
138 {
139 2623 return *r;
140 }
141 };
142
143 auto
144 3630 make_result() noexcept ->
145 system::result<typename implementation_defined::tuple_rule_t<
146 R0, Rn...>::value_type>
147 {
148
2/2
✓ Branch 1 taken 2449 times.
✓ Branch 2 taken 1181 times.
3630 if(ec.failed())
149 2449 return ec;
150 return mp11::tuple_transform(
151 1181 deref{}, vn);
152 }
153 };
154
155 // returns a value_type
156 template<class R0, class... Rn>
157 struct parse_sequence<false, R0, Rn...>
158 {
159 using R = detail::tuple<R0, Rn...>;
160
161 using L = mp11::mp_list<
162 typename R0::value_type,
163 typename Rn::value_type...>;
164
165 using V = mp11::mp_first<
166 mp11::mp_remove<
167 mp11::mp_list<
168 system::result<typename R0::value_type>,
169 system::result<typename Rn::value_type>...>,
170 system::result<void>>>;
171
172 template<std::size_t I>
173 using is_void = std::is_same<
174 mp11::mp_at_c<L, I>, void>;
175
176 R const& rn;
177 V v;
178
179 explicit
180 7595 parse_sequence(
181 R const& rn_) noexcept
182 7595 : rn(rn_)
183 7595 , v(system::error_code{})
184 {
185 7595 }
186
187 void
188 3560 apply(
189 char const*&,
190 char const*,
191 ...) const noexcept
192 {
193 3560 }
194
195 // for system::result<void>
196 template<
197 std::size_t Ir,
198 std::size_t Iv>
199 BOOST_URL_NO_INLINE
200 void
201 6614 apply(
202 char const*& it,
203 char const* end,
204 mp11::mp_size_t<Ir> const&,
205 mp11::mp_size_t<Iv> const&,
206 mp11::mp_true const&)
207 {
208 system::result<void> rv =
209
2/2
✓ Branch 1 taken 2228 times.
✓ Branch 1 taken 4386 times.
6614 grammar::parse(
210 6614 it, end, get<Ir>(rn));
211
2/2
✓ Branch 1 taken 2997 times.
✓ Branch 2 taken 3617 times.
6614 if( !rv )
212 {
213 2997 v = rv.error();
214 2997 return;
215 }
216 3617 apply(it, end,
217 mp11::mp_size_t<Ir+1>{},
218 mp11::mp_size_t<Iv>{});
219 }
220
221 template<
222 std::size_t Ir,
223 std::size_t Iv>
224 void
225 6360 apply(
226 char const*& it,
227 char const* end,
228 mp11::mp_size_t<Ir> const&,
229 mp11::mp_size_t<Iv> const&,
230 mp11::mp_false const&)
231 {
232
1/2
✓ Branch 1 taken 183 times.
✗ Branch 1 not taken.
6360 v = grammar::parse(
233 6360 it, end, get<Ir>(rn));
234
2/2
✓ Branch 1 taken 1038 times.
✓ Branch 2 taken 5322 times.
6360 if( !v )
235 1038 return;
236 5322 apply(it, end,
237 mp11::mp_size_t<Ir+1>{},
238 mp11::mp_size_t<Iv+1>{});
239 }
240
241 template<
242 std::size_t Ir = 0,
243 std::size_t Iv = 0>
244 typename std::enable_if<
245 Ir < 1 + sizeof...(Rn)>::type
246 12974 apply(
247 char const*& it,
248 char const* end,
249 mp11::mp_size_t<Ir> const& ir = {},
250 mp11::mp_size_t<Iv> const& iv = {}
251 ) noexcept
252 {
253 12974 apply(it, end, ir, iv, is_void<Ir>{});
254 12974 }
255
256 V
257 7595 make_result() noexcept
258 {
259 7595 return v;
260 }
261 };
262
263 } // detail
264
265 template<
266 class R0,
267 class... Rn>
268 auto
269 11225 implementation_defined::tuple_rule_t<R0, Rn...>::
270 parse(
271 char const*& it,
272 char const* end) const ->
273 system::result<value_type>
274 {
275 detail::parse_sequence<
276 11225 IsList, R0, Rn...> t(this->get());
277 11225 t.apply(it, end);
278 11225 return t.make_result();
279 3067 }
280
281 } // grammar
282 } // urls
283 } // boost
284
285 #endif
286