Line | Branch | Exec | Source |
---|---|---|---|
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 | 5009 | parse_sequence( | |
53 | R const& rn_) noexcept | ||
54 | : rn(rn_) | ||
55 | , vn(mp11::mp_fill< | ||
56 | 5009 | V, system::error_code>{}) | |
57 | { | ||
58 | 5009 | } | |
59 | |||
60 | void | ||
61 | 1901 | apply( | |
62 | char const*&, | ||
63 | char const*, | ||
64 | ...) const noexcept | ||
65 | { | ||
66 | 1901 | } | |
67 | |||
68 | // for system::result<void> | ||
69 | template< | ||
70 | std::size_t Ir, | ||
71 | std::size_t Iv> | ||
72 | void | ||
73 | 2970 | 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/2✓ Branch 1 taken 1485 times.
✗ Branch 2 not taken.
|
2970 | grammar::parse( |
82 | 2970 | it, end, get<Ir>(rn)); | |
83 |
2/2✓ Branch 1 taken 352 times.
✓ Branch 2 taken 1133 times.
|
2970 | if( !rv ) |
84 | { | ||
85 | 704 | ec = rv.error(); | |
86 | 704 | return; | |
87 | } | ||
88 | 2266 | 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 | 9654 | 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 | 9654 | auto& rv = get<Iv>(vn); | |
105 | 9654 | rv = grammar::parse( | |
106 | 9654 | it, end, get<Ir>(rn)); | |
107 |
2/2✓ Branch 1 taken 2077 times.
✓ Branch 2 taken 2750 times.
|
9654 | if( !rv ) |
108 | { | ||
109 | 4154 | ec = rv.error(); | |
110 | 4154 | return; | |
111 | } | ||
112 | 5500 | 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 | 12624 | 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 | 12624 | apply(it, end, ir, iv, is_void<Ir>{}); | |
130 | 12624 | } | |
131 | |||
132 | struct deref | ||
133 | { | ||
134 | template<class R> | ||
135 | auto | ||
136 | 4726 | operator()(R const& r) const -> | |
137 | decltype(*r) | ||
138 | { | ||
139 | 4726 | return *r; | |
140 | } | ||
141 | }; | ||
142 | |||
143 | auto | ||
144 | 5009 | make_result() noexcept -> | |
145 | system::result<typename tuple_rule_t< | ||
146 | R0, Rn...>::value_type> | ||
147 | { | ||
148 |
2/2✓ Branch 1 taken 2429 times.
✓ Branch 2 taken 1180 times.
|
5009 | if(ec.failed()) |
149 | 3108 | return ec; | |
150 | return mp11::tuple_transform( | ||
151 | 1901 | 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 | 9740 | parse_sequence( | |
181 | R const& rn_) noexcept | ||
182 | : rn(rn_) | ||
183 | 9740 | , v(system::error_code{}) | |
184 | { | ||
185 | 9740 | } | |
186 | |||
187 | void | ||
188 | 4356 | apply( | |
189 | char const*&, | ||
190 | char const*, | ||
191 | ...) const noexcept | ||
192 | { | ||
193 | 4356 | } | |
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 | 8757 | 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 |
1/2✓ Branch 1 taken 6533 times.
✗ Branch 2 not taken.
|
8757 | grammar::parse( |
210 | 8757 | it, end, get<Ir>(rn)); | |
211 |
2/2✓ Branch 1 taken 2957 times.
✓ Branch 2 taken 3576 times.
|
8757 | if( !rv ) |
212 | { | ||
213 | 4286 | v = rv.error(); | |
214 | 4286 | return; | |
215 | } | ||
216 | 4471 | 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 | 7291 | 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 | 7291 | v = grammar::parse( | |
233 | 7291 | it, end, get<Ir>(rn)); | |
234 |
2/2✓ Branch 1 taken 1034 times.
✓ Branch 2 taken 5241 times.
|
7291 | if( !v ) |
235 | 1098 | return; | |
236 | 6193 | 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 | 25614 | 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 | 25614 | apply(it, end, ir, iv, is_void<Ir>{}); | |
254 | 25614 | } | |
255 | |||
256 | V | ||
257 | 9740 | make_result() noexcept | |
258 | { | ||
259 | 9740 | return v; | |
260 | } | ||
261 | }; | ||
262 | |||
263 | } // detail | ||
264 | |||
265 | template< | ||
266 | class R0, | ||
267 | class... Rn> | ||
268 | auto | ||
269 | 11119 | 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 | 14186 | IsList, R0, Rn...> t(this->get()); | |
277 | 11119 | t.apply(it, end); | |
278 | 11119 | return t.make_result(); | |
279 | } | ||
280 | |||
281 | } // grammar | ||
282 | } // urls | ||
283 | } // boost | ||
284 | |||
285 | #endif | ||
286 |