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___FORMAT_FORMATTER_FLOATING_POINT_H
11 #define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H
13 #include <__algorithm/copy_n.h>
14 #include <__algorithm/find.h>
15 #include <__algorithm/max.h>
16 #include <__algorithm/min.h>
17 #include <__algorithm/rotate.h>
18 #include <__algorithm/transform.h>
19 #include <__charconv/chars_format.h>
20 #include <__charconv/to_chars_floating_point.h>
21 #include <__charconv/to_chars_result.h>
22 #include <__concepts/arithmetic.h>
23 #include <__concepts/same_as.h>
25 #include <__format/concepts.h>
26 #include <__format/format_parse_context.h>
27 #include <__format/formatter.h>
28 #include <__format/formatter_integral.h>
29 #include <__format/formatter_output.h>
30 #include <__format/parser_std_format_spec.h>
31 #include <__iterator/concepts.h>
32 #include <__memory/allocator.h>
33 #include <__system_error/errc.h>
34 #include <__type_traits/conditional.h>
35 #include <__utility/move.h>
36 #include <__utility/unreachable.h>
40 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
44 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
45 # pragma GCC system_header
49 #include <__undef_macros>
51 _LIBCPP_BEGIN_NAMESPACE_STD
53 #if _LIBCPP_STD_VER >= 20
55 namespace __formatter
{
57 template <floating_point _Tp
>
58 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
) {
59 to_chars_result __r
= _VSTD::to_chars(__first
, __last
, __value
);
60 _LIBCPP_ASSERT_UNCATEGORIZED(__r
.ec
== errc(0), "Internal buffer too small");
64 template <floating_point _Tp
>
65 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
, chars_format __fmt
) {
66 to_chars_result __r
= _VSTD::to_chars(__first
, __last
, __value
, __fmt
);
67 _LIBCPP_ASSERT_UNCATEGORIZED(__r
.ec
== errc(0), "Internal buffer too small");
71 template <floating_point _Tp
>
72 _LIBCPP_HIDE_FROM_ABI
char* __to_buffer(char* __first
, char* __last
, _Tp __value
, chars_format __fmt
, int __precision
) {
73 to_chars_result __r
= _VSTD::to_chars(__first
, __last
, __value
, __fmt
, __precision
);
74 _LIBCPP_ASSERT_UNCATEGORIZED(__r
.ec
== errc(0), "Internal buffer too small");
78 // https://en.cppreference.com/w/cpp/language/types#cite_note-1
79 // float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38
80 // double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308
81 // long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932
83 // The maximum number of digits required for the integral part is based on the
84 // maximum's value power of 10. Every power of 10 requires one additional
86 // The maximum number of digits required for the fractional part is based on
87 // the minimal subnormal hexadecimal output's power of 10. Every division of a
88 // fraction's binary 1 by 2, requires one additional decimal digit.
90 // The maximum size of a formatted value depends on the selected output format.
91 // Ignoring the fact the format string can request a precision larger than the
92 // values maximum required, these values are:
96 // radix point 1 code unit
98 // exponent character 1 code unit
100 // __max_fractional_value
101 // -----------------------------------
102 // total 4 code units extra required.
104 // TODO FMT Optimize the storage to avoid storing digits that are known to be zero.
105 // https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
107 // TODO FMT Add long double specialization when to_chars has proper long double support.
111 template <floating_point _Fp
>
112 _LIBCPP_HIDE_FROM_ABI
constexpr size_t __float_buffer_size(int __precision
) {
113 using _Traits
= __traits
<_Fp
>;
114 return 4 + _Traits::__max_integral
+ __precision
+ _Traits::__max_fractional_value
;
118 struct __traits
<float> {
119 static constexpr int __max_integral
= 38;
120 static constexpr int __max_fractional
= 149;
121 static constexpr int __max_fractional_value
= 3;
122 static constexpr size_t __stack_buffer_size
= 256;
124 static constexpr int __hex_precision_digits
= 3;
128 struct __traits
<double> {
129 static constexpr int __max_integral
= 308;
130 static constexpr int __max_fractional
= 1074;
131 static constexpr int __max_fractional_value
= 4;
132 static constexpr size_t __stack_buffer_size
= 1024;
134 static constexpr int __hex_precision_digits
= 4;
137 /// Helper class to store the conversion buffer.
139 /// Depending on the maximum size required for a value, the buffer is allocated
140 /// on the stack or the heap.
141 template <floating_point _Fp
>
142 class _LIBCPP_TEMPLATE_VIS __float_buffer
{
143 using _Traits
= __traits
<_Fp
>;
146 // TODO FMT Improve this constructor to do a better estimate.
147 // When using a scientific formatting with a precision of 6 a stack buffer
148 // will always suffice. At the moment that isn't important since floats and
149 // doubles use a stack buffer, unless the precision used in the format string
151 // When supporting long doubles the __max_integral part becomes 4932 which
152 // may be too much for some platforms. For these cases a better estimate is
154 explicit _LIBCPP_HIDE_FROM_ABI
__float_buffer(int __precision
)
155 : __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
- _VSTD::min(__size
, ptrdiff_t(6));
228 for (; __first
!= __last
- 3; ++__first
) {
236 template <class _Fp
, class _Tp
>
237 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_default(const __float_buffer
<_Fp
>& __buffer
, _Tp __value
,
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
= _VSTD::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_UNCATEGORIZED((__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(const __float_buffer
<_Fp
>& __buffer
,
267 _Tp __value
, int __precision
,
269 __float_result __result
;
270 __result
.__integral
= __integral
;
271 if (__precision
== -1)
272 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::hex
);
274 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::hex
, __precision
);
276 // H = one or more hex-digits
278 // D = one or more decimal-digits
279 // When the fractional part is zero and no precision the output is 0p+0
280 // else the output is 0.HpSD
281 // So testing the second position can differentiate between these two cases.
282 char* __first
= __integral
+ 1;
283 if (*__first
== '.') {
284 __result
.__radix_point
= __first
;
285 // One digit is the minimum
288 // ^---- integral = end of search
289 // ^-------- start of search
292 // Four digits is the maximum
295 // ^---- integral = end of search
296 // ^-------- start of search
298 static_assert(__traits
<_Fp
>::__hex_precision_digits
<= 4, "Guard against possible underflow.");
300 char* __last
= __result
.__last
- 2;
301 __first
= __last
- __traits
<_Fp
>::__hex_precision_digits
;
302 __result
.__exponent
= _VSTD::find(__first
, __last
, 'p');
304 __result
.__radix_point
= __result
.__last
;
305 __result
.__exponent
= __first
;
309 _LIBCPP_ASSERT_UNCATEGORIZED((__result
.__integral
!= __result
.__last
) &&
310 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
311 (__result
.__exponent
!= __result
.__last
&& *__result
.__exponent
== 'p'),
312 "Post-condition failure.");
318 template <class _Fp
, class _Tp
>
319 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_hexadecimal_upper_case(const __float_buffer
<_Fp
>& __buffer
,
320 _Tp __value
, int __precision
,
322 __float_result __result
=
323 __formatter::__format_buffer_hexadecimal_lower_case(__buffer
, __value
, __precision
, __integral
);
324 _VSTD::transform(__result
.__integral
, __result
.__exponent
, __result
.__integral
, __hex_to_upper
);
325 *__result
.__exponent
= 'P';
329 template <class _Fp
, class _Tp
>
330 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_scientific_lower_case(const __float_buffer
<_Fp
>& __buffer
,
331 _Tp __value
, int __precision
,
333 __float_result __result
;
334 __result
.__integral
= __integral
;
336 __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::scientific
, __precision
);
338 char* __first
= __integral
+ 1;
339 _LIBCPP_ASSERT_UNCATEGORIZED(__first
!= __result
.__last
, "No exponent present");
340 if (*__first
== '.') {
341 __result
.__radix_point
= __first
;
342 __result
.__exponent
= __formatter::__find_exponent(__first
+ 1, __result
.__last
);
344 __result
.__radix_point
= __result
.__last
;
345 __result
.__exponent
= __first
;
349 _LIBCPP_ASSERT_UNCATEGORIZED((__result
.__integral
!= __result
.__last
) &&
350 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
351 (__result
.__exponent
!= __result
.__last
&& *__result
.__exponent
== 'e'),
352 "Post-condition failure.");
357 template <class _Fp
, class _Tp
>
358 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_scientific_upper_case(const __float_buffer
<_Fp
>& __buffer
,
359 _Tp __value
, int __precision
,
361 __float_result __result
=
362 __formatter::__format_buffer_scientific_lower_case(__buffer
, __value
, __precision
, __integral
);
363 *__result
.__exponent
= 'E';
367 template <class _Fp
, class _Tp
>
368 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_fixed(const __float_buffer
<_Fp
>& __buffer
, _Tp __value
,
369 int __precision
, char* __integral
) {
370 __float_result __result
;
371 __result
.__integral
= __integral
;
372 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::fixed
, __precision
);
374 // When there's no precision there's no radix point.
375 // Else the radix point is placed at __precision + 1 from the end.
376 // By converting __precision to a bool the subtraction can be done
378 __result
.__radix_point
= __result
.__last
- (__precision
+ bool(__precision
));
379 __result
.__exponent
= __result
.__last
;
382 _LIBCPP_ASSERT_UNCATEGORIZED((__result
.__integral
!= __result
.__last
) &&
383 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
384 (__result
.__exponent
== __result
.__last
),
385 "Post-condition failure.");
390 template <class _Fp
, class _Tp
>
391 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_general_lower_case(__float_buffer
<_Fp
>& __buffer
, _Tp __value
,
392 int __precision
, char* __integral
) {
394 __buffer
.__remove_trailing_zeros();
396 __float_result __result
;
397 __result
.__integral
= __integral
;
398 __result
.__last
= __formatter::__to_buffer(__integral
, __buffer
.end(), __value
, chars_format::general
, __precision
);
400 char* __first
= __integral
+ 1;
401 if (__first
== __result
.__last
) {
402 __result
.__radix_point
= __result
.__last
;
403 __result
.__exponent
= __result
.__last
;
405 __result
.__exponent
= __formatter::__find_exponent(__first
, __result
.__last
);
406 if (__result
.__exponent
!= __result
.__last
)
407 // In scientific mode if there's a radix point it will always be after
408 // the first digit. (This is the position __first points at).
409 __result
.__radix_point
= *__first
== '.' ? __first
: __result
.__last
;
411 // In fixed mode the algorithm truncates trailing spaces and possibly the
412 // radix point. There's no good guess for the position of the radix point
413 // therefore scan the output after the first digit.
414 __result
.__radix_point
= _VSTD::find(__first
, __result
.__last
, '.');
419 _LIBCPP_ASSERT_UNCATEGORIZED((__result
.__integral
!= __result
.__last
) &&
420 (__result
.__radix_point
== __result
.__last
|| *__result
.__radix_point
== '.') &&
421 (__result
.__exponent
== __result
.__last
|| *__result
.__exponent
== 'e'),
422 "Post-condition failure.");
428 template <class _Fp
, class _Tp
>
429 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer_general_upper_case(__float_buffer
<_Fp
>& __buffer
, _Tp __value
,
430 int __precision
, char* __integral
) {
431 __float_result __result
= __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __precision
, __integral
);
432 if (__result
.__exponent
!= __result
.__last
)
433 *__result
.__exponent
= 'E';
437 /// Fills the buffer with the data based on the requested formatting.
439 /// This function, when needed, turns the characters to upper case and
440 /// determines the "interesting" locations which are returned to the caller.
442 /// This means the caller never has to convert the contents of the buffer to
443 /// upper case or search for radix points and the location of the exponent.
444 /// This gives a bit of overhead. The original code didn't do that, but due
445 /// to the number of possible additional work needed to turn this number to
446 /// the proper output the code was littered with tests for upper cases and
447 /// searches for radix points and exponents.
448 /// - When a precision larger than the type's precision is selected
449 /// additional zero characters need to be written before the exponent.
450 /// - alternate form needs to add a radix point when not present.
451 /// - localization needs to do grouping in the integral part.
452 template <class _Fp
, class _Tp
>
453 // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
454 _LIBCPP_HIDE_FROM_ABI __float_result
__format_buffer(
455 __float_buffer
<_Fp
>& __buffer
,
458 bool __has_precision
,
459 __format_spec::__sign __sign
,
460 __format_spec::__type __type
) {
461 char* __first
= __formatter::__insert_sign(__buffer
.begin(), __negative
, __sign
);
463 case __format_spec::__type::__default
:
465 return __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
467 return __formatter::__format_buffer_default(__buffer
, __value
, __first
);
469 case __format_spec::__type::__hexfloat_lower_case
:
470 return __formatter::__format_buffer_hexadecimal_lower_case(
471 __buffer
, __value
, __has_precision
? __buffer
.__precision() : -1, __first
);
473 case __format_spec::__type::__hexfloat_upper_case
:
474 return __formatter::__format_buffer_hexadecimal_upper_case(
475 __buffer
, __value
, __has_precision
? __buffer
.__precision() : -1, __first
);
477 case __format_spec::__type::__scientific_lower_case
:
478 return __formatter::__format_buffer_scientific_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
480 case __format_spec::__type::__scientific_upper_case
:
481 return __formatter::__format_buffer_scientific_upper_case(__buffer
, __value
, __buffer
.__precision(), __first
);
483 case __format_spec::__type::__fixed_lower_case
:
484 case __format_spec::__type::__fixed_upper_case
:
485 return __formatter::__format_buffer_fixed(__buffer
, __value
, __buffer
.__precision(), __first
);
487 case __format_spec::__type::__general_lower_case
:
488 return __formatter::__format_buffer_general_lower_case(__buffer
, __value
, __buffer
.__precision(), __first
);
490 case __format_spec::__type::__general_upper_case
:
491 return __formatter::__format_buffer_general_upper_case(__buffer
, __value
, __buffer
.__precision(), __first
);
494 _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parser should have validated the type");
495 __libcpp_unreachable();
499 # ifndef _LIBCPP_HAS_NO_LOCALIZATION
500 template <class _OutIt
, class _Fp
, class _CharT
>
501 _LIBCPP_HIDE_FROM_ABI _OutIt
__format_locale_specific_form(
503 const __float_buffer
<_Fp
>& __buffer
,
504 const __float_result
& __result
,
506 __format_spec::__parsed_specifications
<_CharT
> __specs
) {
507 const auto& __np
= std::use_facet
<numpunct
<_CharT
>>(__loc
);
508 string __grouping
= __np
.grouping();
509 char* __first
= __result
.__integral
;
510 // When no radix point or exponent are present __last will be __result.__last.
511 char* __last
= _VSTD::min(__result
.__radix_point
, __result
.__exponent
);
513 ptrdiff_t __digits
= __last
- __first
;
514 if (!__grouping
.empty()) {
515 if (__digits
<= __grouping
[0])
518 __grouping
= __formatter::__determine_grouping(__digits
, __grouping
);
522 __result
.__last
- __buffer
.begin() + // Formatted string
523 __buffer
.__num_trailing_zeros() + // Not yet rendered zeros
524 __grouping
.size() - // Grouping contains one
525 !__grouping
.empty(); // additional character
527 __formatter::__padding_size_result __padding
= {0, 0};
528 bool __zero_padding
= __specs
.__alignment_
== __format_spec::__alignment::__zero_padding
;
529 if (__size
< __specs
.__width_
) {
530 if (__zero_padding
) {
531 __specs
.__alignment_
= __format_spec::__alignment::__right
;
532 __specs
.__fill_
.__data
[0] = _CharT('0');
535 __padding
= __formatter::__padding_size(__size
, __specs
.__width_
, __specs
.__alignment_
);
538 // sign and (zero padding or alignment)
539 if (__zero_padding
&& __first
!= __buffer
.begin())
540 *__out_it
++ = *__buffer
.begin();
541 __out_it
= __formatter::__fill(_VSTD::move(__out_it
), __padding
.__before_
, __specs
.__fill_
);
542 if (!__zero_padding
&& __first
!= __buffer
.begin())
543 *__out_it
++ = *__buffer
.begin();
546 if (__grouping
.empty()) {
547 __out_it
= __formatter::__copy(__first
, __digits
, _VSTD::move(__out_it
));
549 auto __r
= __grouping
.rbegin();
550 auto __e
= __grouping
.rend() - 1;
551 _CharT __sep
= __np
.thousands_sep();
552 // The output is divided in small groups of numbers to write:
553 // - A group before the first separator.
554 // - A separator and a group, repeated for the number of separators.
555 // - A group after the last separator.
556 // This loop achieves that process by testing the termination condition
557 // midway in the loop.
559 __out_it
= __formatter::__copy(__first
, *__r
, _VSTD::move(__out_it
));
571 if (__result
.__radix_point
!= __result
.__last
) {
572 *__out_it
++ = __np
.decimal_point();
573 __out_it
= __formatter::__copy(__result
.__radix_point
+ 1, __result
.__exponent
, _VSTD::move(__out_it
));
574 __out_it
= __formatter::__fill(_VSTD::move(__out_it
), __buffer
.__num_trailing_zeros(), _CharT('0'));
578 if (__result
.__exponent
!= __result
.__last
)
579 __out_it
= __formatter::__copy(__result
.__exponent
, __result
.__last
, _VSTD::move(__out_it
));
582 return __formatter::__fill(_VSTD::move(__out_it
), __padding
.__after_
, __specs
.__fill_
);
584 # endif // _LIBCPP_HAS_NO_LOCALIZATION
586 template <class _OutIt
, class _CharT
>
587 _LIBCPP_HIDE_FROM_ABI _OutIt
__format_floating_point_non_finite(
588 _OutIt __out_it
, __format_spec::__parsed_specifications
<_CharT
> __specs
, bool __negative
, bool __isnan
) {
590 char* __last
= __formatter::__insert_sign(__buffer
, __negative
, __specs
.__std_
.__sign_
);
592 // to_chars can return inf, infinity, nan, and nan(n-char-sequence).
593 // The format library requires inf and nan.
594 // All in one expression to avoid dangling references.
596 __specs
.__std_
.__type_
== __format_spec::__type::__hexfloat_upper_case
||
597 __specs
.__std_
.__type_
== __format_spec::__type::__scientific_upper_case
||
598 __specs
.__std_
.__type_
== __format_spec::__type::__fixed_upper_case
||
599 __specs
.__std_
.__type_
== __format_spec::__type::__general_upper_case
;
600 __last
= _VSTD::copy_n(&("infnanINFNAN"[6 * __upper_case
+ 3 * __isnan
]), 3, __last
);
602 // [format.string.std]/13
603 // A zero (0) character preceding the width field pads the field with
604 // leading zeros (following any indication of sign or base) to the field
605 // width, except when applied to an infinity or NaN.
606 if (__specs
.__alignment_
== __format_spec::__alignment::__zero_padding
)
607 __specs
.__alignment_
= __format_spec::__alignment::__right
;
609 return __formatter::__write(__buffer
, __last
, _VSTD::move(__out_it
), __specs
);
612 /// Writes additional zero's for the precision before the exponent.
613 /// This is used when the precision requested in the format string is larger
614 /// than the maximum precision of the floating-point type. These precision
615 /// digits are always 0.
617 /// \param __exponent The location of the exponent character.
618 /// \param __num_trailing_zeros The number of 0's to write before the exponent
620 template <class _CharT
, class _ParserCharT
>
621 _LIBCPP_HIDE_FROM_ABI
auto __write_using_trailing_zeros(
622 const _CharT
* __first
,
623 const _CharT
* __last
,
624 output_iterator
<const _CharT
&> auto __out_it
,
625 __format_spec::__parsed_specifications
<_ParserCharT
> __specs
,
627 const _CharT
* __exponent
,
628 size_t __num_trailing_zeros
) -> decltype(__out_it
) {
629 _LIBCPP_ASSERT_UNCATEGORIZED(__first
<= __last
, "Not a valid range");
630 _LIBCPP_ASSERT_UNCATEGORIZED(__num_trailing_zeros
> 0,
631 "The overload not writing trailing zeros should have been used");
633 __padding_size_result __padding
=
634 __formatter::__padding_size(__size
+ __num_trailing_zeros
, __specs
.__width_
, __specs
.__alignment_
);
635 __out_it
= __formatter::__fill(_VSTD::move(__out_it
), __padding
.__before_
, __specs
.__fill_
);
636 __out_it
= __formatter::__copy(__first
, __exponent
, _VSTD::move(__out_it
));
637 __out_it
= __formatter::__fill(_VSTD::move(__out_it
), __num_trailing_zeros
, _CharT('0'));
638 __out_it
= __formatter::__copy(__exponent
, __last
, _VSTD::move(__out_it
));
639 return __formatter::__fill(_VSTD::move(__out_it
), __padding
.__after_
, __specs
.__fill_
);
643 template <floating_point _Tp
, class _CharT
, class _FormatContext
>
644 _LIBCPP_HIDE_FROM_ABI typename
_FormatContext::iterator
645 __format_floating_point(_Tp __value
, _FormatContext
& __ctx
, __format_spec::__parsed_specifications
<_CharT
> __specs
) {
646 bool __negative
= _VSTD::signbit(__value
);
648 if (!_VSTD::isfinite(__value
)) [[unlikely
]]
649 return __formatter::__format_floating_point_non_finite(__ctx
.out(), __specs
, __negative
, _VSTD::isnan(__value
));
651 // Depending on the std-format-spec string the sign and the value
652 // might not be outputted together:
653 // - zero-padding may insert additional '0' characters.
654 // Therefore the value is processed as a non negative value.
655 // The function @ref __insert_sign will insert a '-' when the value was
661 // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
662 using _Fp
= conditional_t
<same_as
<_Tp
, long double>, double, _Tp
>;
663 // Force the type of the precision to avoid -1 to become an unsigned value.
664 __float_buffer
<_Fp
> __buffer(__specs
.__precision_
);
665 __float_result __result
= __formatter::__format_buffer(
666 __buffer
, __value
, __negative
, (__specs
.__has_precision()), __specs
.__std_
.__sign_
, __specs
.__std_
.__type_
);
668 if (__specs
.__std_
.__alternate_form_
) {
669 if (__result
.__radix_point
== __result
.__last
) {
670 *__result
.__last
++ = '.';
672 // When there is an exponent the point needs to be moved before the
673 // exponent. When there's no exponent the rotate does nothing. Since
674 // rotate tests whether the operation is a nop, call it unconditionally.
675 _VSTD::rotate(__result
.__exponent
, __result
.__last
- 1, __result
.__last
);
676 __result
.__radix_point
= __result
.__exponent
;
678 // The radix point is always placed before the exponent.
679 // - No exponent needs to point to the new last.
680 // - An exponent needs to move one position to the right.
681 // So it's safe to increment the value unconditionally.
682 ++__result
.__exponent
;
685 // [format.string.std]/6
686 // In addition, for g and G conversions, trailing zeros are not removed
689 // If the type option for a floating-point type is none it may use the
690 // general formatting, but it's not a g or G conversion. So in that case
691 // the formatting should not append trailing zeros.
692 bool __is_general
= __specs
.__std_
.__type_
== __format_spec::__type::__general_lower_case
||
693 __specs
.__std_
.__type_
== __format_spec::__type::__general_upper_case
;
696 // https://en.cppreference.com/w/c/io/fprintf
697 // Let P equal the precision if nonzero, 6 if the precision is not
698 // specified, or 1 if the precision is 0. Then, if a conversion with
699 // style E would have an exponent of X:
700 int __p
= _VSTD::max(1, (__specs
.__has_precision() ? __specs
.__precision_
: 6));
701 if (__result
.__exponent
== __result
.__last
)
702 // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X.
703 // By including the radix point it calculates P - (1 + X)
704 __p
-= __result
.__radix_point
- __result
.__integral
;
706 // otherwise, the conversion is with style e or E and precision P - 1.
709 ptrdiff_t __precision
= (__result
.__exponent
- __result
.__radix_point
) - 1;
710 if (__precision
< __p
)
711 __buffer
.__add_trailing_zeros(__p
- __precision
);
715 # ifndef _LIBCPP_HAS_NO_LOCALIZATION
716 if (__specs
.__std_
.__locale_specific_form_
)
717 return __formatter::__format_locale_specific_form(__ctx
.out(), __buffer
, __result
, __ctx
.locale(), __specs
);
720 ptrdiff_t __size
= __result
.__last
- __buffer
.begin();
721 int __num_trailing_zeros
= __buffer
.__num_trailing_zeros();
722 if (__size
+ __num_trailing_zeros
>= __specs
.__width_
) {
723 if (__num_trailing_zeros
&& __result
.__exponent
!= __result
.__last
)
724 // Insert trailing zeros before exponent character.
725 return __formatter::__copy(
728 __formatter::__fill(__formatter::__copy(__buffer
.begin(), __result
.__exponent
, __ctx
.out()),
729 __num_trailing_zeros
,
732 return __formatter::__fill(
733 __formatter::__copy(__buffer
.begin(), __result
.__last
, __ctx
.out()), __num_trailing_zeros
, _CharT('0'));
736 auto __out_it
= __ctx
.out();
737 char* __first
= __buffer
.begin();
738 if (__specs
.__alignment_
== __format_spec::__alignment ::__zero_padding
) {
739 // When there is a sign output it before the padding. Note the __size
740 // doesn't need any adjustment, regardless whether the sign is written
741 // here or in __formatter::__write.
742 if (__first
!= __result
.__integral
)
743 *__out_it
++ = *__first
++;
744 // After the sign is written, zero padding is the same a right alignment
746 __specs
.__alignment_
= __format_spec::__alignment::__right
;
747 __specs
.__fill_
.__data
[0] = _CharT('0');
750 if (__num_trailing_zeros
)
751 return __formatter::__write_using_trailing_zeros(
752 __first
, __result
.__last
, _VSTD::move(__out_it
), __specs
, __size
, __result
.__exponent
, __num_trailing_zeros
);
754 return __formatter::__write(__first
, __result
.__last
, _VSTD::move(__out_it
), __specs
, __size
);
757 } // namespace __formatter
759 template <__fmt_char_type _CharT
>
760 struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point
{
762 template <class _ParseContext
>
763 _LIBCPP_HIDE_FROM_ABI
constexpr typename
_ParseContext::iterator
parse(_ParseContext
& __ctx
) {
764 typename
_ParseContext::iterator __result
= __parser_
.__parse(__ctx
, __format_spec::__fields_floating_point
);
765 __format_spec::__process_parsed_floating_point(__parser_
, "a floating-point");
769 template <floating_point _Tp
, class _FormatContext
>
770 _LIBCPP_HIDE_FROM_ABI typename
_FormatContext::iterator
format(_Tp __value
, _FormatContext
& __ctx
) const {
771 return __formatter::__format_floating_point(__value
, __ctx
, __parser_
.__get_parsed_std_specifications(__ctx
));
774 __format_spec::__parser
<_CharT
> __parser_
;
777 template <__fmt_char_type _CharT
>
778 struct _LIBCPP_TEMPLATE_VIS formatter
<float, _CharT
>
779 : public __formatter_floating_point
<_CharT
> {};
780 template <__fmt_char_type _CharT
>
781 struct _LIBCPP_TEMPLATE_VIS formatter
<double, _CharT
>
782 : public __formatter_floating_point
<_CharT
> {};
783 template <__fmt_char_type _CharT
>
784 struct _LIBCPP_TEMPLATE_VIS formatter
<long double, _CharT
>
785 : public __formatter_floating_point
<_CharT
> {};
787 #endif //_LIBCPP_STD_VER >= 20
789 _LIBCPP_END_NAMESPACE_STD
793 #endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H