TLA Line data 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 HIT 3946 : parse_sequence(
55 : R const& rn_) noexcept
56 3946 : : rn(rn_)
57 3946 : , vn(mp11::mp_fill<
58 3946 : V, system::error_code>{})
59 : {
60 3946 : }
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 1694 : grammar::parse(
86 1694 : it, end, get<Ir>(rn));
87 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 5180 : 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 5180 : auto& rv = get<Iv>(vn);
110 5180 : rv = grammar::parse(
111 5180 : it, end, get<Ir>(rn));
112 5180 : if( !rv )
113 : {
114 2272 : ec = rv.error();
115 2272 : 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 6874 : 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 6874 : apply(it, end, ir, iv, is_void<Ir>{});
136 6874 : }
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 3946 : make_result() noexcept ->
153 : system::result<typename implementation_defined::tuple_rule_t<
154 : R0, Rn...>::value_type>
155 : {
156 3946 : if(ec.failed())
157 2691 : return ec;
158 : return mp11::tuple_transform(
159 1255 : 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 8128 : parse_sequence(
196 : R const& rn_) noexcept
197 8128 : : rn(rn_)
198 8128 : , v(system::error_code{})
199 : {
200 8128 : }
201 :
202 : BOOST_URL_CXX14_CONSTEXPR
203 : void
204 3754 : apply(
205 : char const*&,
206 : char const*,
207 : ...) const noexcept
208 : {
209 3754 : }
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 7129 : 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 7129 : grammar::parse(
226 7129 : it, end, get<Ir>(rn));
227 7129 : if( rv.has_error() )
228 : {
229 3318 : v = rv.error();
230 3318 : return;
231 : }
232 3811 : 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 6700 : 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 6700 : v = grammar::parse(
250 6700 : it, end, get<Ir>(rn));
251 6700 : if( !v )
252 1056 : return;
253 5644 : 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 13829 : 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 13829 : apply(it, end, ir, iv, is_void<Ir>{});
272 13829 : }
273 :
274 : BOOST_URL_CXX14_CONSTEXPR
275 : V
276 8128 : make_result() noexcept
277 : {
278 8128 : 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 12074 : 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 12074 : IsList, R0, Rn...> t(this->get());
301 12074 : t.apply(it, end);
302 12074 : return t.make_result();
303 767 : }
304 :
305 : } // grammar
306 : } // urls
307 : } // boost
308 :
309 : #endif
|