2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H
11 #define _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H
13 #include <__cxx03/__algorithm/copy_n.h>
14 #include <__cxx03/__algorithm/find.h>
15 #include <__cxx03/__algorithm/max.h>
16 #include <__cxx03/__algorithm/min.h>
17 #include <__cxx03/__algorithm/rotate.h>
18 #include <__cxx03/__algorithm/transform.h>
19 #include <__cxx03/__assert>
20 #include <__cxx03/__charconv/chars_format.h>
21 #include <__cxx03/__charconv/to_chars_floating_point.h>
22 #include <__cxx03/__charconv/to_chars_result.h>
23 #include <__cxx03/__concepts/arithmetic.h>
24 #include <__cxx03/__concepts/same_as.h>
25 #include <__cxx03/__config>
26 #include <__cxx03/__format/concepts.h>
27 #include <__cxx03/__format/format_parse_context.h>
28 #include <__cxx03/__format/formatter.h>
29 #include <__cxx03/__format/formatter_integral.h>
30 #include <__cxx03/__format/formatter_output.h>
31 #include <__cxx03/__format/parser_std_format_spec.h>
32 #include <__cxx03/__iterator/concepts.h>
33 #include <__cxx03/__memory/allocator.h>
34 #include <__cxx03/__system_error/errc.h>
35 #include <__cxx03/__type_traits/conditional.h>
36 #include <__cxx03/__utility/move.h>
37 #include <__cxx03/__utility/unreachable.h>
38 #include <__cxx03/cmath>
39 #include <__cxx03/cstddef>
41 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
42 # include <__cxx03/__locale>
45 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
46 # pragma GCC system_header
50 #include <__cxx03/__undef_macros>
52 _LIBCPP_BEGIN_NAMESPACE_STD
54 #if _LIBCPP_STD_VER >= 20
56 namespace __formatter
{
58 template <floating_point _Tp
>
59 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
) {
60 to_chars_result __r
= std::to_chars(__first
, __last
, __value
);
61 _LIBCPP_ASSERT_INTERNAL(__r
.ec
== errc(0), "Internal buffer too small");
65 template <floating_point _Tp
>
66 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
, chars_format __fmt
) {
67 to_chars_result __r
= std::to_chars(__first
, __last
, __value
, __fmt
);
68 _LIBCPP_ASSERT_INTERNAL(__r
.ec
== errc(0), "Internal buffer too small");
72 template <floating_point _Tp
>
73 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
, chars_format __fmt
, int __precision
) {
74 to_chars_result __r
= std::to_chars(__first
, __last
, __value
, __fmt
, __precision
);
75 _LIBCPP_ASSERT_INTERNAL(__r
.ec
== errc(0), "Internal buffer too small");
79 // https://en.cppreference.com/w/cpp/language/types#cite_note-1
80 // float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38
81 // double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308
82 // long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932
84 // The maximum number of digits required for the integral part is based on the
85 // maximum's value power of 10. Every power of 10 requires one additional
87 // The maximum number of digits required for the fractional part is based on
88 // the minimal subnormal hexadecimal output's power of 10. Every division of a
89 // fraction's binary 1 by 2, requires one additional decimal digit.
91 // The maximum size of a formatted value depends on the selected output format.
92 // Ignoring the fact the format string can request a precision larger than the
93 // values maximum required, these values are:
97 // radix point 1 code unit
99 // exponent character 1 code unit
101 // __max_fractional_value
102 // -----------------------------------
103 // total 4 code units extra required.
105 // TODO FMT Optimize the storage to avoid storing digits that are known to be zero.
106 // https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
108 // TODO FMT Add long double specialization when to_chars has proper long double support.
112 template <floating_point _Fp
>
113 _LIBCPP_HIDE_FROM_ABI
constexpr size_t __float_buffer_size(int __precision
) {
114 using _Traits
= __traits
<_Fp
>;
115 return 4 + _Traits::__max_integral
+ __precision
+ _Traits::__max_fractional_value
;
119 struct __traits
<float> {
120 static constexpr int __max_integral
= 38;
121 static constexpr int __max_fractional
= 149;
122 static constexpr int __max_fractional_value
= 3;
123 static constexpr size_t __stack_buffer_size
= 256;
125 static constexpr int __hex_precision_digits
= 3;
129 struct __traits
<double> {
130 static constexpr int __max_integral
= 308;
131 static constexpr int __max_fractional
= 1074;
132 static constexpr int __max_fractional_value
= 4;
133 static constexpr size_t __stack_buffer_size
= 1024;
135 static constexpr int __hex_precision_digits
= 4;
138 /// Helper class to store the conversion buffer.
140 /// Depending on the maximum size required for a value, the buffer is allocated
141 /// on the stack or the heap.
142 template <floating_point _Fp
>
143 class _LIBCPP_TEMPLATE_VIS __float_buffer
{
144 using _Traits
= __traits
<_Fp
>;
147 // TODO FMT Improve this constructor to do a better estimate.
148 // When using a scientific formatting with a precision of 6 a stack buffer
149 // will always suffice. At the moment that isn't important since floats and
150 // doubles use a stack buffer, unless the precision used in the format string
152 // When supporting long doubles the __max_integral part becomes 4932 which
153 // may be too much for some platforms. For these cases a better estimate is
155 explicit _LIBCPP_HIDE_FROM_ABI
__float_buffer(int __precision
)
156 : __precision_(__precision
!= -1 ? __precision
: _Traits::__max_fractional
) {
157 // When the precision is larger than _Traits::__max_fractional the digits in
158 // the range (_Traits::__max_fractional, precision] will contain the value
159 // zero. There's no need to request to_chars to write these zeros:
160 // - When the value is large a temporary heap buffer needs to be allocated.
161 // - When to_chars writes the values they need to be "copied" to the output:
162 // - char: std::fill on the output iterator is faster than std::copy.
163 // - wchar_t: same argument as char, but additional std::copy won't work.
164 // The input is always a char buffer, so every char in the buffer needs
165 // to be converted from a char to a wchar_t.
166 if (__precision_
> _Traits::__max_fractional
) {
167 __num_trailing_zeros_
= __precision_
- _Traits::__max_fractional
;
168 __precision_
= _Traits::__max_fractional
;
171 __size_
= __formatter::__float_buffer_size
<_Fp
>(__precision_
);
172 if (__size_
> _Traits::__stack_buffer_size
)
173 // The allocated buffer's contents don't need initialization.
174 __begin_
= allocator
<char>{}.allocate(__size_
);
176 __begin_
= __buffer_
;
179 _LIBCPP_HIDE_FROM_ABI
~__float_buffer() {
180 if (__size_
> _Traits::__stack_buffer_size
)
181 allocator
<char>{}.deallocate(__begin_
, __size_
);
183 _LIBCPP_HIDE_FROM_ABI
__float_buffer(const __float_buffer
&) = delete;
184 _LIBCPP_HIDE_FROM_ABI __float_buffer
& operator=(const __float_buffer
&) = delete;
186 _LIBCPP_HIDE_FROM_ABI
char* begin() const { return __begin_
; }
187 _LIBCPP_HIDE_FROM_ABI
char* end() const { return __begin_
+ __size_
; }
189 _LIBCPP_HIDE_FROM_ABI
int __precision() const { return __precision_
; }
190 _LIBCPP_HIDE_FROM_ABI
int __num_trailing_zeros() const { return __num_trailing_zeros_
; }
191 _LIBCPP_HIDE_FROM_ABI
void __remove_trailing_zeros() { __num_trailing_zeros_
= 0; }
192 _LIBCPP_HIDE_FROM_ABI
void __add_trailing_zeros(int __zeros
) { __num_trailing_zeros_
+= __zeros
; }
196 int __num_trailing_zeros_
{0};
199 char __buffer_
[_Traits::__stack_buffer_size
];
202 struct __float_result
{
203 /// Points at the beginning of the integral part in the buffer.
205 /// When there's no sign character this points at the start of the buffer.
208 /// Points at the radix point, when not present it's the same as \ref __last.
211 /// Points at the exponent character, when not present it's the same as \ref __last.
214 /// Points beyond the last written element in the buffer.
218 /// Finds the position of the exponent character 'e' at the end of the buffer.
220 /// Assuming there is an exponent the input will terminate with
221 /// eSdd and eSdddd (S = sign, d = digit)
223 /// \returns a pointer to the exponent or __last when not found.
224 constexpr inline _LIBCPP_HIDE_FROM_ABI
char* __find_exponent(char* __first
, char* __last
) {
225 ptrdiff_t __size
= __last
- __first
;
227 __first
= __last
- std::min(__size
, ptrdiff_t(6));
228 for (; __first
!= __last
- 3; ++__first
) {
236 template <class _Fp
, class _Tp
>
237 _LIBCPP_HIDE_FROM_ABI __float_result
238 __format_buffer_default(const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, char* __integral
) {
239 __float_result __result
;
240 __result
.__integral
= __integral
;
241 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
);
243 __result
.__exponent
= __formatter::__find_exponent(__result
.__integral
, __result
.__last
);
246 // - There's at least one decimal digit before the radix point.
247 // - The radix point, when present, is placed before the exponent.
248 __result
.__radix_point
= std::find(__result
.__integral
+ 1, __result
.__exponent
, '.');
250 // When the radix point isn't found its position is the exponent instead of
252 if (__result
.__radix_point
== __result
.__exponent
)
253 __result
.__radix_point
= __result
.__last
;
256 _LIBCPP_ASSERT_INTERNAL((__result
.__integral
!= __result
.__last
) &&
257 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
258 (__result
.__exponent
== __result
.__last
|| *__result
.__exponent
== 'e'),
259 "Post-condition failure.");
265 template <class _Fp
, class _Tp
>
266 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_hexadecimal_lower_case(
267 const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
268 __float_result __result
;
269 __result
.__integral
= __integral
;
270 if (__precision
== -1)
271 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::hex
);
273 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::hex
, __precision
);
275 // H = one or more hex-digits
277 // D = one or more decimal-digits
278 // When the fractional part is zero and no precision the output is 0p+0
279 // else the output is 0.HpSD
280 // So testing the second position can differentiate between these two cases.
281 char* __first
= __integral
+ 1;
282 if (*__first
== '.') {
283 __result
.__radix_point
= __first
;
284 // One digit is the minimum
287 // ^---- integral = end of search
288 // ^-------- start of search
291 // Four digits is the maximum
294 // ^---- integral = end of search
295 // ^-------- start of search
297 static_assert(__traits
<_Fp
>::__hex_precision_digits
<= 4, "Guard against possible underflow.");
299 char* __last
= __result
.__last
- 2;
300 __first
= __last
- __traits
<_Fp
>::__hex_precision_digits
;
301 __result
.__exponent
= std::find(__first
, __last
, 'p');
303 __result
.__radix_point
= __result
.__last
;
304 __result
.__exponent
= __first
;
308 _LIBCPP_ASSERT_INTERNAL((__result
.__integral
!= __result
.__last
) &&
309 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
310 (__result
.__exponent
!= __result
.__last
&& *__result
.__exponent
== 'p'),
311 "Post-condition failure.");
317 template <class _Fp
, class _Tp
>
318 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_hexadecimal_upper_case(
319 const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
320 __float_result __result
=
321 __formatter::__format_buffer_hexadecimal_lower_case(__buffer
, __value
, __precision
, __integral
);
322 std::transform(__result
.__integral
, __result
.__exponent
, __result
.__integral
, __hex_to_upper
);
323 *__result
.__exponent
= 'P';
327 template <class _Fp
, class _Tp
>
328 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_scientific_lower_case(
329 const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
330 __float_result __result
;
331 __result
.__integral
= __integral
;
333 __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::scientific
, __precision
);
335 char* __first
= __integral
+ 1;
336 _LIBCPP_ASSERT_INTERNAL(__first
!= __result
.__last
, "No exponent present");
337 if (*__first
== '.') {
338 __result
.__radix_point
= __first
;
339 __result
.__exponent
= __formatter::__find_exponent(__first
+ 1, __result
.__last
);
341 __result
.__radix_point
= __result
.__last
;
342 __result
.__exponent
= __first
;
346 _LIBCPP_ASSERT_INTERNAL((__result
.__integral
!= __result
.__last
) &&
347 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
348 (__result
.__exponent
!= __result
.__last
&& *__result
.__exponent
== 'e'),
349 "Post-condition failure.");
354 template <class _Fp
, class _Tp
>
355 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_scientific_upper_case(
356 const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
357 __float_result __result
=
358 __formatter::__format_buffer_scientific_lower_case(__buffer
, __value
, __precision
, __integral
);
359 *__result
.__exponent
= 'E';
363 template <class _Fp
, class _Tp
>
364 _LIBCPP_HIDE_FROM_ABI __float_result
365 __format_buffer_fixed(const __float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
366 __float_result __result
;
367 __result
.__integral
= __integral
;
368 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::fixed
, __precision
);
370 // When there's no precision there's no radix point.
371 // Else the radix point is placed at __precision + 1 from the end.
372 // By converting __precision to a bool the subtraction can be done
374 __result
.__radix_point
= __result
.__last
- (__precision
+ bool(__precision
));
375 __result
.__exponent
= __result
.__last
;
378 _LIBCPP_ASSERT_INTERNAL((__result
.__integral
!= __result
.__last
) &&
379 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
380 (__result
.__exponent
== __result
.__last
),
381 "Post-condition failure.");
386 template <class _Fp
, class _Tp
>
387 _LIBCPP_HIDE_FROM_ABI __float_result
388 __format_buffer_general_lower_case(__float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
389 __buffer
.__remove_trailing_zeros();
391 __float_result __result
;
392 __result
.__integral
= __integral
;
393 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::general
, __precision
);
395 char* __first
= __integral
+ 1;
396 if (__first
== __result
.__last
) {
397 __result
.__radix_point
= __result
.__last
;
398 __result
.__exponent
= __result
.__last
;
400 __result
.__exponent
= __formatter::__find_exponent(__first
, __result
.__last
);
401 if (__result
.__exponent
!= __result
.__last
)
402 // In scientific mode if there's a radix point it will always be after
403 // the first digit. (This is the position __first points at).
404 __result
.__radix_point
= *__first
== '.' ? __first
: __result
.__last
;
406 // In fixed mode the algorithm truncates trailing spaces and possibly the
407 // radix point. There's no good guess for the position of the radix point
408 // therefore scan the output after the first digit.
409 __result
.__radix_point
= std::find(__first
, __result
.__last
, '.');
414 _LIBCPP_ASSERT_INTERNAL((__result
.__integral
!= __result
.__last
) &&
415 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
416 (__result
.__exponent
== __result
.__last
|| *__result
.__exponent
== 'e'),
417 "Post-condition failure.");
423 template <class _Fp
, class _Tp
>
424 _LIBCPP_HIDE_FROM_ABI __float_result
425 __format_buffer_general_upper_case(__float_buffer
<_Fp
>& __buffer
, _Tp __value
, int __precision
, char* __integral
) {
426 __float_result __result
= __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __precision
, __integral
);
427 if (__result
.__exponent
!= __result
.__last
)
428 *__result
.__exponent
= 'E';
432 /// Fills the buffer with the data based on the requested formatting.
434 /// This function, when needed, turns the characters to upper case and
435 /// determines the "interesting" locations which are returned to the caller.
437 /// This means the caller never has to convert the contents of the buffer to
438 /// upper case or search for radix points and the location of the exponent.
439 /// This gives a bit of overhead. The original code didn't do that, but due
440 /// to the number of possible additional work needed to turn this number to
441 /// the proper output the code was littered with tests for upper cases and
442 /// searches for radix points and exponents.
443 /// - When a precision larger than the type's precision is selected
444 /// additional zero characters need to be written before the exponent.
445 /// - alternate form needs to add a radix point when not present.
446 /// - localization needs to do grouping in the integral part.
447 template <class _Fp
, class _Tp
>
448 // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
449 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer(
450 __float_buffer
<_Fp
>& __buffer
,
453 bool __has_precision
,
454 __format_spec::__sign __sign
,
455 __format_spec::__type __type
) {
456 char* __first
= __formatter::__insert_sign(__buffer
.begin(), __negative
, __sign
);
458 case __format_spec::__type::__default
:
460 return __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
462 return __formatter::__format_buffer_default(__buffer
, __value
, __first
);
464 case __format_spec::__type::__hexfloat_lower_case
:
465 return __formatter::__format_buffer_hexadecimal_lower_case(
466 __buffer
, __value
, __has_precision
? __buffer
.__precision() : -1, __first
);
468 case __format_spec::__type::__hexfloat_upper_case
:
469 return __formatter::__format_buffer_hexadecimal_upper_case(
470 __buffer
, __value
, __has_precision
? __buffer
.__precision() : -1, __first
);
472 case __format_spec::__type::__scientific_lower_case
:
473 return __formatter::__format_buffer_scientific_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
475 case __format_spec::__type::__scientific_upper_case
:
476 return __formatter::__format_buffer_scientific_upper_case(__buffer
, __value
, __buffer
.__precision(), __first
);
478 case __format_spec::__type::__fixed_lower_case
:
479 case __format_spec::__type::__fixed_upper_case
:
480 return __formatter::__format_buffer_fixed(__buffer
, __value
, __buffer
.__precision(), __first
);
482 case __format_spec::__type::__general_lower_case
:
483 return __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
485 case __format_spec::__type::__general_upper_case
:
486 return __formatter::__format_buffer_general_upper_case(__buffer
, __value
, __buffer
.__precision(), __first
);
489 _LIBCPP_ASSERT_INTERNAL(false, "The parser should have validated the type");
490 __libcpp_unreachable();
494 # ifndef _LIBCPP_HAS_NO_LOCALIZATION
495 template <class _OutIt
, class _Fp
, class _CharT
>
496 _LIBCPP_HIDE_FROM_ABI _OutIt
__format_locale_specific_form(
498 const __float_buffer
<_Fp
>& __buffer
,
499 const __float_result
& __result
,
501 __format_spec::__parsed_specifications
<_CharT
> __specs
) {
502 const auto& __np
= std::use_facet
<numpunct
<_CharT
>>(__loc
);
503 string __grouping
= __np
.grouping();
504 char* __first
= __result
.__integral
;
505 // When no radix point or exponent are present __last will be __result.__last.
506 char* __last
= std::min(__result
.__radix_point
, __result
.__exponent
);
508 ptrdiff_t __digits
= __last
- __first
;
509 if (!__grouping
.empty()) {
510 if (__digits
<= __grouping
[0])
513 __grouping
= __formatter::__determine_grouping(__digits
, __grouping
);
517 __result
.__last
- __buffer
.begin() + // Formatted string
518 __buffer
.__num_trailing_zeros() + // Not yet rendered zeros
519 __grouping
.size() - // Grouping contains one
520 !__grouping
.empty(); // additional character
522 __formatter::__padding_size_result __padding
= {0, 0};
523 bool __zero_padding
= __specs
.__alignment_
== __format_spec::__alignment::__zero_padding
;
524 if (__size
< __specs
.__width_
) {
525 if (__zero_padding
) {
526 __specs
.__alignment_
= __format_spec::__alignment::__right
;
527 __specs
.__fill_
.__data
[0] = _CharT('0');
530 __padding
= __formatter::__padding_size(__size
, __specs
.__width_
, __specs
.__alignment_
);
533 // sign and (zero padding or alignment)
534 if (__zero_padding
&& __first
!= __buffer
.begin())
535 *__out_it
++ = *__buffer
.begin();
536 __out_it
= __formatter::__fill(std::move(__out_it
), __padding
.__before_
, __specs
.__fill_
);
537 if (!__zero_padding
&& __first
!= __buffer
.begin())
538 *__out_it
++ = *__buffer
.begin();
541 if (__grouping
.empty()) {
542 __out_it
= __formatter::__copy(__first
, __digits
, std::move(__out_it
));
544 auto __r
= __grouping
.rbegin();
545 auto __e
= __grouping
.rend() - 1;
546 _CharT __sep
= __np
.thousands_sep();
547 // The output is divided in small groups of numbers to write:
548 // - A group before the first separator.
549 // - A separator and a group, repeated for the number of separators.
550 // - A group after the last separator.
551 // This loop achieves that process by testing the termination condition
552 // midway in the loop.
554 __out_it
= __formatter::__copy(__first
, *__r
, std::move(__out_it
));
566 if (__result
.__radix_point
!= __result
.__last
) {
567 *__out_it
++ = __np
.decimal_point();
568 __out_it
= __formatter::__copy(__result
.__radix_point
+ 1, __result
.__exponent
, std::move(__out_it
));
569 __out_it
= __formatter::__fill(std::move(__out_it
), __buffer
.__num_trailing_zeros(), _CharT('0'));
573 if (__result
.__exponent
!= __result
.__last
)
574 __out_it
= __formatter::__copy(__result
.__exponent
, __result
.__last
, std::move(__out_it
));
577 return __formatter::__fill(std::move(__out_it
), __padding
.__after_
, __specs
.__fill_
);
579 # endif // _LIBCPP_HAS_NO_LOCALIZATION
581 template <class _OutIt
, class _CharT
>
582 _LIBCPP_HIDE_FROM_ABI _OutIt
__format_floating_point_non_finite(
583 _OutIt __out_it
, __format_spec::__parsed_specifications
<_CharT
> __specs
, bool __negative
, bool __isnan
) {
585 char* __last
= __formatter::__insert_sign(__buffer
, __negative
, __specs
.__std_
.__sign_
);
587 // to_chars can return inf, infinity, nan, and nan(n-char-sequence).
588 // The format library requires inf and nan.
589 // All in one expression to avoid dangling references.
591 __specs
.__std_
.__type_
== __format_spec::__type::__hexfloat_upper_case
||
592 __specs
.__std_
.__type_
== __format_spec::__type::__scientific_upper_case
||
593 __specs
.__std_
.__type_
== __format_spec::__type::__fixed_upper_case
||
594 __specs
.__std_
.__type_
== __format_spec::__type::__general_upper_case
;
595 __last
= std::copy_n(&("infnanINFNAN"[6 * __upper_case
+ 3 * __isnan
]), 3, __last
);
597 // [format.string.std]/13
598 // A zero (0) character preceding the width field pads the field with
599 // leading zeros (following any indication of sign or base) to the field
600 // width, except when applied to an infinity or NaN.
601 if (__specs
.__alignment_
== __format_spec::__alignment::__zero_padding
)
602 __specs
.__alignment_
= __format_spec::__alignment::__right
;
604 return __formatter::__write(__buffer
, __last
, std::move(__out_it
), __specs
);
607 /// Writes additional zero's for the precision before the exponent.
608 /// This is used when the precision requested in the format string is larger
609 /// than the maximum precision of the floating-point type. These precision
610 /// digits are always 0.
612 /// \param __exponent The location of the exponent character.
613 /// \param __num_trailing_zeros The number of 0's to write before the exponent
615 template <class _CharT
, class _ParserCharT
>
616 _LIBCPP_HIDE_FROM_ABI
auto __write_using_trailing_zeros(
617 const _CharT
* __first
,
618 const _CharT
* __last
,
619 output_iterator
<const _CharT
&> auto __out_it
,
620 __format_spec::__parsed_specifications
<_ParserCharT
> __specs
,
622 const _CharT
* __exponent
,
623 size_t __num_trailing_zeros
) -> decltype(__out_it
) {
624 _LIBCPP_ASSERT_INTERNAL(__first
<= __last
, "Not a valid range");
625 _LIBCPP_ASSERT_INTERNAL(__num_trailing_zeros
> 0, "The overload not writing trailing zeros should have been used");
627 __padding_size_result __padding
=
628 __formatter::__padding_size(__size
+ __num_trailing_zeros
, __specs
.__width_
, __specs
.__alignment_
);
629 __out_it
= __formatter::__fill(std::move(__out_it
), __padding
.__before_
, __specs
.__fill_
);
630 __out_it
= __formatter::__copy(__first
, __exponent
, std::move(__out_it
));
631 __out_it
= __formatter::__fill(std::move(__out_it
), __num_trailing_zeros
, _CharT('0'));
632 __out_it
= __formatter::__copy(__exponent
, __last
, std::move(__out_it
));
633 return __formatter::__fill(std::move(__out_it
), __padding
.__after_
, __specs
.__fill_
);
636 template <floating_point _Tp
, class _CharT
, class _FormatContext
>
637 _LIBCPP_HIDE_FROM_ABI typename
_FormatContext::iterator
638 __format_floating_point(_Tp __value
, _FormatContext
& __ctx
, __format_spec::__parsed_specifications
<_CharT
> __specs
) {
639 bool __negative
= std::signbit(__value
);
641 if (!std::isfinite(__value
)) [[unlikely
]]
642 return __formatter::__format_floating_point_non_finite(__ctx
.out(), __specs
, __negative
, std::isnan(__value
));
644 // Depending on the std-format-spec string the sign and the value
645 // might not be outputted together:
646 // - zero-padding may insert additional '0' characters.
647 // Therefore the value is processed as a non negative value.
648 // The function @ref __insert_sign will insert a '-' when the value was
654 // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
655 using _Fp
= conditional_t
<same_as
<_Tp
, long double>, double, _Tp
>;
656 // Force the type of the precision to avoid -1 to become an unsigned value.
657 __float_buffer
<_Fp
> __buffer(__specs
.__precision_
);
658 __float_result __result
= __formatter::__format_buffer(
659 __buffer
, __value
, __negative
, (__specs
.__has_precision()), __specs
.__std_
.__sign_
, __specs
.__std_
.__type_
);
661 if (__specs
.__std_
.__alternate_form_
) {
662 if (__result
.__radix_point
== __result
.__last
) {
663 *__result
.__last
++ = '.';
665 // When there is an exponent the point needs to be moved before the
666 // exponent. When there's no exponent the rotate does nothing. Since
667 // rotate tests whether the operation is a nop, call it unconditionally.
668 std::rotate(__result
.__exponent
, __result
.__last
- 1, __result
.__last
);
669 __result
.__radix_point
= __result
.__exponent
;
671 // The radix point is always placed before the exponent.
672 // - No exponent needs to point to the new last.
673 // - An exponent needs to move one position to the right.
674 // So it's safe to increment the value unconditionally.
675 ++__result
.__exponent
;
678 // [format.string.std]/6
679 // In addition, for g and G conversions, trailing zeros are not removed
682 // If the type option for a floating-point type is none it may use the
683 // general formatting, but it's not a g or G conversion. So in that case
684 // the formatting should not append trailing zeros.
685 bool __is_general
= __specs
.__std_
.__type_
== __format_spec::__type::__general_lower_case
||
686 __specs
.__std_
.__type_
== __format_spec::__type::__general_upper_case
;
689 // https://en.cppreference.com/w/c/io/fprintf
690 // Let P equal the precision if nonzero, 6 if the precision is not
691 // specified, or 1 if the precision is 0. Then, if a conversion with
692 // style E would have an exponent of X:
693 int __p
= std::max
<int>(1, (__specs
.__has_precision() ? __specs
.__precision_
: 6));
694 if (__result
.__exponent
== __result
.__last
)
695 // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X.
696 // By including the radix point it calculates P - (1 + X)
697 __p
-= __result
.__radix_point
- __result
.__integral
;
699 // otherwise, the conversion is with style e or E and precision P - 1.
702 ptrdiff_t __precision
= (__result
.__exponent
- __result
.__radix_point
) - 1;
703 if (__precision
< __p
)
704 __buffer
.__add_trailing_zeros(__p
- __precision
);
708 # ifndef _LIBCPP_HAS_NO_LOCALIZATION
709 if (__specs
.__std_
.__locale_specific_form_
)
710 return __formatter::__format_locale_specific_form(__ctx
.out(), __buffer
, __result
, __ctx
.locale(), __specs
);
713 ptrdiff_t __size
= __result
.__last
- __buffer
.begin();
714 int __num_trailing_zeros
= __buffer
.__num_trailing_zeros();
715 if (__size
+ __num_trailing_zeros
>= __specs
.__width_
) {
716 if (__num_trailing_zeros
&& __result
.__exponent
!= __result
.__last
)
717 // Insert trailing zeros before exponent character.
718 return __formatter::__copy(
721 __formatter::__fill(__formatter::__copy(__buffer
.begin(), __result
.__exponent
, __ctx
.out()),
722 __num_trailing_zeros
,
725 return __formatter::__fill(
726 __formatter::__copy(__buffer
.begin(), __result
.__last
, __ctx
.out()), __num_trailing_zeros
, _CharT('0'));
729 auto __out_it
= __ctx
.out();
730 char* __first
= __buffer
.begin();
731 if (__specs
.__alignment_
== __format_spec::__alignment ::__zero_padding
) {
732 // When there is a sign output it before the padding. Note the __size
733 // doesn't need any adjustment, regardless whether the sign is written
734 // here or in __formatter::__write.
735 if (__first
!= __result
.__integral
)
736 *__out_it
++ = *__first
++;
737 // After the sign is written, zero padding is the same a right alignment
739 __specs
.__alignment_
= __format_spec::__alignment::__right
;
740 __specs
.__fill_
.__data
[0] = _CharT('0');
743 if (__num_trailing_zeros
)
744 return __formatter::__write_using_trailing_zeros(
745 __first
, __result
.__last
, std::move(__out_it
), __specs
, __size
, __result
.__exponent
, __num_trailing_zeros
);
747 return __formatter::__write(__first
, __result
.__last
, std::move(__out_it
), __specs
, __size
);
750 } // namespace __formatter
752 template <__fmt_char_type _CharT
>
753 struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point
{
755 template <class _ParseContext
>
756 _LIBCPP_HIDE_FROM_ABI
constexpr typename
_ParseContext::iterator
parse(_ParseContext
& __ctx
) {
757 typename
_ParseContext::iterator __result
= __parser_
.__parse(__ctx
, __format_spec::__fields_floating_point
);
758 __format_spec::__process_parsed_floating_point(__parser_
, "a floating-point");
762 template <floating_point _Tp
, class _FormatContext
>
763 _LIBCPP_HIDE_FROM_ABI typename
_FormatContext::iterator
format(_Tp __value
, _FormatContext
& __ctx
) const {
764 return __formatter::__format_floating_point(__value
, __ctx
, __parser_
.__get_parsed_std_specifications(__ctx
));
767 __format_spec::__parser
<_CharT
> __parser_
;
770 template <__fmt_char_type _CharT
>
771 struct _LIBCPP_TEMPLATE_VIS formatter
<float, _CharT
> : public __formatter_floating_point
<_CharT
> {};
772 template <__fmt_char_type _CharT
>
773 struct _LIBCPP_TEMPLATE_VIS formatter
<double, _CharT
> : public __formatter_floating_point
<_CharT
> {};
774 template <__fmt_char_type _CharT
>
775 struct _LIBCPP_TEMPLATE_VIS formatter
<long double, _CharT
> : public __formatter_floating_point
<_CharT
> {};
777 #endif //_LIBCPP_STD_VER >= 20
779 _LIBCPP_END_NAMESPACE_STD
783 #endif // _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H