libstdc++
charconv
Go to the documentation of this file.
1// Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2
3// Copyright (C) 2017-2020 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 <cctype> // for isdigit
43#include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl
44#include <bits/error_constants.h> // for std::errc
45#include <bits/int_limits.h>
46
47// FIXME: Define when floating point is supported:
48// #define __cpp_lib_to_chars 201611L
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
54 /// Result type of std::to_chars
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
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
78namespace __detail
79{
80 template<typename _Tp>
81 using __integer_to_chars_result_type
83 __is_unsigned_integer<_Tp>,
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 >= __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 (__detail::__int_limits<_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 (__value == 0 && __first != __last)
331 {
332 *__first = '0';
333 return { __first + 1, errc{} };
334 }
335
336 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
337 if (__value < 0)
338 {
339 if (__builtin_expect(__first != __last, 1))
340 *__first++ = '-';
341 __unsigned_val = _Up(~__value) + _Up(1);
342 }
343
344 switch (__base)
345 {
346 case 16:
347 return __detail::__to_chars_16(__first, __last, __unsigned_val);
348 case 10:
349 return __detail::__to_chars_10(__first, __last, __unsigned_val);
350 case 8:
351 return __detail::__to_chars_8(__first, __last, __unsigned_val);
352 case 2:
353 return __detail::__to_chars_2(__first, __last, __unsigned_val);
354 default:
355 return __detail::__to_chars(__first, __last, __unsigned_val, __base);
356 }
357 }
358
359#define _GLIBCXX_TO_CHARS(T) \
360 inline to_chars_result \
361 to_chars(char* __first, char* __last, T __value, int __base = 10) \
362 { return std::__to_chars_i<T>(__first, __last, __value, __base); }
363_GLIBCXX_TO_CHARS(char)
364_GLIBCXX_TO_CHARS(signed char)
365_GLIBCXX_TO_CHARS(unsigned char)
366_GLIBCXX_TO_CHARS(signed short)
367_GLIBCXX_TO_CHARS(unsigned short)
368_GLIBCXX_TO_CHARS(signed int)
369_GLIBCXX_TO_CHARS(unsigned int)
370_GLIBCXX_TO_CHARS(signed long)
371_GLIBCXX_TO_CHARS(unsigned long)
372_GLIBCXX_TO_CHARS(signed long long)
373_GLIBCXX_TO_CHARS(unsigned long long)
374#if defined(__GLIBCXX_TYPE_INT_N_0)
375_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
376_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
377#endif
378#if defined(__GLIBCXX_TYPE_INT_N_1)
379_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
380_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
381#endif
382#if defined(__GLIBCXX_TYPE_INT_N_2)
383_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
384_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
385#endif
386#if defined(__GLIBCXX_TYPE_INT_N_3)
387_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
388_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
389#endif
390#undef _GLIBCXX_TO_CHARS
391
392 // _GLIBCXX_RESOLVE_LIB_DEFECTS
393 // 3266. to_chars(bool) should be deleted
394 to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
395
396namespace __detail
397{
398 template<typename _Tp>
399 bool
400 __raise_and_add(_Tp& __val, int __base, unsigned char __c)
401 {
402 if (__builtin_mul_overflow(__val, __base, &__val)
403 || __builtin_add_overflow(__val, __c, &__val))
404 return false;
405 return true;
406 }
407
408 /// std::from_chars implementation for integers in base 2.
409 template<typename _Tp>
410 bool
411 __from_chars_binary(const char*& __first, const char* __last, _Tp& __val)
412 {
413 static_assert(is_integral<_Tp>::value, "implementation bug");
414 static_assert(is_unsigned<_Tp>::value, "implementation bug");
415
416 const ptrdiff_t __len = __last - __first;
417 int __i = 0;
418 while (__i < __len)
419 {
420 const unsigned char __c = (unsigned)__first[__i] - '0';
421 if (__c < 2)
422 __val = (__val << 1) | __c;
423 else
424 break;
425 __i++;
426 }
427 __first += __i;
428 return __i <= __detail::__int_limits<_Tp>::digits;
429 }
430
431 /// std::from_chars implementation for integers in bases 3 to 10.
432 template<typename _Tp>
433 bool
434 __from_chars_digit(const char*& __first, const char* __last, _Tp& __val,
435 int __base)
436 {
437 static_assert(is_integral<_Tp>::value, "implementation bug");
438 static_assert(is_unsigned<_Tp>::value, "implementation bug");
439
440 auto __matches = [__base](char __c) {
441 return '0' <= __c && __c <= ('0' + (__base - 1));
442 };
443
444 while (__first != __last)
445 {
446 const char __c = *__first;
447 if (__matches(__c))
448 {
449 if (!__raise_and_add(__val, __base, __c - '0'))
450 {
451 while (++__first != __last && __matches(*__first))
452 ;
453 return false;
454 }
455 __first++;
456 }
457 else
458 return true;
459 }
460 return true;
461 }
462
463 constexpr unsigned char
464 __from_chars_alpha_to_num(char __c)
465 {
466 switch (__c)
467 {
468 case 'a':
469 case 'A':
470 return 10;
471 case 'b':
472 case 'B':
473 return 11;
474 case 'c':
475 case 'C':
476 return 12;
477 case 'd':
478 case 'D':
479 return 13;
480 case 'e':
481 case 'E':
482 return 14;
483 case 'f':
484 case 'F':
485 return 15;
486 case 'g':
487 case 'G':
488 return 16;
489 case 'h':
490 case 'H':
491 return 17;
492 case 'i':
493 case 'I':
494 return 18;
495 case 'j':
496 case 'J':
497 return 19;
498 case 'k':
499 case 'K':
500 return 20;
501 case 'l':
502 case 'L':
503 return 21;
504 case 'm':
505 case 'M':
506 return 22;
507 case 'n':
508 case 'N':
509 return 23;
510 case 'o':
511 case 'O':
512 return 24;
513 case 'p':
514 case 'P':
515 return 25;
516 case 'q':
517 case 'Q':
518 return 26;
519 case 'r':
520 case 'R':
521 return 27;
522 case 's':
523 case 'S':
524 return 28;
525 case 't':
526 case 'T':
527 return 29;
528 case 'u':
529 case 'U':
530 return 30;
531 case 'v':
532 case 'V':
533 return 31;
534 case 'w':
535 case 'W':
536 return 32;
537 case 'x':
538 case 'X':
539 return 33;
540 case 'y':
541 case 'Y':
542 return 34;
543 case 'z':
544 case 'Z':
545 return 35;
546 }
548 }
549
550 /// std::from_chars implementation for integers in bases 11 to 26.
551 template<typename _Tp>
552 bool
553 __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
554 int __base)
555 {
556 bool __valid = true;
557 while (__first != __last)
558 {
559 unsigned char __c = *__first;
560 if (std::isdigit(__c))
561 __c -= '0';
562 else
563 {
564 __c = __from_chars_alpha_to_num(__c);
565 if (__c >= __base)
566 break;
567 }
568
569 if (__builtin_expect(__valid, 1))
570 __valid = __raise_and_add(__val, __base, __c);
571 __first++;
572 }
573 return __valid;
574 }
575
576 template<typename _Tp>
577 using __integer_from_chars_result_type
579 __is_unsigned_integer<_Tp>,
582
583} // namespace __detail
584
585 /// std::from_chars for integral types.
586 template<typename _Tp>
587 __detail::__integer_from_chars_result_type<_Tp>
588 from_chars(const char* __first, const char* __last, _Tp& __value,
589 int __base = 10)
590 {
591 __glibcxx_assert(2 <= __base && __base <= 36);
592
593 from_chars_result __res{__first, {}};
594
595 int __sign = 1;
596 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
597 if (__first != __last && *__first == '-')
598 {
599 __sign = -1;
600 ++__first;
601 }
602
603 using _Up = __detail::__unsigned_least_t<_Tp>;
604 _Up __val = 0;
605
606 const auto __start = __first;
607 bool __valid;
608 if (__base == 2)
609 __valid = __detail::__from_chars_binary(__first, __last, __val);
610 else if (__base <= 10)
611 __valid = __detail::__from_chars_digit(__first, __last, __val, __base);
612 else
613 __valid = __detail::__from_chars_alnum(__first, __last, __val, __base);
614
615 if (__builtin_expect(__first == __start, 0))
616 __res.ec = errc::invalid_argument;
617 else
618 {
619 __res.ptr = __first;
620 if (!__valid)
621 __res.ec = errc::result_out_of_range;
622 else
623 {
624 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
625 {
626 _Tp __tmp;
627 if (__builtin_mul_overflow(__val, __sign, &__tmp))
628 __res.ec = errc::result_out_of_range;
629 else
630 __value = __tmp;
631 }
632 else
633 {
634 if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Up>::max()
636 {
638 __res.ec = errc::result_out_of_range;
639 else
640 __value = __val;
641 }
642 else
643 __value = __val;
644 }
645 }
646 }
647 return __res;
648 }
649
650 /// floating-point format for primitive numerical conversion
651 enum class chars_format
652 {
653 scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
654 };
655
656 constexpr chars_format
657 operator|(chars_format __lhs, chars_format __rhs) noexcept
658 { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
659
660 constexpr chars_format
661 operator&(chars_format __lhs, chars_format __rhs) noexcept
662 { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
663
664 constexpr chars_format
665 operator^(chars_format __lhs, chars_format __rhs) noexcept
666 { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
667
668 constexpr chars_format
669 operator~(chars_format __fmt) noexcept
670 { return (chars_format)~(unsigned)__fmt; }
671
672 constexpr chars_format&
673 operator|=(chars_format& __lhs, chars_format __rhs) noexcept
674 { return __lhs = __lhs | __rhs; }
675
676 constexpr chars_format&
677 operator&=(chars_format& __lhs, chars_format __rhs) noexcept
678 { return __lhs = __lhs & __rhs; }
679
680 constexpr chars_format&
681 operator^=(chars_format& __lhs, chars_format __rhs) noexcept
682 { return __lhs = __lhs ^ __rhs; }
683
684_GLIBCXX_END_NAMESPACE_VERSION
685} // namespace std
686#endif // C++14
687#endif // _GLIBCXX_CHARCONV
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition: type_traits:2541
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:254
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:1056
ios_base & hex(ios_base &__base)
Calls base.setf(ios_base::hex, ios_base::basefield).
Definition: ios_base.h:1031
chars_format
floating-point format for primitive numerical conversion
Definition: charconv:652
bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1433
bool isdigit(_CharT __c, const locale &__loc)
Convenience interface to ctype.is(ctype_base::digit, __c).
__detail::__integer_from_chars_result_type< _Tp > from_chars(const char *__first, const char *__last, _Tp &__value, int __base=10)
std::from_chars for integral types.
Definition: charconv:588
ios_base & fixed(ios_base &__base)
Calls base.setf(ios_base::fixed, ios_base::floatfield).
Definition: ios_base.h:1048
bool __from_chars_alnum(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in bases 11 to 26.
Definition: charconv:553
bool __from_chars_binary(const char *&__first, const char *__last, _Tp &__val)
std::from_chars implementation for integers in base 2.
Definition: charconv:411
bool __from_chars_digit(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in bases 3 to 10.
Definition: charconv:434
constexpr _Iterator __base(_Iterator __it)
Result type of std::to_chars.
Definition: charconv:56
Result type of std::from_chars.
Definition: charconv:68
is_integral
Definition: type_traits:367
is_same
Definition: type_traits:1388