Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.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_DETAIL_IMPL_FORMAT_ARGS_IPP | ||
11 | #define BOOST_URL_DETAIL_IMPL_FORMAT_ARGS_IPP | ||
12 | |||
13 | #include <boost/url/detail/config.hpp> | ||
14 | #include <boost/url/encode.hpp> | ||
15 | #include <boost/url/detail/format_args.hpp> | ||
16 | #include "boost/url/detail/replacement_field_rule.hpp" | ||
17 | #include <boost/url/grammar/delim_rule.hpp> | ||
18 | #include <boost/url/grammar/optional_rule.hpp> | ||
19 | #include <boost/url/grammar/parse.hpp> | ||
20 | #include <boost/url/grammar/tuple_rule.hpp> | ||
21 | #include <boost/url/grammar/unsigned_rule.hpp> | ||
22 | |||
23 | namespace boost { | ||
24 | namespace urls { | ||
25 | namespace detail { | ||
26 | |||
27 | std::size_t | ||
28 | 68 | get_uvalue( core::string_view a ) | |
29 | { | ||
30 | 68 | core::string_view str(a); | |
31 | auto rv = grammar::parse( | ||
32 | 68 | str, grammar::unsigned_rule<std::size_t>{}); | |
33 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 66 times.
|
68 | if (rv) |
34 | 2 | return *rv; | |
35 | 66 | return 0; | |
36 | } | ||
37 | |||
38 | std::size_t | ||
39 | 68 | get_uvalue( char a ) | |
40 | { | ||
41 | 68 | core::string_view str(&a, 1); | |
42 |
1/2✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
|
136 | return get_uvalue(str); |
43 | } | ||
44 | |||
45 | char const* | ||
46 | 369 | formatter<core::string_view>:: | |
47 | parse(format_parse_context& ctx) | ||
48 | { | ||
49 | 369 | char const* it = ctx.begin(); | |
50 | 369 | char const* end = ctx.end(); | |
51 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
|
369 | BOOST_ASSERT(it != end); |
52 | |||
53 | // fill / align | ||
54 |
2/2✓ Branch 0 taken 107 times.
✓ Branch 1 taken 262 times.
|
369 | if (end - it > 2) |
55 | { | ||
56 |
1/2✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
|
107 | if (*it != '{' && |
57 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 86 times.
|
107 | *it != '}' && |
58 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 2 times.
|
21 | (*(it + 1) == '<' || |
59 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 12 times.
|
19 | *(it + 1) == '>' || |
60 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | *(it + 1) == '^')) |
61 | { | ||
62 | 16 | fill = *it; | |
63 | 16 | align = *(it + 1); | |
64 | 16 | it += 2; | |
65 | } | ||
66 | } | ||
67 | |||
68 | // align | ||
69 |
2/2✓ Branch 0 taken 353 times.
✓ Branch 1 taken 16 times.
|
369 | if (align == '\0' && |
70 |
1/2✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
|
353 | (*it == '<' || |
71 |
1/2✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
|
353 | *it == '>' || |
72 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 349 times.
|
353 | *it == '^')) |
73 | { | ||
74 | 4 | align = *it++; | |
75 | } | ||
76 | |||
77 | // width | ||
78 | 369 | char const* it0 = it; | |
79 | 369 | constexpr auto width_rule = | |
80 | grammar::variant_rule( | ||
81 | grammar::unsigned_rule<std::size_t>{}, | ||
82 | grammar::tuple_rule( | ||
83 | grammar::squelch( | ||
84 | grammar::delim_rule('{')), | ||
85 | grammar::optional_rule( | ||
86 | arg_id_rule), | ||
87 | grammar::squelch( | ||
88 | grammar::delim_rule('}')))); | ||
89 |
1/2✓ Branch 1 taken 369 times.
✗ Branch 2 not taken.
|
370 | auto rw = grammar::parse(it, end, width_rule); |
90 |
2/2✓ Branch 1 taken 349 times.
✓ Branch 2 taken 20 times.
|
369 | if (!rw) |
91 | { | ||
92 | // rewind | ||
93 | 349 | it = it0; | |
94 | } | ||
95 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | else if (align != '\0') |
96 | { | ||
97 | // width is ignored when align is '\0' | ||
98 |
2/2✓ Branch 2 taken 10 times.
✓ Branch 3 taken 10 times.
|
20 | if (rw->index() == 0) |
99 | { | ||
100 | // unsigned_rule | ||
101 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | width = variant2::get<0>(*rw); |
102 | } | ||
103 | else | ||
104 | { | ||
105 | // arg_id: store the id idx or string | ||
106 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | auto& arg_id = variant2::get<1>(*rw); |
107 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
|
10 | if (!arg_id) |
108 | { | ||
109 | // empty arg_id, use and consume | ||
110 | // the next arg idx | ||
111 | 2 | width_idx = ctx.next_arg_id(); | |
112 | } | ||
113 |
3/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
8 | else if (arg_id->index() == 0) |
114 | { | ||
115 | // string identifier | ||
116 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | width_name = variant2::get<0>(*arg_id); |
117 | } | ||
118 | else | ||
119 | { | ||
120 | // integer identifier: use the | ||
121 | // idx of this format_arg | ||
122 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | width_idx = variant2::get<1>(*arg_id); |
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | // type is parsed but doesn't have to | ||
128 | // be stored for strings | ||
129 |
2/2✓ Branch 0 taken 366 times.
✓ Branch 1 taken 3 times.
|
369 | if (*it == 'c' || |
130 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 346 times.
|
366 | *it == 's') |
131 | { | ||
132 | 23 | ++it; | |
133 | } | ||
134 | |||
135 | // we should have arrived at the end now | ||
136 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 368 times.
|
369 | if (*it != '}') |
137 | { | ||
138 | 1 | urls::detail::throw_invalid_argument(); | |
139 | } | ||
140 | |||
141 | 736 | return it; | |
142 | } | ||
143 | |||
144 | std::size_t | ||
145 | 185 | formatter<core::string_view>:: | |
146 | measure( | ||
147 | core::string_view str, | ||
148 | measure_context& ctx, | ||
149 | grammar::lut_chars const& cs) const | ||
150 | { | ||
151 | 185 | std::size_t w = width; | |
152 |
4/4✓ Branch 0 taken 182 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 180 times.
|
367 | if (width_idx != std::size_t(-1) || |
153 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 180 times.
|
182 | !width_name.empty()) |
154 | { | ||
155 | 5 | get_width_from_args( | |
156 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
157 | } | ||
158 | |||
159 | 185 | std::size_t n = ctx.out(); | |
160 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 176 times.
|
185 | if (str.size() < w) |
161 | 9 | n += measure_one(fill, cs) * (w - str.size()); | |
162 | |||
163 | 185 | return n + encoded_size(str, cs); | |
164 | } | ||
165 | |||
166 | char* | ||
167 | 183 | formatter<core::string_view>:: | |
168 | format(core::string_view str, format_context& ctx, grammar::lut_chars const& cs) const | ||
169 | { | ||
170 | 183 | std::size_t w = width; | |
171 |
4/4✓ Branch 0 taken 180 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 178 times.
|
363 | if (width_idx != std::size_t(-1) || |
172 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 178 times.
|
180 | !width_name.empty()) |
173 | { | ||
174 | 5 | get_width_from_args( | |
175 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
176 | } | ||
177 | |||
178 | 183 | std::size_t lpad = 0; | |
179 | 183 | std::size_t rpad = 0; | |
180 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 174 times.
|
183 | if (str.size() < w) |
181 | { | ||
182 | 9 | std::size_t pad = w - str.size(); | |
183 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
9 | switch (align) |
184 | { | ||
185 | 1 | case '<': | |
186 | 1 | rpad = pad; | |
187 | 1 | break; | |
188 | 6 | case '>': | |
189 | 6 | lpad = pad; | |
190 | 6 | break; | |
191 | 2 | case '^': | |
192 | 2 | lpad = w / 2; | |
193 | 2 | rpad = pad - lpad; | |
194 | 2 | break; | |
195 | } | ||
196 | } | ||
197 | |||
198 | // unsafe `encode`, assuming `out` has | ||
199 | // enough capacity | ||
200 | 183 | char* out = ctx.out(); | |
201 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 183 times.
|
210 | for (std::size_t i = 0; i < lpad; ++i) |
202 | 27 | encode_one(out, fill, cs); | |
203 |
2/2✓ Branch 2 taken 695 times.
✓ Branch 3 taken 183 times.
|
878 | for (char c: str) |
204 | 695 | encode_one(out, c, cs); | |
205 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 183 times.
|
190 | for (std::size_t i = 0; i < rpad; ++i) |
206 | 7 | encode_one(out, fill, cs); | |
207 | 183 | return out; | |
208 | } | ||
209 | |||
210 | void | ||
211 | 28 | get_width_from_args( | |
212 | std::size_t arg_idx, | ||
213 | core::string_view arg_name, | ||
214 | format_args args, | ||
215 | std::size_t& w) | ||
216 | { | ||
217 | // check arg_id | ||
218 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | format_arg warg; |
219 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
|
28 | if (arg_idx != std::size_t(-1)) |
220 | { | ||
221 | // identifier | ||
222 | 18 | warg = args.get(arg_idx); | |
223 | } | ||
224 | else | ||
225 | { | ||
226 | // unsigned integer | ||
227 | 10 | warg = args.get(arg_name); | |
228 | } | ||
229 | |||
230 | // get unsigned int value from that format arg | ||
231 | 28 | w = warg.value(); | |
232 | 28 | } | |
233 | |||
234 | char const* | ||
235 | 97 | integer_formatter_impl:: | |
236 | parse(format_parse_context& ctx) | ||
237 | { | ||
238 | 97 | char const* it = ctx.begin(); | |
239 | 97 | char const* end = ctx.end(); | |
240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | BOOST_ASSERT(it != end); |
241 | |||
242 | // fill / align | ||
243 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 40 times.
|
97 | if (end - it > 2) |
244 | { | ||
245 |
1/2✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
|
57 | if (*it != '{' && |
246 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 4 times.
|
57 | *it != '}' && |
247 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 4 times.
|
53 | (*(it + 1) == '<' || |
248 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 22 times.
|
49 | *(it + 1) == '>' || |
249 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 23 times.
|
27 | *(it + 1) == '^')) |
250 | { | ||
251 | 30 | fill = *it; | |
252 | 30 | align = *(it + 1); | |
253 | 30 | it += 2; | |
254 | } | ||
255 | } | ||
256 | |||
257 | // align | ||
258 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 30 times.
|
97 | if (align == '\0' && |
259 |
1/2✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
|
67 | (*it == '<' || |
260 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 8 times.
|
67 | *it == '>' || |
261 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 55 times.
|
59 | *it == '^')) |
262 | { | ||
263 | 12 | align = *it++; | |
264 | } | ||
265 | |||
266 | // sign | ||
267 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 6 times.
|
97 | if (*it == '+' || |
268 |
1/2✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
|
91 | *it == '-' || |
269 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 85 times.
|
91 | *it == ' ') |
270 | { | ||
271 | 12 | sign = *it++; | |
272 | } | ||
273 | |||
274 | // # | ||
275 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 95 times.
|
97 | if (*it == '#') |
276 | { | ||
277 | // alternate form not supported | ||
278 | 2 | ++it; | |
279 | } | ||
280 | |||
281 | // 0 | ||
282 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 89 times.
|
97 | if (*it == '0') |
283 | { | ||
284 | 8 | zeros = *it++; | |
285 | } | ||
286 | |||
287 | // width | ||
288 | 97 | char const* it0 = it; | |
289 | 97 | constexpr auto width_rule = grammar::variant_rule( | |
290 | grammar::unsigned_rule<std::size_t>{}, | ||
291 | grammar::tuple_rule( | ||
292 | grammar::squelch( | ||
293 | grammar::delim_rule('{')), | ||
294 | grammar::optional_rule( | ||
295 | arg_id_rule), | ||
296 | grammar::squelch( | ||
297 | grammar::delim_rule('}')))); | ||
298 |
1/2✓ Branch 1 taken 97 times.
✗ Branch 2 not taken.
|
98 | auto rw = grammar::parse(it, end, width_rule); |
299 |
2/2✓ Branch 1 taken 55 times.
✓ Branch 2 taken 42 times.
|
97 | if (!rw) |
300 | { | ||
301 | // rewind | ||
302 | 55 | it = it0; | |
303 | } | ||
304 |
1/2✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
|
42 | else if (align != '\0') |
305 | { | ||
306 | // width is ignored when align is '\0' | ||
307 |
2/2✓ Branch 2 taken 24 times.
✓ Branch 3 taken 18 times.
|
42 | if (rw->index() == 0) |
308 | { | ||
309 | // unsigned_rule | ||
310 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
24 | width = variant2::get<0>(*rw); |
311 | } | ||
312 | else | ||
313 | { | ||
314 | // arg_id: store the id idx or string | ||
315 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 | auto& arg_id = variant2::get<1>(*rw); |
316 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 14 times.
|
18 | if (!arg_id) |
317 | { | ||
318 | // empty arg_id, use and consume | ||
319 | // the next arg idx | ||
320 | 4 | width_idx = ctx.next_arg_id(); | |
321 | } | ||
322 |
3/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 8 times.
|
14 | else if (arg_id->index() == 0) |
323 | { | ||
324 | // string identifier | ||
325 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
6 | width_name = variant2::get<0>(*arg_id); |
326 | } | ||
327 | else | ||
328 | { | ||
329 | // integer identifier: use the | ||
330 | // idx of this format_arg | ||
331 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | width_idx = variant2::get<1>(*arg_id); |
332 | } | ||
333 | } | ||
334 | } | ||
335 | |||
336 | // type is parsed but doesn't have to | ||
337 | // be stored for strings | ||
338 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 42 times.
|
97 | if (*it == 'd') |
339 | { | ||
340 | // we don't include other presentation | ||
341 | // modes for integers as they are not | ||
342 | // recommended or generally used in | ||
343 | // urls | ||
344 | 55 | ++it; | |
345 | } | ||
346 | |||
347 | // we should have arrived at the end now | ||
348 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 96 times.
|
97 | if (*it != '}') |
349 | { | ||
350 | 1 | urls::detail::throw_invalid_argument(); | |
351 | } | ||
352 | |||
353 | 192 | return it; | |
354 | } | ||
355 | |||
356 | std::size_t | ||
357 | 34 | integer_formatter_impl:: | |
358 | measure( | ||
359 | long long int v, | ||
360 | measure_context& ctx, | ||
361 | grammar::lut_chars const& cs) const | ||
362 | { | ||
363 | 34 | std::size_t dn = 0; | |
364 | 34 | std::size_t n = 0; | |
365 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
366 | { | ||
367 | 1 | dn += measure_one('-', cs); | |
368 | 1 | ++n; | |
369 | 1 | v *= -1; | |
370 | } | ||
371 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
372 | { | ||
373 | 4 | dn += measure_one(sign, cs); | |
374 | 4 | ++n; | |
375 | } | ||
376 | 33 | do | |
377 | { | ||
378 | 67 | int d = v % 10; | |
379 | 67 | v /= 10; | |
380 | 67 | dn += measure_one('0' + static_cast<char>(d), cs); | |
381 | 67 | ++n; | |
382 | } | ||
383 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | while (v > 0); |
384 | |||
385 | 34 | std::size_t w = width; | |
386 |
4/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 29 times.
|
65 | if (width_idx != std::size_t(-1) || |
387 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
|
31 | !width_name.empty()) |
388 | { | ||
389 | 5 | get_width_from_args( | |
390 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
391 | } | ||
392 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 22 times.
|
34 | if (w > n) |
393 | { | ||
394 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
|
12 | if (!zeros) |
395 | 9 | dn += measure_one(fill, cs) * (w - n); | |
396 | else | ||
397 | 3 | dn += measure_one('0', cs) * (w - n); | |
398 | } | ||
399 | 34 | return ctx.out() + dn; | |
400 | } | ||
401 | |||
402 | std::size_t | ||
403 | 14 | integer_formatter_impl:: | |
404 | measure( | ||
405 | unsigned long long int v, | ||
406 | measure_context& ctx, | ||
407 | grammar::lut_chars const& cs) const | ||
408 | { | ||
409 | 14 | std::size_t dn = 0; | |
410 | 14 | std::size_t n = 0; | |
411 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
412 | { | ||
413 | 2 | dn += measure_one(sign, cs); | |
414 | 2 | ++n; | |
415 | } | ||
416 | 39 | do | |
417 | { | ||
418 | 53 | int d = v % 10; | |
419 | 53 | v /= 10; | |
420 | 53 | dn += measure_one('0' + static_cast<char>(d), cs); | |
421 | 53 | ++n; | |
422 | } | ||
423 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | while (v != 0); |
424 | |||
425 | 14 | std::size_t w = width; | |
426 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 10 times.
|
25 | if (width_idx != std::size_t(-1) || |
427 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | !width_name.empty()) |
428 | { | ||
429 | 4 | get_width_from_args( | |
430 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | width_idx, width_name, ctx.args(), w); |
431 | } | ||
432 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | if (w > n) |
433 | { | ||
434 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
|
8 | if (!zeros) |
435 | 7 | dn += measure_one(fill, cs) * (w - n); | |
436 | else | ||
437 | 1 | dn += measure_one('0', cs) * (w - n); | |
438 | } | ||
439 | 14 | return ctx.out() + dn; | |
440 | } | ||
441 | |||
442 | char* | ||
443 | 34 | integer_formatter_impl:: | |
444 | format( | ||
445 | long long int v, | ||
446 | format_context& ctx, | ||
447 | grammar::lut_chars const& cs) const | ||
448 | { | ||
449 | // get n digits | ||
450 | 34 | long long int v0 = v; | |
451 | 34 | long long int p = 1; | |
452 | 34 | std::size_t n = 0; | |
453 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
454 | { | ||
455 | 1 | v *= - 1; | |
456 | 1 | ++n; | |
457 | } | ||
458 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
459 | { | ||
460 | 4 | ++n; | |
461 | } | ||
462 | 33 | do | |
463 | { | ||
464 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | if (v >= 10) |
465 | 33 | p *= 10; | |
466 | 67 | v /= 10; | |
467 | 67 | ++n; | |
468 | } | ||
469 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 34 times.
|
67 | while (v > 0); |
470 | static constexpr auto m = | ||
471 | std::numeric_limits<long long int>::digits10; | ||
472 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | BOOST_ASSERT(n <= m + 1); |
473 | ignore_unused(m); | ||
474 | |||
475 | // get pad | ||
476 | 34 | std::size_t w = width; | |
477 |
4/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 29 times.
|
65 | if (width_idx != std::size_t(-1) || |
478 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
|
31 | !width_name.empty()) |
479 | { | ||
480 | 5 | get_width_from_args( | |
481 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | width_idx, width_name, ctx.args(), w); |
482 | } | ||
483 | 34 | std::size_t lpad = 0; | |
484 | 34 | std::size_t rpad = 0; | |
485 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 22 times.
|
34 | if (w > n) |
486 | { | ||
487 | 12 | std::size_t pad = w - n; | |
488 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
|
12 | if (zeros) |
489 | { | ||
490 | 3 | lpad = pad; | |
491 | } | ||
492 | else | ||
493 | { | ||
494 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
9 | switch (align) |
495 | { | ||
496 | 1 | case '<': | |
497 | 1 | rpad = pad; | |
498 | 1 | break; | |
499 | 6 | case '>': | |
500 | 6 | lpad = pad; | |
501 | 6 | break; | |
502 | 2 | case '^': | |
503 | 2 | lpad = pad / 2; | |
504 | 2 | rpad = pad - lpad; | |
505 | 2 | break; | |
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 | // write | ||
511 | 34 | v = v0; | |
512 | 34 | char* out = ctx.out(); | |
513 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
|
34 | if (!zeros) |
514 | { | ||
515 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 31 times.
|
59 | for (std::size_t i = 0; i < lpad; ++i) |
516 | 28 | encode_one(out, fill, cs); | |
517 | } | ||
518 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 33 times.
|
34 | if (v < 0) |
519 | { | ||
520 | 1 | encode_one(out, '-', cs); | |
521 | 1 | v *= -1; | |
522 | 1 | --n; | |
523 | } | ||
524 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
|
33 | else if (sign != '-') |
525 | { | ||
526 | 4 | encode_one(out, sign, cs); | |
527 | 4 | --n; | |
528 | } | ||
529 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 31 times.
|
34 | if (zeros) |
530 | { | ||
531 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
|
13 | for (std::size_t i = 0; i < lpad; ++i) |
532 | 10 | encode_one(out, '0', cs); | |
533 | } | ||
534 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 34 times.
|
101 | while (n) |
535 | { | ||
536 | 67 | unsigned long long int d = v / p; | |
537 | 67 | encode_one(out, '0' + static_cast<char>(d), cs); | |
538 | 67 | --n; | |
539 | 67 | v %= p; | |
540 | 67 | p /= 10; | |
541 | } | ||
542 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 3 times.
|
34 | if (!zeros) |
543 | { | ||
544 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 31 times.
|
39 | for (std::size_t i = 0; i < rpad; ++i) |
545 | 8 | encode_one(out, fill, cs); | |
546 | } | ||
547 | 34 | return out; | |
548 | } | ||
549 | |||
550 | char* | ||
551 | 14 | integer_formatter_impl:: | |
552 | format( | ||
553 | unsigned long long int v, | ||
554 | format_context& ctx, | ||
555 | grammar::lut_chars const& cs) const | ||
556 | { | ||
557 | // get n digits | ||
558 | 14 | unsigned long long int v0 = v; | |
559 | 14 | unsigned long long int p = 1; | |
560 | 14 | std::size_t n = 0; | |
561 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
562 | { | ||
563 | 2 | ++n; | |
564 | } | ||
565 | 39 | do | |
566 | { | ||
567 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | if (v >= 10) |
568 | 39 | p *= 10; | |
569 | 53 | v /= 10; | |
570 | 53 | ++n; | |
571 | } | ||
572 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | while (v > 0); |
573 | static constexpr auto m = | ||
574 | std::numeric_limits<unsigned long long int>::digits10; | ||
575 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | BOOST_ASSERT(n <= m + 1); |
576 | ignore_unused(m); | ||
577 | |||
578 | // get pad | ||
579 | 14 | std::size_t w = width; | |
580 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 10 times.
|
25 | if (width_idx != std::size_t(-1) || |
581 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | !width_name.empty()) |
582 | { | ||
583 | 4 | get_width_from_args( | |
584 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | width_idx, width_name, ctx.args(), w); |
585 | } | ||
586 | 14 | std::size_t lpad = 0; | |
587 | 14 | std::size_t rpad = 0; | |
588 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | if (w > n) |
589 | { | ||
590 | 8 | std::size_t pad = w - n; | |
591 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
|
8 | if (zeros) |
592 | { | ||
593 | 1 | lpad = pad; | |
594 | } | ||
595 | else | ||
596 | { | ||
597 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
7 | switch (align) |
598 | { | ||
599 | 1 | case '<': | |
600 | 1 | rpad = pad; | |
601 | 1 | break; | |
602 | 5 | case '>': | |
603 | 5 | lpad = pad; | |
604 | 5 | break; | |
605 | 1 | case '^': | |
606 | 1 | lpad = pad / 2; | |
607 | 1 | rpad = pad - lpad; | |
608 | 1 | break; | |
609 | } | ||
610 | } | ||
611 | } | ||
612 | |||
613 | // write | ||
614 | 14 | v = v0; | |
615 | 14 | char* out = ctx.out(); | |
616 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | if (!zeros) |
617 | { | ||
618 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 13 times.
|
35 | for (std::size_t i = 0; i < lpad; ++i) |
619 | 22 | encode_one(out, fill, cs); | |
620 | } | ||
621 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (sign != '-') |
622 | { | ||
623 | 2 | encode_one(out, sign, cs); | |
624 | 2 | --n; | |
625 | } | ||
626 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if (zeros) |
627 | { | ||
628 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
|
5 | for (std::size_t i = 0; i < lpad; ++i) |
629 | 4 | encode_one(out, '0', cs); | |
630 | } | ||
631 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 14 times.
|
67 | while (n) |
632 | { | ||
633 | 53 | unsigned long long int d = v / p; | |
634 | 53 | encode_one(out, '0' + static_cast<char>(d), cs); | |
635 | 53 | --n; | |
636 | 53 | v %= p; | |
637 | 53 | p /= 10; | |
638 | } | ||
639 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | if (!zeros) |
640 | { | ||
641 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13 times.
|
19 | for (std::size_t i = 0; i < rpad; ++i) |
642 | 6 | encode_one(out, fill, cs); | |
643 | } | ||
644 | 14 | return out; | |
645 | } | ||
646 | |||
647 | } // detail | ||
648 | } // urls | ||
649 | } // boost | ||
650 | |||
651 | #endif | ||
652 |