libstdc++
charconv
Go to the documentation of this file.
1// Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2
3// Copyright (C) 2017-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/charconv
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_CHARCONV
30#define _GLIBCXX_CHARCONV 1
31
32#ifdef _GLIBCXX_SYSHDR
33#pragma GCC system_header
34#endif
35
36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wpedantic" // __int128
38
39#include <bits/requires_hosted.h> // for error codes
40
41// As an extension we support <charconv> in C++14, but this header should not
42// be included by any other library headers in C++14 mode. This ensures that
43// the names defined in this header are not added to namespace std unless a
44// user explicitly includes <charconv> in C++14 code.
45#if __cplusplus >= 201402L
46
47#include <type_traits>
48#include <bit> // for __bit_width
49#include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl
50#include <bits/error_constants.h> // for std::errc
51#include <ext/numeric_traits.h>
52
53#define __glibcxx_want_to_chars
54#define __glibcxx_want_constexpr_charconv
55#include <bits/version.h>
56
57namespace std _GLIBCXX_VISIBILITY(default)
58{
59_GLIBCXX_BEGIN_NAMESPACE_VERSION
60
61 /// Result type of std::to_chars
63 {
64 char* ptr;
65 errc ec;
66
67#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
68 friend bool
69 operator==(const to_chars_result&, const to_chars_result&) = default;
70#endif
71#if __cplusplus > 202302L
72 constexpr explicit operator bool() const noexcept { return ec == errc{}; }
73#endif
74 };
75
76 /// Result type of std::from_chars
78 {
79 const char* ptr;
80 errc ec;
81
82#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
83 friend bool
84 operator==(const from_chars_result&, const from_chars_result&) = default;
85#endif
86#if __cplusplus > 202302L
87 constexpr explicit operator bool() const noexcept { return ec == errc{}; }
88#endif
89 };
90
91namespace __detail
92{
93 // Pick an unsigned type of suitable size. This is used to reduce the
94 // number of specializations of __to_chars_len, __to_chars etc. that
95 // get instantiated. For example, to_chars<char> and to_chars<short>
96 // and to_chars<unsigned> will all use the same code, and so will
97 // to_chars<long> when sizeof(int) == sizeof(long).
98 template<typename _Tp>
99 struct __to_chars_unsigned_type : __make_unsigned_selector_base
100 {
101 using _UInts = _List<unsigned int, unsigned long, unsigned long long
102#if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__
103 , unsigned __int128
104#endif
105 >;
106 using type = typename __select<sizeof(_Tp), _UInts>::__type;
107 };
108
109 template<typename _Tp>
110 using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type;
111
112 // Generic implementation for arbitrary bases.
113 // Defined in <bits/charconv.h>.
114 template<typename _Tp>
115 constexpr unsigned
116 __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept;
117
118 template<typename _Tp>
119 constexpr unsigned
120 __to_chars_len_2(_Tp __value) noexcept
121 { return std::__bit_width(__value); }
122
123 // Generic implementation for arbitrary bases.
124 template<typename _Tp>
125 constexpr to_chars_result
126 __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
127 {
128 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
129
130 to_chars_result __res;
131
132 const unsigned __len = __to_chars_len(__val, __base);
133
134 if (__builtin_expect(size_t(__last - __first) < __len, 0))
135 {
136 __res.ptr = __last;
137 __res.ec = errc::value_too_large;
138 return __res;
139 }
140
141 unsigned __pos = __len - 1;
142
143 constexpr char __digits[] = {
144 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
145 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
146 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
147 'u', 'v', 'w', 'x', 'y', 'z'
148 };
149
150 while (__val >= (unsigned)__base)
151 {
152 auto const __quo = __val / __base;
153 auto const __rem = __val % __base;
154 __first[__pos--] = __digits[__rem];
155 __val = __quo;
156 }
157 *__first = __digits[__val];
158
159 __res.ptr = __first + __len;
160 __res.ec = {};
161 return __res;
162 }
163
164 template<typename _Tp>
165 constexpr to_chars_result
166 __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
167 {
168 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
169
170 to_chars_result __res;
171
172 const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
173
174 if (__builtin_expect(size_t(__last - __first) < __len, 0))
175 {
176 __res.ptr = __last;
177 __res.ec = errc::value_too_large;
178 return __res;
179 }
180
181 constexpr char __digits[] = {
182 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
183 'a', 'b', 'c', 'd', 'e', 'f'
184 };
185 unsigned __pos = __len - 1;
186 while (__val >= 0x100)
187 {
188 auto __num = __val & 0xF;
189 __val >>= 4;
190 __first[__pos] = __digits[__num];
191 __num = __val & 0xF;
192 __val >>= 4;
193 __first[__pos - 1] = __digits[__num];
194 __pos -= 2;
195 }
196 if (__val >= 0x10)
197 {
198 const auto __num = __val & 0xF;
199 __val >>= 4;
200 __first[1] = __digits[__num];
201 __first[0] = __digits[__val];
202 }
203 else
204 __first[0] = __digits[__val];
205 __res.ptr = __first + __len;
206 __res.ec = {};
207 return __res;
208 }
209
210 template<typename _Tp>
211 constexpr to_chars_result
212 __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
213 {
214 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
215
216 to_chars_result __res;
217
218 const unsigned __len = __to_chars_len(__val, 10);
219
220 if (__builtin_expect(size_t(__last - __first) < __len, 0))
221 {
222 __res.ptr = __last;
223 __res.ec = errc::value_too_large;
224 return __res;
225 }
226
227 __detail::__to_chars_10_impl(__first, __len, __val);
228 __res.ptr = __first + __len;
229 __res.ec = {};
230 return __res;
231 }
232
233 template<typename _Tp>
234 constexpr to_chars_result
235 __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
236 {
237 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
238
239 to_chars_result __res;
240 unsigned __len = 0;
241
242 if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16)
243 {
244 __len = __val > 077777u ? 6u
245 : __val > 07777u ? 5u
246 : __val > 0777u ? 4u
247 : __val > 077u ? 3u
248 : __val > 07u ? 2u
249 : 1u;
250 }
251 else
252 __len = (__to_chars_len_2(__val) + 2) / 3;
253
254 if (__builtin_expect(size_t(__last - __first) < __len, 0))
255 {
256 __res.ptr = __last;
257 __res.ec = errc::value_too_large;
258 return __res;
259 }
260
261 unsigned __pos = __len - 1;
262 while (__val >= 0100)
263 {
264 auto __num = __val & 7;
265 __val >>= 3;
266 __first[__pos] = '0' + __num;
267 __num = __val & 7;
268 __val >>= 3;
269 __first[__pos - 1] = '0' + __num;
270 __pos -= 2;
271 }
272 if (__val >= 010)
273 {
274 auto const __num = __val & 7;
275 __val >>= 3;
276 __first[1] = '0' + __num;
277 __first[0] = '0' + __val;
278 }
279 else
280 __first[0] = '0' + __val;
281 __res.ptr = __first + __len;
282 __res.ec = {};
283 return __res;
284 }
285
286 template<typename _Tp>
287 constexpr to_chars_result
288 __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
289 {
290 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
291
292 to_chars_result __res;
293
294 const unsigned __len = __to_chars_len_2(__val);
295
296 if (__builtin_expect(size_t(__last - __first) < __len, 0))
297 {
298 __res.ptr = __last;
299 __res.ec = errc::value_too_large;
300 return __res;
301 }
302
303 unsigned __pos = __len - 1;
304
305 while (__pos)
306 {
307 __first[__pos--] = '0' + (__val & 1);
308 __val >>= 1;
309 }
310 // First digit is always '1' because __to_chars_len_2 skips
311 // leading zero bits and std::to_chars handles zero values
312 // directly.
313 __first[0] = '1';
314
315 __res.ptr = __first + __len;
316 __res.ec = {};
317 return __res;
318 }
319
320} // namespace __detail
321
322 template<typename _Tp>
323 constexpr to_chars_result
324 __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
325 {
326 __glibcxx_assert(2 <= __base && __base <= 36);
327
328 using _Up = __detail::__unsigned_least_t<_Tp>;
329 _Up __unsigned_val = __value;
330
331 if (__first >= __last) [[__unlikely__]]
332 return { __last, errc::value_too_large };
333
334 if (__value == 0)
335 {
336 *__first = '0';
337 return { __first + 1, errc{} };
338 }
339 else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
340 if (__value < 0)
341 {
342 *__first++ = '-';
343 __unsigned_val = _Up(~__value) + _Up(1);
344 }
345
346 switch (__base)
347 {
348 case 16:
349 return __detail::__to_chars_16(__first, __last, __unsigned_val);
350 case 10:
351 return __detail::__to_chars_10(__first, __last, __unsigned_val);
352 case 8:
353 return __detail::__to_chars_8(__first, __last, __unsigned_val);
354 case 2:
355 return __detail::__to_chars_2(__first, __last, __unsigned_val);
356 default:
357 return __detail::__to_chars(__first, __last, __unsigned_val, __base);
358 }
359 }
360
361#define _GLIBCXX_TO_CHARS(T) \
362 _GLIBCXX23_CONSTEXPR inline to_chars_result \
363 to_chars(char* __first, char* __last, T __value, int __base = 10) \
364 { return std::__to_chars_i<T>(__first, __last, __value, __base); }
365_GLIBCXX_TO_CHARS(char)
366_GLIBCXX_TO_CHARS(signed char)
367_GLIBCXX_TO_CHARS(unsigned char)
368_GLIBCXX_TO_CHARS(signed short)
369_GLIBCXX_TO_CHARS(unsigned short)
370_GLIBCXX_TO_CHARS(signed int)
371_GLIBCXX_TO_CHARS(unsigned int)
372_GLIBCXX_TO_CHARS(signed long)
373_GLIBCXX_TO_CHARS(unsigned long)
374_GLIBCXX_TO_CHARS(signed long long)
375_GLIBCXX_TO_CHARS(unsigned long long)
376#if defined(__GLIBCXX_TYPE_INT_N_0)
377_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
378_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
379#endif
380#if defined(__GLIBCXX_TYPE_INT_N_1)
381_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
382_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
383#endif
384#if defined(__GLIBCXX_TYPE_INT_N_2)
385_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
386_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
387#endif
388#if defined(__GLIBCXX_TYPE_INT_N_3)
389_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
390_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
391#endif
392#undef _GLIBCXX_TO_CHARS
393
394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
395 // 3266. to_chars(bool) should be deleted
396 to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
397
398namespace __detail
399{
400 template<typename _Tp>
401 constexpr bool
402 __raise_and_add(_Tp& __val, int __base, unsigned char __c)
403 {
404 if (__builtin_mul_overflow(__val, __base, &__val)
405 || __builtin_add_overflow(__val, __c, &__val))
406 return false;
407 return true;
408 }
409
410 template<bool _DecOnly>
411 struct __from_chars_alnum_to_val_table
412 {
413 struct type { unsigned char __data[1u << __CHAR_BIT__] = {}; };
414
415 // Construct and return a lookup table that maps 0-9, A-Z and a-z to their
416 // corresponding base-36 value and maps all other characters to 127.
417 static constexpr type
418 _S_make_table()
419 {
420 constexpr unsigned char __lower_letters[27] = "abcdefghijklmnopqrstuvwxyz";
421 constexpr unsigned char __upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
422 type __table;
423 for (auto& __entry : __table.__data)
424 __entry = 127;
425 for (int __i = 0; __i < 10; ++__i)
426 __table.__data['0' + __i] = __i;
427 for (int __i = 0; __i < 26; ++__i)
428 {
429 __table.__data[__lower_letters[__i]] = 10 + __i;
430 __table.__data[__upper_letters[__i]] = 10 + __i;
431 }
432 return __table;
433 }
434
435 // This initializer is made superficially dependent in order
436 // to prevent the compiler from wastefully constructing the
437 // table ahead of time when it's not needed.
438 static constexpr type value = (_DecOnly, _S_make_table());
439 };
440
441#if ! __cpp_inline_variables
442 template<bool _DecOnly>
443 const typename __from_chars_alnum_to_val_table<_DecOnly>::type
444 __from_chars_alnum_to_val_table<_DecOnly>::value;
445#endif
446
447 // If _DecOnly is true: if the character is a decimal digit, then
448 // return its corresponding base-10 value, otherwise return a value >= 127.
449 // If _DecOnly is false: if the character is an alphanumeric digit, then
450 // return its corresponding base-36 value, otherwise return a value >= 127.
451 template<bool _DecOnly = false>
452 _GLIBCXX20_CONSTEXPR unsigned char
453 __from_chars_alnum_to_val(unsigned char __c)
454 {
455 if _GLIBCXX17_CONSTEXPR (_DecOnly)
456 return static_cast<unsigned char>(__c - '0');
457 else
458 return __from_chars_alnum_to_val_table<_DecOnly>::value.__data[__c];
459 }
460
461 /// std::from_chars implementation for integers in a power-of-two base.
462 /// If _DecOnly is true, then we may assume __base is at most 8.
463 template<bool _DecOnly, typename _Tp>
464 _GLIBCXX23_CONSTEXPR bool
465 __from_chars_pow2_base(const char*& __first, const char* __last, _Tp& __val,
466 int __base)
467 {
468 static_assert(is_integral<_Tp>::value, "implementation bug");
469 static_assert(is_unsigned<_Tp>::value, "implementation bug");
470
471 // __glibcxx_assert((__base & (__base - 1)) == 0);
472 // __glibcxx_assert(_DecOnly ? __base <= 8 : __base <= 32);
473 const int __log2_base = __countr_zero(unsigned(__base & 0x3f));
474
475 const ptrdiff_t __len = __last - __first;
476 ptrdiff_t __i = 0;
477 while (__i < __len && __first[__i] == '0')
478 ++__i;
479 const ptrdiff_t __leading_zeroes = __i;
480 if (__i >= __len) [[__unlikely__]]
481 {
482 __first += __i;
483 return true;
484 }
485
486 // Remember the leading significant digit value if necessary.
487 unsigned char __leading_c = 0;
488 if (__base != 2)
489 {
490 __leading_c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]);
491 // __glibcxx_assert(__leading_c != 0);
492 if (__leading_c >= __base) [[__unlikely__]]
493 {
494 __first += __i;
495 return true;
496 }
497 __val = __leading_c;
498 ++__i;
499 }
500
501 for (; __i < __len; ++__i)
502 {
503 const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]);
504 if (__c >= __base)
505 break;
506 __val = (__val << __log2_base) | __c;
507 }
508 __first += __i;
509 auto __significant_bits = (__i - __leading_zeroes) * __log2_base;
510 if (__base != 2)
511 // Compensate for a leading significant digit that didn't use all
512 // of its available bits.
513 __significant_bits -= __log2_base - __bit_width(__leading_c);
514 // __glibcxx_assert(__significant_bits >= 0);
515 return __significant_bits <= __gnu_cxx::__int_traits<_Tp>::__digits;
516 }
517
518 /// std::from_chars implementation for integers in any base.
519 /// If _DecOnly is true, then we may assume __base is at most 10.
520 template<bool _DecOnly, typename _Tp>
521 constexpr bool
522 __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
523 int __base)
524 {
525 // __glibcxx_assert(_DecOnly ? __base <= 10 : __base <= 36);
526
527 const int __bits_per_digit = __bit_width(unsigned(__base & 0x3f));
528 int __unused_bits_lower_bound = __gnu_cxx::__int_traits<_Tp>::__digits;
529 for (; __first != __last; ++__first)
530 {
531 const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(*__first);
532 if (__c >= __base)
533 return true;
534
535 __unused_bits_lower_bound -= __bits_per_digit;
536 if (__unused_bits_lower_bound >= 0) [[__likely__]]
537 // We're definitely not going to overflow.
538 __val = __val * __base + __c;
539 else if (!__raise_and_add(__val, __base, __c)) [[__unlikely__]]
540 {
541 while (++__first != __last
542 && __from_chars_alnum_to_val<_DecOnly>(*__first) < __base)
543 ;
544 return false;
545 }
546 }
547 return true;
548 }
549
550} // namespace __detail
551
552 /// std::from_chars for integral types.
553 template<typename _Tp,
554 enable_if_t<__or_<__is_standard_integer<_Tp>,
555 is_same<char, remove_cv_t<_Tp>>>::value, int> = 0>
556 _GLIBCXX23_CONSTEXPR from_chars_result
557 from_chars(const char* __first, const char* __last, _Tp& __value,
558 int __base = 10)
559 {
560 __glibcxx_assert(2 <= __base && __base <= 36);
561
562 from_chars_result __res{__first, {}};
563
564 int __sign = 1;
565 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
566 if (__first != __last && *__first == '-')
567 {
568 __sign = -1;
569 ++__first;
570 }
571
572 using _Up = __detail::__unsigned_least_t<_Tp>;
573 _Up __val = 0;
574
575 const auto __start = __first;
576 bool __valid;
577 if ((__base & (__base - 1)) == 0)
578 {
579 if (__base <= 8)
580 __valid = __detail::__from_chars_pow2_base<true>(__first, __last, __val, __base);
581 else
582 __valid = __detail::__from_chars_pow2_base<false>(__first, __last, __val, __base);
583 }
584 else if (__base <= 10)
585 __valid = __detail::__from_chars_alnum<true>(__first, __last, __val, __base);
586 else
587 __valid = __detail::__from_chars_alnum<false>(__first, __last, __val, __base);
588
589 if (__builtin_expect(__first == __start, 0))
590 __res.ec = errc::invalid_argument;
591 else
592 {
593 __res.ptr = __first;
594 if (!__valid)
595 __res.ec = errc::result_out_of_range;
596 else
597 {
598 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
599 {
600 _Tp __tmp;
601 if (__builtin_mul_overflow(__val, __sign, &__tmp))
602 __res.ec = errc::result_out_of_range;
603 else
604 __value = __tmp;
605 }
606 else
607 {
608 if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max
610 {
612 __res.ec = errc::result_out_of_range;
613 else
614 __value = __val;
615 }
616 else
617 __value = __val;
618 }
619 }
620 }
621 return __res;
622 }
623
624 /// floating-point format for primitive numerical conversion
625 enum class chars_format
626 {
627 scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
628 };
629
630 [[nodiscard]]
631 constexpr chars_format
632 operator|(chars_format __lhs, chars_format __rhs) noexcept
633 { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
634
635 [[nodiscard]]
636 constexpr chars_format
637 operator&(chars_format __lhs, chars_format __rhs) noexcept
638 { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
639
640 [[nodiscard]]
641 constexpr chars_format
642 operator^(chars_format __lhs, chars_format __rhs) noexcept
643 { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
644
645 [[nodiscard]]
646 constexpr chars_format
647 operator~(chars_format __fmt) noexcept
648 { return (chars_format)~(unsigned)__fmt; }
649
650 constexpr chars_format&
651 operator|=(chars_format& __lhs, chars_format __rhs) noexcept
652 { return __lhs = __lhs | __rhs; }
653
654 constexpr chars_format&
655 operator&=(chars_format& __lhs, chars_format __rhs) noexcept
656 { return __lhs = __lhs & __rhs; }
657
658 constexpr chars_format&
659 operator^=(chars_format& __lhs, chars_format __rhs) noexcept
660 { return __lhs = __lhs ^ __rhs; }
661
662#if defined __cpp_lib_to_chars || _GLIBCXX_HAVE_USELOCALE
663 from_chars_result
664 from_chars(const char* __first, const char* __last, float& __value,
665 chars_format __fmt = chars_format::general) noexcept;
666
667 from_chars_result
668 from_chars(const char* __first, const char* __last, double& __value,
669 chars_format __fmt = chars_format::general) noexcept;
670
671 from_chars_result
672 from_chars(const char* __first, const char* __last, long double& __value,
673 chars_format __fmt = chars_format::general) noexcept;
674
675 // Library routines for 16-bit extended floating point formats
676 // using float as interchange format.
677 from_chars_result
678 __from_chars_float16_t(const char* __first, const char* __last,
679 float& __value,
680 chars_format __fmt = chars_format::general) noexcept;
681 from_chars_result
682 __from_chars_bfloat16_t(const char* __first, const char* __last,
683 float& __value,
684 chars_format __fmt = chars_format::general) noexcept;
685
686#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
687 && defined(__cpp_lib_to_chars)
688 inline from_chars_result
689 from_chars(const char* __first, const char* __last, _Float16& __value,
690 chars_format __fmt = chars_format::general) noexcept
691 {
692 float __val;
693 from_chars_result __res
694 = __from_chars_float16_t(__first, __last, __val, __fmt);
695 if (__res.ec == errc{})
696 __value = _Float16(__val);
697 return __res;
698 }
699#endif
700
701#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
702 inline from_chars_result
703 from_chars(const char* __first, const char* __last, _Float32& __value,
704 chars_format __fmt = chars_format::general) noexcept
705 {
706 float __val;
707 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
708 if (__res.ec == errc{})
709 __value = _Float32(__val);
710 return __res;
711 }
712#endif
713
714#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
715 inline from_chars_result
716 from_chars(const char* __first, const char* __last, _Float64& __value,
717 chars_format __fmt = chars_format::general) noexcept
718 {
719 double __val;
720 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
721 if (__res.ec == errc{})
722 __value = _Float64(__val);
723 return __res;
724 }
725#endif
726
727#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
728 inline from_chars_result
729 from_chars(const char* __first, const char* __last, _Float128& __value,
730 chars_format __fmt = chars_format::general) noexcept
731 {
732 long double __val;
733 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
734 if (__res.ec == errc{})
735 __value = _Float128(__val);
736 return __res;
737 }
738#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
739#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
740 __extension__ from_chars_result
741 from_chars(const char* __first, const char* __last, __ieee128& __value,
742 chars_format __fmt = chars_format::general) noexcept;
743
744 inline from_chars_result
745 from_chars(const char* __first, const char* __last, _Float128& __value,
746 chars_format __fmt = chars_format::general) noexcept
747 {
748 __extension__ __ieee128 __val;
749 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
750 if (__res.ec == errc{})
751 __value = _Float128(__val);
752 return __res;
753 }
754#else
755 from_chars_result
756 from_chars(const char* __first, const char* __last, _Float128& __value,
757 chars_format __fmt = chars_format::general) noexcept;
758#endif
759#endif
760
761#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
762 && defined(__cpp_lib_to_chars)
763 inline from_chars_result
764 from_chars(const char* __first, const char* __last,
765 __gnu_cxx::__bfloat16_t & __value,
766 chars_format __fmt = chars_format::general) noexcept
767 {
768 float __val;
769 from_chars_result __res
770 = __from_chars_bfloat16_t(__first, __last, __val, __fmt);
771 if (__res.ec == errc{})
772 __value = __gnu_cxx::__bfloat16_t(__val);
773 return __res;
774 }
775#endif
776#endif
777
778#if defined __cpp_lib_to_chars
779 // Floating-point std::to_chars
780
781 // Overloads for float.
782 to_chars_result to_chars(char* __first, char* __last, float __value) noexcept;
783 to_chars_result to_chars(char* __first, char* __last, float __value,
784 chars_format __fmt) noexcept;
785 to_chars_result to_chars(char* __first, char* __last, float __value,
786 chars_format __fmt, int __precision) noexcept;
787
788 // Overloads for double.
789 to_chars_result to_chars(char* __first, char* __last, double __value) noexcept;
790 to_chars_result to_chars(char* __first, char* __last, double __value,
791 chars_format __fmt) noexcept;
792 to_chars_result to_chars(char* __first, char* __last, double __value,
793 chars_format __fmt, int __precision) noexcept;
794
795 // Overloads for long double.
796 to_chars_result to_chars(char* __first, char* __last, long double __value)
797 noexcept;
798 to_chars_result to_chars(char* __first, char* __last, long double __value,
799 chars_format __fmt) noexcept;
800 to_chars_result to_chars(char* __first, char* __last, long double __value,
801 chars_format __fmt, int __precision) noexcept;
802
803 // Library routines for 16-bit extended floating point formats
804 // using float as interchange format.
805 to_chars_result __to_chars_float16_t(char* __first, char* __last,
806 float __value,
807 chars_format __fmt) noexcept;
808 to_chars_result __to_chars_bfloat16_t(char* __first, char* __last,
809 float __value,
810 chars_format __fmt) noexcept;
811
812#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
813 inline to_chars_result
814 to_chars(char* __first, char* __last, _Float16 __value) noexcept
815 {
816 return __to_chars_float16_t(__first, __last, float(__value),
817 chars_format{});
818 }
819 inline to_chars_result
820 to_chars(char* __first, char* __last, _Float16 __value,
821 chars_format __fmt) noexcept
822 { return __to_chars_float16_t(__first, __last, float(__value), __fmt); }
823 inline to_chars_result
824 to_chars(char* __first, char* __last, _Float16 __value,
825 chars_format __fmt, int __precision) noexcept
826 { return to_chars(__first, __last, float(__value), __fmt, __precision); }
827#endif
828
829#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
830 inline to_chars_result
831 to_chars(char* __first, char* __last, _Float32 __value) noexcept
832 { return to_chars(__first, __last, float(__value)); }
833 inline to_chars_result
834 to_chars(char* __first, char* __last, _Float32 __value,
835 chars_format __fmt) noexcept
836 { return to_chars(__first, __last, float(__value), __fmt); }
837 inline to_chars_result
838 to_chars(char* __first, char* __last, _Float32 __value,
839 chars_format __fmt, int __precision) noexcept
840 { return to_chars(__first, __last, float(__value), __fmt, __precision); }
841#endif
842
843#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
844 inline to_chars_result
845 to_chars(char* __first, char* __last, _Float64 __value) noexcept
846 { return to_chars(__first, __last, double(__value)); }
847 inline to_chars_result
848 to_chars(char* __first, char* __last, _Float64 __value,
849 chars_format __fmt) noexcept
850 { return to_chars(__first, __last, double(__value), __fmt); }
851 inline to_chars_result
852 to_chars(char* __first, char* __last, _Float64 __value,
853 chars_format __fmt, int __precision) noexcept
854 { return to_chars(__first, __last, double(__value), __fmt, __precision); }
855#endif
856
857#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
858 inline to_chars_result
859 to_chars(char* __first, char* __last, _Float128 __value) noexcept
860 { return to_chars(__first, __last, static_cast<long double>(__value)); }
861 inline to_chars_result
862 to_chars(char* __first, char* __last, _Float128 __value,
863 chars_format __fmt) noexcept
864 {
865 return to_chars(__first, __last, static_cast<long double>(__value), __fmt);
866 }
867 inline to_chars_result
868 to_chars(char* __first, char* __last, _Float128 __value,
869 chars_format __fmt, int __precision) noexcept
870 {
871 return to_chars(__first, __last, static_cast<long double>(__value), __fmt,
872 __precision);
873 }
874#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
875#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
876 __extension__ to_chars_result
877 to_chars(char* __first, char* __last, __float128 __value) noexcept;
878 __extension__ to_chars_result
879 to_chars(char* __first, char* __last, __float128 __value,
880 chars_format __fmt) noexcept;
881 __extension__ to_chars_result
882 to_chars(char* __first, char* __last, __float128 __value,
883 chars_format __fmt, int __precision) noexcept;
884
885 inline to_chars_result
886 to_chars(char* __first, char* __last, _Float128 __value) noexcept
887 {
888 return __extension__ to_chars(__first, __last,
889 static_cast<__float128>(__value));
890 }
891 inline to_chars_result
892 to_chars(char* __first, char* __last, _Float128 __value,
893 chars_format __fmt) noexcept
894 {
895
896 return __extension__ to_chars(__first, __last,
897 static_cast<__float128>(__value), __fmt);
898 }
899 inline to_chars_result
900 to_chars(char* __first, char* __last, _Float128 __value,
901 chars_format __fmt, int __precision) noexcept
902 {
903
904 return __extension__ to_chars(__first, __last,
905 static_cast<__float128>(__value), __fmt,
906 __precision);
907 }
908#else
909 to_chars_result to_chars(char* __first, char* __last, _Float128 __value)
910 noexcept;
911 to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
912 chars_format __fmt) noexcept;
913 to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
914 chars_format __fmt, int __precision) noexcept;
915#endif
916#endif
917
918#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
919 inline to_chars_result
920 to_chars(char* __first, char* __last,
921 __gnu_cxx::__bfloat16_t __value) noexcept
922 {
923 return __to_chars_bfloat16_t(__first, __last, float(__value),
924 chars_format{});
925 }
926 inline to_chars_result
927 to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
928 chars_format __fmt) noexcept
929 { return __to_chars_bfloat16_t(__first, __last, float(__value), __fmt); }
930 inline to_chars_result
931 to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
932 chars_format __fmt, int __precision) noexcept
933 { return to_chars(__first, __last, float(__value), __fmt, __precision); }
934#endif
935#endif
936
937_GLIBCXX_END_NAMESPACE_VERSION
938} // namespace std
939#endif // C++14
940#pragma GCC diagnostic pop
941#endif // _GLIBCXX_CHARCONV
ISO C++ entities toplevel namespace is std.
ios_base & scientific(ios_base &__base)
Calls base.setf(ios_base::scientific, ios_base::floatfield).
Definition ios_base.h:1127
ios_base & hex(ios_base &__base)
Calls base.setf(ios_base::hex, ios_base::basefield).
Definition ios_base.h:1102
chars_format
floating-point format for primitive numerical conversion
Definition charconv:626
constexpr bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1582
ios_base & fixed(ios_base &__base)
Calls base.setf(ios_base::fixed, ios_base::floatfield).
Definition ios_base.h:1119
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1572
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1562
constexpr from_chars_result from_chars(const char *__first, const char *__last, _Tp &__value, int __base=10)
std::from_chars for integral types.
Definition charconv:557
constexpr bool __from_chars_alnum(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in any base. If _DecOnly is true, then we may assume __ba...
Definition charconv:522
constexpr bool __from_chars_pow2_base(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in a power-of-two base. If _DecOnly is true,...
Definition charconv:465
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
constexpr _Iterator __base(_Iterator __it)
Result type of std::to_chars.
Definition charconv:63
Result type of std::from_chars.
Definition charconv:78
is_integral
Definition type_traits:468
is_signed
Definition type_traits:995
is_unsigned
Definition type_traits:1001