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