]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/std/charconv
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / charconv
1 // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2
3 // Copyright (C) 2017-2018 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 #if __cplusplus >= 201402L
35
36 #include <type_traits>
37 #include <limits>
38 #include <cctype>
39 #include <bits/error_constants.h> // for std::errc
40
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /// Result type of std::to_chars
46 struct to_chars_result
47 {
48 char* ptr;
49 errc ec;
50 };
51
52 /// Result type of std::from_chars
53 struct from_chars_result
54 {
55 const char* ptr;
56 errc ec;
57 };
58
59 namespace __detail
60 {
61 template<typename _Tp, typename... _Types>
62 using __is_one_of = __or_<is_same<_Tp, _Types>...>;
63
64 template<typename _Tp>
65 using __is_int_to_chars_type = __and_<is_integral<_Tp>,
66 __not_<__is_one_of<_Tp, bool, char16_t, char32_t
67 #if _GLIBCXX_USE_WCHAR_T
68 , wchar_t
69 #endif
70 >>>;
71
72 template<typename _Tp>
73 using __integer_to_chars_result_type
74 = enable_if_t<__is_int_to_chars_type<_Tp>::value, to_chars_result>;
75
76 template<typename _Tp>
77 using __unsigned_least_t
78 = conditional_t<(sizeof(_Tp) <= sizeof(int)), unsigned int,
79 conditional_t<(sizeof(_Tp) <= sizeof(long)), unsigned long,
80 conditional_t<(sizeof(_Tp) <= sizeof(long long)), unsigned long long,
81 #if _GLIBCXX_USE_INT128
82 conditional_t<(sizeof(_Tp) <= sizeof(__int128)), unsigned __int128,
83 #endif
84 void
85 #if _GLIBCXX_USE_INT128
86 >
87 #endif
88 >>>;
89
90 // Generic implementation for arbitrary bases.
91 template<typename _Tp>
92 constexpr unsigned
93 __to_chars_len(_Tp __value, int __base = 10) noexcept
94 {
95 static_assert(is_integral<_Tp>::value, "implementation bug");
96 static_assert(is_unsigned<_Tp>::value, "implementation bug");
97
98 unsigned __n = 1;
99 const int __b2 = __base * __base;
100 const int __b3 = __b2 * __base;
101 const int __b4 = __b3 * __base;
102 for (;;)
103 {
104 if (__value < __base) return __n;
105 if (__value < __b2) return __n + 1;
106 if (__value < __b3) return __n + 2;
107 if (__value < __b4) return __n + 3;
108 __value /= (unsigned)__b4;
109 __n += 4;
110 }
111 }
112
113 template<typename _Tp>
114 constexpr unsigned
115 __to_chars_len_2(_Tp __value) noexcept
116 {
117 static_assert(is_integral<_Tp>::value, "implementation bug");
118 static_assert(is_unsigned<_Tp>::value, "implementation bug");
119
120 constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp);
121
122 // N.B. __builtin_clzll is undefined if __value == 0, but std::to_chars
123 // handles zero values directly.
124
125 // For sizeof(_Tp) > 1 this is an order of magnitude faster than
126 // the generic __to_chars_len.
127 return __nbits
128 - (__builtin_clzll(__value)
129 - ((__CHAR_BIT__ * sizeof(long long)) - __nbits));
130 }
131
132 template<typename _Tp>
133 constexpr unsigned
134 __to_chars_len_8(_Tp __value) noexcept
135 {
136 static_assert(is_integral<_Tp>::value, "implementation bug");
137 static_assert(is_unsigned<_Tp>::value, "implementation bug");
138
139 constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp);
140
141 if _GLIBCXX17_CONSTEXPR (__nbits <= 16)
142 {
143 return __value > 077777u ? 6u
144 : __value > 07777u ? 5u
145 : __value > 0777u ? 4u
146 : __value > 077u ? 3u
147 : __value > 07u ? 2u
148 : 1u;
149 }
150 else
151 return __to_chars_len(__value, 8);
152 }
153
154 // Generic implementation for arbitrary bases.
155 template<typename _Tp>
156 to_chars_result
157 __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
158 {
159 static_assert(is_integral<_Tp>::value, "implementation bug");
160 static_assert(is_unsigned<_Tp>::value, "implementation bug");
161
162 to_chars_result __res;
163
164 const unsigned __len = __to_chars_len(__val, __base);
165
166 if (__builtin_expect((__last - __first) < __len, 0))
167 {
168 __res.ptr = __last;
169 __res.ec = errc::value_too_large;
170 return __res;
171 }
172
173 unsigned __pos = __len - 1;
174
175 static constexpr char __digits[]
176 = "0123456789abcdefghijklmnopqrstuvwxyz";
177
178 while (__val >= __base)
179 {
180 auto const __quo = __val / __base;
181 auto const __rem = __val % __base;
182 __first[__pos--] = __digits[__rem];
183 __val = __quo;
184 }
185 *__first = __digits[__val];
186
187 __res.ptr = __first + __len;
188 __res.ec = {};
189 return __res;
190 }
191
192 template<typename _Tp>
193 __integer_to_chars_result_type<_Tp>
194 __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
195 {
196 static_assert(is_integral<_Tp>::value, "implementation bug");
197 static_assert(is_unsigned<_Tp>::value, "implementation bug");
198
199 to_chars_result __res;
200
201 const unsigned __len = __to_chars_len(__val, 0x10);
202
203 if (__builtin_expect((__last - __first) < __len, 0))
204 {
205 __res.ptr = __last;
206 __res.ec = errc::value_too_large;
207 return __res;
208 }
209
210 static constexpr char __digits[513] =
211 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
212 "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
213 "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
214 "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
215 "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
216 "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
217 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
218 "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
219 unsigned __pos = __len - 1;
220 while (__val >= 0x100)
221 {
222 auto const __num = (__val % 0x100) * 2;
223 __val /= 0x100;
224 __first[__pos] = __digits[__num + 1];
225 __first[__pos - 1] = __digits[__num];
226 __pos -= 2;
227 }
228 if (__val >= 0x10)
229 {
230 auto const __num = __val * 2;
231 __first[__pos] = __digits[__num + 1];
232 __first[__pos - 1] = __digits[__num];
233 }
234 else
235 __first[__pos] = "0123456789abcdef"[__val];
236 __res.ptr = __first + __len;
237 __res.ec = {};
238 return __res;
239 }
240
241 template<typename _Tp>
242 __integer_to_chars_result_type<_Tp>
243 __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
244 {
245 static_assert(is_integral<_Tp>::value, "implementation bug");
246 static_assert(is_unsigned<_Tp>::value, "implementation bug");
247
248 to_chars_result __res;
249
250 const unsigned __len = __to_chars_len(__val, 10);
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 static constexpr char __digits[201] =
260 "0001020304050607080910111213141516171819"
261 "2021222324252627282930313233343536373839"
262 "4041424344454647484950515253545556575859"
263 "6061626364656667686970717273747576777879"
264 "8081828384858687888990919293949596979899";
265 unsigned __pos = __len - 1;
266 while (__val >= 100)
267 {
268 auto const __num = (__val % 100) * 2;
269 __val /= 100;
270 __first[__pos] = __digits[__num + 1];
271 __first[__pos - 1] = __digits[__num];
272 __pos -= 2;
273 }
274 if (__val >= 10)
275 {
276 auto const __num = __val * 2;
277 __first[__pos] = __digits[__num + 1];
278 __first[__pos - 1] = __digits[__num];
279 }
280 else
281 __first[__pos] = '0' + __val;
282 __res.ptr = __first + __len;
283 __res.ec = {};
284 return __res;
285 }
286
287 template<typename _Tp>
288 __integer_to_chars_result_type<_Tp>
289 __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
290 {
291 static_assert(is_integral<_Tp>::value, "implementation bug");
292 static_assert(is_unsigned<_Tp>::value, "implementation bug");
293
294 to_chars_result __res;
295
296 const unsigned __len = __to_chars_len_8(__val);
297
298 if (__builtin_expect((__last - __first) < __len, 0))
299 {
300 __res.ptr = __last;
301 __res.ec = errc::value_too_large;
302 return __res;
303 }
304
305 static constexpr char __digits[129] =
306 "00010203040506071011121314151617"
307 "20212223242526273031323334353637"
308 "40414243444546475051525354555657"
309 "60616263646566677071727374757677";
310 unsigned __pos = __len - 1;
311 while (__val >= 0100)
312 {
313 auto const __num = (__val % 0100) * 2;
314 __val /= 0100;
315 __first[__pos] = __digits[__num + 1];
316 __first[__pos - 1] = __digits[__num];
317 __pos -= 2;
318 }
319 if (__val >= 010)
320 {
321 auto const __num = __val * 2;
322 __first[__pos] = __digits[__num + 1];
323 __first[__pos - 1] = __digits[__num];
324 }
325 else
326 __first[__pos] = '0' + __val;
327 __res.ptr = __first + __len;
328 __res.ec = {};
329 return __res;
330 }
331
332 template<typename _Tp>
333 __integer_to_chars_result_type<_Tp>
334 __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
335 {
336 static_assert(is_integral<_Tp>::value, "implementation bug");
337 static_assert(is_unsigned<_Tp>::value, "implementation bug");
338
339 to_chars_result __res;
340
341 const unsigned __len = __to_chars_len_2(__val);
342
343 if (__builtin_expect((__last - __first) < __len, 0))
344 {
345 __res.ptr = __last;
346 __res.ec = errc::value_too_large;
347 return __res;
348 }
349
350 unsigned __pos = __len - 1;
351
352 while (__pos)
353 {
354 __first[__pos--] = '0' + (__val & 1);
355 __val >>= 1;
356 }
357 *__first = '0' + (__val & 1);
358
359 __res.ptr = __first + __len;
360 __res.ec = {};
361 return __res;
362 }
363
364 } // namespace __detail
365
366 template<typename _Tp>
367 __detail::__integer_to_chars_result_type<_Tp>
368 to_chars(char* __first, char* __last, _Tp __value, int __base = 10)
369 {
370 __glibcxx_assert(2 <= __base && __base <= 36);
371
372 using _Up = __detail::__unsigned_least_t<_Tp>;
373 _Up __unsigned_val = __value;
374
375 if (__value == 0 && __first != __last)
376 {
377 *__first = '0';
378 return { __first + 1, errc{} };
379 }
380
381 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
382 if (__value < 0)
383 {
384 if (__builtin_expect(__first != __last, 1))
385 *__first++ = '-';
386 __unsigned_val = _Up(~__value) + _Up(1);
387 }
388
389 switch (__base)
390 {
391 case 16:
392 return __detail::__to_chars_16(__first, __last, __unsigned_val);
393 case 10:
394 return __detail::__to_chars_10(__first, __last, __unsigned_val);
395 case 8:
396 return __detail::__to_chars_8(__first, __last, __unsigned_val);
397 case 2:
398 return __detail::__to_chars_2(__first, __last, __unsigned_val);
399 default:
400 return __detail::__to_chars(__first, __last, __unsigned_val, __base);
401 }
402 }
403
404 namespace __detail
405 {
406 template<typename _Tp>
407 bool
408 __raise_and_add(_Tp& __val, int __base, unsigned char __c)
409 {
410 if (__builtin_mul_overflow(__val, __base, &__val)
411 || __builtin_add_overflow(__val, __c, &__val))
412 return false;
413 return true;
414 }
415
416 /// std::from_chars implementation for integers in base 2.
417 template<typename _Tp>
418 bool
419 __from_chars_binary(const char*& __first, const char* __last, _Tp& __val)
420 {
421 static_assert(is_integral<_Tp>::value, "implementation bug");
422 static_assert(is_unsigned<_Tp>::value, "implementation bug");
423
424 const ptrdiff_t __len = __last - __first;
425 int __i = 0;
426 while (__i < __len)
427 {
428 const unsigned char __c = (unsigned)__first[__i] - '0';
429 if (__c < 2)
430 __val = (__val << 1) | __c;
431 else
432 break;
433 __i++;
434 }
435 __first += __i;
436 return __i <= (sizeof(_Tp) * __CHAR_BIT__);
437 }
438
439 /// std::from_chars implementation for integers in bases 3 to 10.
440 template<typename _Tp>
441 bool
442 __from_chars_digit(const char*& __first, const char* __last, _Tp& __val,
443 int __base)
444 {
445 static_assert(is_integral<_Tp>::value, "implementation bug");
446 static_assert(is_unsigned<_Tp>::value, "implementation bug");
447
448 auto __matches = [__base](char __c) {
449 return '0' <= __c && __c <= ('0' + (__base - 1));
450 };
451
452 while (__first != __last)
453 {
454 const char __c = *__first;
455 if (__matches(__c))
456 {
457 if (!__raise_and_add(__val, __base, __c - '0'))
458 {
459 while (++__first != __last && __matches(*__first))
460 ;
461 return false;
462 }
463 __first++;
464 }
465 else
466 return true;
467 }
468 return true;
469 }
470
471 constexpr unsigned char
472 __from_chars_alpha_to_num(char __c)
473 {
474 switch (__c)
475 {
476 case 'a':
477 case 'A':
478 return 10;
479 case 'b':
480 case 'B':
481 return 11;
482 case 'c':
483 case 'C':
484 return 12;
485 case 'd':
486 case 'D':
487 return 13;
488 case 'e':
489 case 'E':
490 return 14;
491 case 'f':
492 case 'F':
493 return 15;
494 case 'g':
495 case 'G':
496 return 16;
497 case 'h':
498 case 'H':
499 return 17;
500 case 'i':
501 case 'I':
502 return 18;
503 case 'j':
504 case 'J':
505 return 19;
506 case 'k':
507 case 'K':
508 return 20;
509 case 'l':
510 case 'L':
511 return 21;
512 case 'm':
513 case 'M':
514 return 22;
515 case 'n':
516 case 'N':
517 return 23;
518 case 'o':
519 case 'O':
520 return 24;
521 case 'p':
522 case 'P':
523 return 25;
524 case 'q':
525 case 'Q':
526 return 26;
527 case 'r':
528 case 'R':
529 return 27;
530 case 's':
531 case 'S':
532 return 28;
533 case 't':
534 case 'T':
535 return 29;
536 case 'u':
537 case 'U':
538 return 30;
539 case 'v':
540 case 'V':
541 return 31;
542 case 'w':
543 case 'W':
544 return 32;
545 case 'x':
546 case 'X':
547 return 33;
548 case 'y':
549 case 'Y':
550 return 34;
551 case 'z':
552 case 'Z':
553 return 35;
554 }
555 return std::numeric_limits<unsigned char>::max();
556 }
557
558 /// std::from_chars implementation for integers in bases 11 to 26.
559 template<typename _Tp>
560 bool
561 __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
562 int __base)
563 {
564 bool __valid = true;
565 while (__first != __last)
566 {
567 unsigned char __c = *__first;
568 if (std::isdigit(__c))
569 __c -= '0';
570 else
571 {
572 __c = __from_chars_alpha_to_num(__c);
573 if (__c >= __base)
574 break;
575 }
576
577 if (__builtin_expect(__valid, 1))
578 __valid = __raise_and_add(__val, __base, __c);
579 __first++;
580 }
581 return __valid;
582 }
583
584 template<typename _Tp>
585 using __integer_from_chars_result_type
586 = enable_if_t<__is_int_to_chars_type<_Tp>::value, 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 from_chars(const char* __first, const char* __last, _Tp& __value,
594 int __base = 10)
595 {
596 __glibcxx_assert(2 <= __base && __base <= 36);
597
598 from_chars_result __res{__first, {}};
599
600 int __sign = 1;
601 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
602 if (__first != __last && *__first == '-')
603 {
604 __sign = -1;
605 ++__first;
606 }
607
608 using _Up = __detail::__unsigned_least_t<_Tp>;
609 _Up __val = 0;
610
611 const auto __start = __first;
612 bool __valid;
613 if (__base == 2)
614 __valid = __detail::__from_chars_binary(__first, __last, __val);
615 else if (__base <= 10)
616 __valid = __detail::__from_chars_digit(__first, __last, __val, __base);
617 else
618 __valid = __detail::__from_chars_alnum(__first, __last, __val, __base);
619
620 if (__builtin_expect(__first == __start, 0))
621 __res.ec = errc::invalid_argument;
622 else
623 {
624 __res.ptr = __first;
625 if (!__valid)
626 __res.ec = errc::result_out_of_range;
627 else
628 {
629 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
630 {
631 _Tp __tmp;
632 if (__builtin_mul_overflow(__val, __sign, &__tmp))
633 __res.ec = errc::result_out_of_range;
634 else
635 __value = __tmp;
636 }
637 else
638 {
639 if _GLIBCXX17_CONSTEXPR
640 (numeric_limits<_Up>::max() > numeric_limits<_Tp>::max())
641 {
642 if (__val > numeric_limits<_Tp>::max())
643 __res.ec = errc::result_out_of_range;
644 else
645 __value = __val;
646 }
647 else
648 __value = __val;
649 }
650 }
651 }
652 return __res;
653 }
654
655 _GLIBCXX_END_NAMESPACE_VERSION
656 } // namespace std
657 #endif // C++14
658 #endif // _GLIBCXX_CHARCONV