GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/impl/tuple_rule.hpp
Date: 2024-03-12 19:37:18
Exec Total Coverage
Lines: 56 56 100.0%
Functions: 263 269 97.8%
Branches: 12 14 85.7%

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 5023 parse_sequence(
53 R const& rn_) noexcept
54 : rn(rn_)
55 , vn(mp11::mp_fill<
56 5023 V, system::error_code>{})
57 {
58 5023 }
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 9682 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 9682 auto& rv = get<Iv>(vn);
105 9682 rv = grammar::parse(
106 9682 it, end, get<Ir>(rn));
107
2/2
✓ Branch 1 taken 2091 times.
✓ Branch 2 taken 2750 times.
9682 if( !rv )
108 {
109 4182 ec = rv.error();
110 4182 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 12652 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 12652 apply(it, end, ir, iv, is_void<Ir>{});
130 12652 }
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 5023 make_result() noexcept ->
145 system::result<typename tuple_rule_t<
146 R0, Rn...>::value_type>
147 {
148
2/2
✓ Branch 1 taken 2443 times.
✓ Branch 2 taken 1180 times.
5023 if(ec.failed())
149 3122 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 9768 parse_sequence(
181 R const& rn_) noexcept
182 : rn(rn_)
183 9768 , v(system::error_code{})
184 {
185 9768 }
186
187 void
188 4370 apply(
189 char const*&,
190 char const*,
191 ...) const noexcept
192 {
193 4370 }
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 8785 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 6561 times.
✗ Branch 2 not taken.
8785 grammar::parse(
210 8785 it, end, get<Ir>(rn));
211
2/2
✓ Branch 1 taken 2971 times.
✓ Branch 2 taken 3590 times.
8785 if( !rv )
212 {
213 4300 v = rv.error();
214 4300 return;
215 }
216 4485 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 7319 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 7319 v = grammar::parse(
233 7319 it, end, get<Ir>(rn));
234
2/2
✓ Branch 1 taken 1034 times.
✓ Branch 2 taken 5269 times.
7319 if( !v )
235 1098 return;
236 6221 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 25726 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 25726 apply(it, end, ir, iv, is_void<Ir>{});
254 25726 }
255
256 V
257 9768 make_result() noexcept
258 {
259 9768 return v;
260 }
261 };
262
263 } // detail
264
265 template<
266 class R0,
267 class... Rn>
268 auto
269 11161 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 14228 IsList, R0, Rn...> t(this->get());
277 11161 t.apply(it, end);
278 11161 return t.make_result();
279 }
280
281 } // grammar
282 } // urls
283 } // boost
284
285 #endif
286