GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/format_args.cpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 305 305 100.0%
Functions: 11 11 100.0%
Branches: 233 272 85.7%

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