Line data Source code
1 : // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2 :
3 : // Copyright (C) 2017-2021 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 : #pragma GCC system_header
33 :
34 : // As an extension we support <charconv> in C++14, but this header should not
35 : // be included by any other library headers in C++14 mode. This ensures that
36 : // the names defined in this header are not added to namespace std unless a
37 : // user explicitly includes <charconv> in C++14 code.
38 : #if __cplusplus >= 201402L
39 :
40 : #include <type_traits>
41 : #include <bit> // for __bit_width
42 : #include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl
43 : #include <bits/error_constants.h> // for std::errc
44 : #include <ext/numeric_traits.h>
45 :
46 : #if _GLIBCXX_HAVE_USELOCALE
47 : # define __cpp_lib_to_chars 201611L
48 : #endif
49 :
50 : namespace std _GLIBCXX_VISIBILITY(default)
51 : {
52 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 :
54 : /// Result type of std::to_chars
55 : struct to_chars_result
56 : {
57 : char* ptr;
58 : errc ec;
59 :
60 : #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
61 : friend bool
62 : operator==(const to_chars_result&, const to_chars_result&) = default;
63 : #endif
64 : };
65 :
66 : /// Result type of std::from_chars
67 : struct from_chars_result
68 : {
69 : const char* ptr;
70 : errc ec;
71 :
72 : #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
73 : friend bool
74 : operator==(const from_chars_result&, const from_chars_result&) = default;
75 : #endif
76 : };
77 :
78 : namespace __detail
79 : {
80 : template<typename _Tp>
81 : using __integer_to_chars_result_type
82 : = enable_if_t<__or_<__is_signed_integer<_Tp>,
83 : __is_unsigned_integer<_Tp>,
84 : is_same<char, remove_cv_t<_Tp>>>::value,
85 : to_chars_result>;
86 :
87 : // Pick an unsigned type of suitable size. This is used to reduce the
88 : // number of specializations of __to_chars_len, __to_chars etc. that
89 : // get instantiated. For example, to_chars<char> and to_chars<short>
90 : // and to_chars<unsigned> will all use the same code, and so will
91 : // to_chars<long> when sizeof(int) == sizeof(long).
92 : template<typename _Tp>
93 : struct __to_chars_unsigned_type : __make_unsigned_selector_base
94 : {
95 : using _UInts = _List<unsigned int, unsigned long, unsigned long long
96 : #if _GLIBCXX_USE_INT128
97 : , unsigned __int128
98 : #endif
99 : >;
100 : using type = typename __select<sizeof(_Tp), _UInts>::__type;
101 : };
102 :
103 : template<typename _Tp>
104 : using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type;
105 :
106 : // Generic implementation for arbitrary bases.
107 : // Defined in <bits/charconv.h>.
108 : template<typename _Tp>
109 : constexpr unsigned
110 : __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept;
111 :
112 : template<typename _Tp>
113 : constexpr unsigned
114 : __to_chars_len_2(_Tp __value) noexcept
115 : { return std::__bit_width(__value); }
116 :
117 : // Generic implementation for arbitrary bases.
118 : template<typename _Tp>
119 : to_chars_result
120 : __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
121 : {
122 : static_assert(is_integral<_Tp>::value, "implementation bug");
123 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
124 :
125 : to_chars_result __res;
126 :
127 : const unsigned __len = __to_chars_len(__val, __base);
128 :
129 : if (__builtin_expect((__last - __first) < __len, 0))
130 : {
131 : __res.ptr = __last;
132 : __res.ec = errc::value_too_large;
133 : return __res;
134 : }
135 :
136 : unsigned __pos = __len - 1;
137 :
138 : static constexpr char __digits[] = {
139 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
140 : 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
141 : 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
142 : 'u', 'v', 'w', 'x', 'y', 'z'
143 : };
144 :
145 : while (__val >= (unsigned)__base)
146 : {
147 : auto const __quo = __val / __base;
148 : auto const __rem = __val % __base;
149 : __first[__pos--] = __digits[__rem];
150 : __val = __quo;
151 : }
152 : *__first = __digits[__val];
153 :
154 : __res.ptr = __first + __len;
155 : __res.ec = {};
156 : return __res;
157 : }
158 :
159 : template<typename _Tp>
160 : __integer_to_chars_result_type<_Tp>
161 : __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
162 : {
163 : static_assert(is_integral<_Tp>::value, "implementation bug");
164 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
165 :
166 : to_chars_result __res;
167 :
168 : const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
169 :
170 : if (__builtin_expect((__last - __first) < __len, 0))
171 : {
172 : __res.ptr = __last;
173 : __res.ec = errc::value_too_large;
174 : return __res;
175 : }
176 :
177 : static constexpr char __digits[] = {
178 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
179 : 'a', 'b', 'c', 'd', 'e', 'f'
180 : };
181 : unsigned __pos = __len - 1;
182 : while (__val >= 0x100)
183 : {
184 : auto __num = __val & 0xF;
185 : __val >>= 4;
186 : __first[__pos] = __digits[__num];
187 : __num = __val & 0xF;
188 : __val >>= 4;
189 : __first[__pos - 1] = __digits[__num];
190 : __pos -= 2;
191 : }
192 : if (__val >= 0x10)
193 : {
194 : const auto __num = __val & 0xF;
195 : __val >>= 4;
196 : __first[1] = __digits[__num];
197 : __first[0] = __digits[__val];
198 : }
199 : else
200 : __first[0] = __digits[__val];
201 : __res.ptr = __first + __len;
202 : __res.ec = {};
203 : return __res;
204 : }
205 :
206 : template<typename _Tp>
207 : inline __integer_to_chars_result_type<_Tp>
208 : __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
209 : {
210 : static_assert(is_integral<_Tp>::value, "implementation bug");
211 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
212 :
213 : to_chars_result __res;
214 :
215 : const unsigned __len = __to_chars_len(__val, 10);
216 :
217 : if (__builtin_expect((__last - __first) < __len, 0))
218 : {
219 : __res.ptr = __last;
220 : __res.ec = errc::value_too_large;
221 : return __res;
222 : }
223 :
224 : __detail::__to_chars_10_impl(__first, __len, __val);
225 : __res.ptr = __first + __len;
226 : __res.ec = {};
227 : return __res;
228 : }
229 :
230 : template<typename _Tp>
231 : __integer_to_chars_result_type<_Tp>
232 : __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
233 : {
234 : static_assert(is_integral<_Tp>::value, "implementation bug");
235 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
236 :
237 : to_chars_result __res;
238 : unsigned __len;
239 :
240 : if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16)
241 : {
242 : __len = __val > 077777u ? 6u
243 : : __val > 07777u ? 5u
244 : : __val > 0777u ? 4u
245 : : __val > 077u ? 3u
246 : : __val > 07u ? 2u
247 : : 1u;
248 : }
249 : else
250 : __len = (__to_chars_len_2(__val) + 2) / 3;
251 :
252 : if (__builtin_expect((__last - __first) < __len, 0))
253 : {
254 : __res.ptr = __last;
255 : __res.ec = errc::value_too_large;
256 : return __res;
257 : }
258 :
259 : unsigned __pos = __len - 1;
260 : while (__val >= 0100)
261 : {
262 : auto __num = __val & 7;
263 : __val >>= 3;
264 : __first[__pos] = '0' + __num;
265 : __num = __val & 7;
266 : __val >>= 3;
267 : __first[__pos - 1] = '0' + __num;
268 : __pos -= 2;
269 : }
270 : if (__val >= 010)
271 : {
272 : auto const __num = __val & 7;
273 : __val >>= 3;
274 : __first[1] = '0' + __num;
275 : __first[0] = '0' + __val;
276 : }
277 : else
278 : __first[0] = '0' + __val;
279 : __res.ptr = __first + __len;
280 : __res.ec = {};
281 : return __res;
282 : }
283 :
284 : template<typename _Tp>
285 : __integer_to_chars_result_type<_Tp>
286 : __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
287 : {
288 : static_assert(is_integral<_Tp>::value, "implementation bug");
289 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
290 :
291 : to_chars_result __res;
292 :
293 : const unsigned __len = __to_chars_len_2(__val);
294 :
295 : if (__builtin_expect((__last - __first) < __len, 0))
296 : {
297 : __res.ptr = __last;
298 : __res.ec = errc::value_too_large;
299 : return __res;
300 : }
301 :
302 : unsigned __pos = __len - 1;
303 :
304 : while (__pos)
305 : {
306 : __first[__pos--] = '0' + (__val & 1);
307 : __val >>= 1;
308 : }
309 : // First digit is always '1' because __to_chars_len_2 skips
310 : // leading zero bits and std::to_chars handles zero values
311 : // directly.
312 : __first[0] = '1';
313 :
314 : __res.ptr = __first + __len;
315 : __res.ec = {};
316 : return __res;
317 : }
318 :
319 : } // namespace __detail
320 :
321 : template<typename _Tp>
322 : __detail::__integer_to_chars_result_type<_Tp>
323 : __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
324 : {
325 : __glibcxx_assert(2 <= __base && __base <= 36);
326 :
327 : using _Up = __detail::__unsigned_least_t<_Tp>;
328 : _Up __unsigned_val = __value;
329 :
330 : if (__first == __last) [[__unlikely__]]
331 : return { __last, errc::value_too_large };
332 :
333 : if (__value == 0)
334 : {
335 : *__first = '0';
336 : return { __first + 1, errc{} };
337 : }
338 : else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
339 : if (__value < 0)
340 : {
341 : *__first++ = '-';
342 : __unsigned_val = _Up(~__value) + _Up(1);
343 : }
344 :
345 : switch (__base)
346 : {
347 : case 16:
348 : return __detail::__to_chars_16(__first, __last, __unsigned_val);
349 : case 10:
350 : return __detail::__to_chars_10(__first, __last, __unsigned_val);
351 : case 8:
352 : return __detail::__to_chars_8(__first, __last, __unsigned_val);
353 : case 2:
354 : return __detail::__to_chars_2(__first, __last, __unsigned_val);
355 : default:
356 : return __detail::__to_chars(__first, __last, __unsigned_val, __base);
357 : }
358 : }
359 :
360 : #define _GLIBCXX_TO_CHARS(T) \
361 : inline to_chars_result \
362 : to_chars(char* __first, char* __last, T __value, int __base = 10) \
363 : { return std::__to_chars_i<T>(__first, __last, __value, __base); }
364 : _GLIBCXX_TO_CHARS(char)
365 : _GLIBCXX_TO_CHARS(signed char)
366 : _GLIBCXX_TO_CHARS(unsigned char)
367 : _GLIBCXX_TO_CHARS(signed short)
368 : _GLIBCXX_TO_CHARS(unsigned short)
369 : _GLIBCXX_TO_CHARS(signed int)
370 : _GLIBCXX_TO_CHARS(unsigned int)
371 : _GLIBCXX_TO_CHARS(signed long)
372 : _GLIBCXX_TO_CHARS(unsigned long)
373 : _GLIBCXX_TO_CHARS(signed long long)
374 : _GLIBCXX_TO_CHARS(unsigned long long)
375 : #if defined(__GLIBCXX_TYPE_INT_N_0)
376 : _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
377 : _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
378 : #endif
379 : #if defined(__GLIBCXX_TYPE_INT_N_1)
380 : _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
381 : _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
382 : #endif
383 : #if defined(__GLIBCXX_TYPE_INT_N_2)
384 : _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
385 : _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
386 : #endif
387 : #if defined(__GLIBCXX_TYPE_INT_N_3)
388 : _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
389 : _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
390 : #endif
391 : #undef _GLIBCXX_TO_CHARS
392 :
393 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
394 : // 3266. to_chars(bool) should be deleted
395 : to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
396 :
397 : namespace __detail
398 : {
399 : template<typename _Tp>
400 : bool
401 104957 : __raise_and_add(_Tp& __val, int __base, unsigned char __c)
402 : {
403 209914 : if (__builtin_mul_overflow(__val, __base, &__val)
404 104957 : || __builtin_add_overflow(__val, __c, &__val))
405 0 : return false;
406 104957 : return true;
407 : }
408 :
409 : /// std::from_chars implementation for integers in base 2.
410 : template<typename _Tp>
411 : bool
412 0 : __from_chars_binary(const char*& __first, const char* __last, _Tp& __val)
413 : {
414 : static_assert(is_integral<_Tp>::value, "implementation bug");
415 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
416 :
417 0 : const ptrdiff_t __len = __last - __first;
418 0 : ptrdiff_t __i = 0;
419 0 : while (__i < __len && __first[__i] == '0')
420 0 : ++__i;
421 0 : const ptrdiff_t __leading_zeroes = __i;
422 :
423 0 : while (__i < __len)
424 : {
425 0 : const unsigned char __c = (unsigned)__first[__i] - '0';
426 0 : if (__c < 2)
427 0 : __val = (__val << 1) | __c;
428 : else
429 0 : break;
430 0 : __i++;
431 : }
432 0 : __first += __i;
433 0 : return (__i - __leading_zeroes) <= __gnu_cxx::__int_traits<_Tp>::__digits;
434 : }
435 :
436 : /// std::from_chars implementation for integers in bases 3 to 10.
437 : template<typename _Tp>
438 : bool
439 7184 : __from_chars_digit(const char*& __first, const char* __last, _Tp& __val,
440 : int __base)
441 : {
442 : static_assert(is_integral<_Tp>::value, "implementation bug");
443 : static_assert(is_unsigned<_Tp>::value, "implementation bug");
444 :
445 51994 : auto __matches = [__base](char __c) {
446 22405 : return '0' <= __c && __c <= ('0' + (__base - 1));
447 : };
448 :
449 29589 : while (__first != __last)
450 : {
451 22405 : const char __c = *__first;
452 22405 : if (__matches(__c))
453 : {
454 22405 : if (!__raise_and_add(__val, __base, __c - '0'))
455 : {
456 0 : while (++__first != __last && __matches(*__first))
457 : ;
458 0 : return false;
459 : }
460 22405 : __first++;
461 : }
462 : else
463 0 : return true;
464 : }
465 7184 : return true;
466 : }
467 :
468 : constexpr char
469 1004 : __from_chars_alpha_to_num(char __c)
470 : {
471 1004 : switch (__c)
472 : {
473 0 : case 'a':
474 : case 'A':
475 0 : return 10;
476 0 : case 'b':
477 : case 'B':
478 0 : return 11;
479 0 : case 'c':
480 : case 'C':
481 0 : return 12;
482 1004 : case 'd':
483 : case 'D':
484 1004 : return 13;
485 0 : case 'e':
486 : case 'E':
487 0 : return 14;
488 0 : case 'f':
489 : case 'F':
490 0 : return 15;
491 0 : case 'g':
492 : case 'G':
493 0 : return 16;
494 0 : case 'h':
495 : case 'H':
496 0 : return 17;
497 0 : case 'i':
498 : case 'I':
499 0 : return 18;
500 0 : case 'j':
501 : case 'J':
502 0 : return 19;
503 0 : case 'k':
504 : case 'K':
505 0 : return 20;
506 0 : case 'l':
507 : case 'L':
508 0 : return 21;
509 0 : case 'm':
510 : case 'M':
511 0 : return 22;
512 0 : case 'n':
513 : case 'N':
514 0 : return 23;
515 0 : case 'o':
516 : case 'O':
517 0 : return 24;
518 0 : case 'p':
519 : case 'P':
520 0 : return 25;
521 0 : case 'q':
522 : case 'Q':
523 0 : return 26;
524 0 : case 'r':
525 : case 'R':
526 0 : return 27;
527 0 : case 's':
528 : case 'S':
529 0 : return 28;
530 0 : case 't':
531 : case 'T':
532 0 : return 29;
533 0 : case 'u':
534 : case 'U':
535 0 : return 30;
536 0 : case 'v':
537 : case 'V':
538 0 : return 31;
539 0 : case 'w':
540 : case 'W':
541 0 : return 32;
542 0 : case 'x':
543 : case 'X':
544 0 : return 33;
545 0 : case 'y':
546 : case 'Y':
547 0 : return 34;
548 0 : case 'z':
549 : case 'Z':
550 0 : return 35;
551 : }
552 0 : return 127;
553 : }
554 :
555 : /// std::from_chars implementation for integers in bases 11 to 36.
556 : template<typename _Tp>
557 : bool
558 20635 : __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
559 : int __base)
560 : {
561 20635 : bool __valid = true;
562 103187 : while (__first != __last)
563 : {
564 82552 : char __c = *__first;
565 82552 : if ('0' <= __c && __c <= '9') // isdigit
566 81548 : __c -= '0';
567 : else
568 : {
569 1004 : __c = __from_chars_alpha_to_num(__c);
570 1004 : if (__c >= __base)
571 0 : break;
572 : }
573 :
574 82552 : if (__builtin_expect(__valid, 1))
575 82552 : __valid = __raise_and_add(__val, __base, __c);
576 82552 : __first++;
577 : }
578 20635 : return __valid;
579 : }
580 :
581 : template<typename _Tp>
582 : using __integer_from_chars_result_type
583 : = enable_if_t<__or_<__is_signed_integer<_Tp>,
584 : __is_unsigned_integer<_Tp>,
585 : is_same<char, remove_cv_t<_Tp>>>::value,
586 : from_chars_result>;
587 :
588 : } // namespace __detail
589 :
590 : /// std::from_chars for integral types.
591 : template<typename _Tp>
592 : __detail::__integer_from_chars_result_type<_Tp>
593 27819 : from_chars(const char* __first, const char* __last, _Tp& __value,
594 : int __base = 10)
595 : {
596 : __glibcxx_assert(2 <= __base && __base <= 36);
597 :
598 27819 : from_chars_result __res{__first, {}};
599 :
600 27819 : int __sign = 1;
601 : if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
602 3498 : if (__first != __last && *__first == '-')
603 : {
604 692 : __sign = -1;
605 692 : ++__first;
606 : }
607 :
608 : using _Up = __detail::__unsigned_least_t<_Tp>;
609 27819 : _Up __val = 0;
610 :
611 27819 : const auto __start = __first;
612 : bool __valid;
613 27819 : if (__base == 2)
614 0 : __valid = __detail::__from_chars_binary(__first, __last, __val);
615 27819 : else if (__base <= 10)
616 7184 : __valid = __detail::__from_chars_digit(__first, __last, __val, __base);
617 : else
618 20635 : __valid = __detail::__from_chars_alnum(__first, __last, __val, __base);
619 :
620 27819 : if (__builtin_expect(__first == __start, 0))
621 0 : __res.ec = errc::invalid_argument;
622 : else
623 : {
624 27819 : __res.ptr = __first;
625 27819 : if (!__valid)
626 0 : __res.ec = errc::result_out_of_range;
627 : else
628 : {
629 : if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
630 : {
631 : _Tp __tmp;
632 3498 : if (__builtin_mul_overflow(__val, __sign, &__tmp))
633 0 : __res.ec = errc::result_out_of_range;
634 : else
635 3498 : __value = __tmp;
636 : }
637 : else
638 : {
639 : if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max
640 : > __gnu_cxx::__int_traits<_Tp>::__max)
641 : {
642 708 : if (__val > __gnu_cxx::__int_traits<_Tp>::__max)
643 0 : __res.ec = errc::result_out_of_range;
644 : else
645 708 : __value = __val;
646 : }
647 : else
648 23613 : __value = __val;
649 : }
650 : }
651 : }
652 27819 : return __res;
653 : }
654 :
655 : /// floating-point format for primitive numerical conversion
656 : enum class chars_format
657 : {
658 : scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
659 : };
660 :
661 : constexpr chars_format
662 : operator|(chars_format __lhs, chars_format __rhs) noexcept
663 : { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
664 :
665 : constexpr chars_format
666 : operator&(chars_format __lhs, chars_format __rhs) noexcept
667 : { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
668 :
669 : constexpr chars_format
670 : operator^(chars_format __lhs, chars_format __rhs) noexcept
671 : { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
672 :
673 : constexpr chars_format
674 : operator~(chars_format __fmt) noexcept
675 : { return (chars_format)~(unsigned)__fmt; }
676 :
677 : constexpr chars_format&
678 : operator|=(chars_format& __lhs, chars_format __rhs) noexcept
679 : { return __lhs = __lhs | __rhs; }
680 :
681 : constexpr chars_format&
682 : operator&=(chars_format& __lhs, chars_format __rhs) noexcept
683 : { return __lhs = __lhs & __rhs; }
684 :
685 : constexpr chars_format&
686 : operator^=(chars_format& __lhs, chars_format __rhs) noexcept
687 : { return __lhs = __lhs ^ __rhs; }
688 :
689 : #if _GLIBCXX_HAVE_USELOCALE
690 : from_chars_result
691 : from_chars(const char* __first, const char* __last, float& __value,
692 : chars_format __fmt = chars_format::general) noexcept;
693 :
694 : from_chars_result
695 : from_chars(const char* __first, const char* __last, double& __value,
696 : chars_format __fmt = chars_format::general) noexcept;
697 :
698 : from_chars_result
699 : from_chars(const char* __first, const char* __last, long double& __value,
700 : chars_format __fmt = chars_format::general) noexcept;
701 : #endif
702 :
703 : #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \
704 : && __SIZE_WIDTH__ >= 32
705 : // Floating-point std::to_chars
706 :
707 : // Overloads for float.
708 : to_chars_result to_chars(char* __first, char* __last, float __value) noexcept;
709 : to_chars_result to_chars(char* __first, char* __last, float __value,
710 : chars_format __fmt) noexcept;
711 : to_chars_result to_chars(char* __first, char* __last, float __value,
712 : chars_format __fmt, int __precision) noexcept;
713 :
714 : // Overloads for double.
715 : to_chars_result to_chars(char* __first, char* __last, double __value) noexcept;
716 : to_chars_result to_chars(char* __first, char* __last, double __value,
717 : chars_format __fmt) noexcept;
718 : to_chars_result to_chars(char* __first, char* __last, double __value,
719 : chars_format __fmt, int __precision) noexcept;
720 :
721 : // Overloads for long double.
722 : to_chars_result to_chars(char* __first, char* __last, long double __value)
723 : noexcept;
724 : to_chars_result to_chars(char* __first, char* __last, long double __value,
725 : chars_format __fmt) noexcept;
726 : to_chars_result to_chars(char* __first, char* __last, long double __value,
727 : chars_format __fmt, int __precision) noexcept;
728 : #endif
729 :
730 : _GLIBCXX_END_NAMESPACE_VERSION
731 : } // namespace std
732 : #endif // C++14
733 : #endif // _GLIBCXX_CHARCONV
|