29 #ifndef _GLIBCXX_CHARCONV
30 #define _GLIBCXX_CHARCONV 1
32 #pragma GCC system_header
34 #if __cplusplus >= 201402L
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
65 template<
typename _Tp>
66 using __integer_to_chars_result_type
68 __is_unsigned_integer<_Tp>,
77 template<
typename _Tp>
78 struct __to_chars_unsigned_type : __make_unsigned_selector_base
80 using _UInts = _List<
unsigned int,
unsigned long,
unsigned long long
81 #if _GLIBCXX_USE_INT128
85 using type =
typename __select<
sizeof(_Tp), _UInts>::__type;
88 template<
typename _Tp>
89 using __unsigned_least_t =
typename __to_chars_unsigned_type<_Tp>::type;
93 template<
typename _Tp>
95 __to_chars_len(_Tp __value,
int __base ) noexcept;
97 template<
typename _Tp>
99 __to_chars_len_2(_Tp __value) noexcept
100 {
return std::__log2p1(__value); }
103 template<
typename _Tp>
105 __to_chars(
char* __first,
char* __last, _Tp __val,
int __base) noexcept
107 static_assert(is_integral<_Tp>::value,
"implementation bug");
108 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
110 to_chars_result __res;
112 const unsigned __len = __to_chars_len(__val,
__base);
114 if (__builtin_expect((__last - __first) < __len, 0))
117 __res.ec = errc::value_too_large;
121 unsigned __pos = __len - 1;
123 static constexpr
char __digits[] = {
124 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
125 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
126 'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
127 'u',
'v',
'w',
'x',
'y',
'z'
132 auto const __quo = __val /
__base;
133 auto const __rem = __val %
__base;
134 __first[__pos--] = __digits[__rem];
137 *__first = __digits[__val];
139 __res.ptr = __first + __len;
144 template<
typename _Tp>
145 __integer_to_chars_result_type<_Tp>
146 __to_chars_16(
char* __first,
char* __last, _Tp __val) noexcept
148 static_assert(is_integral<_Tp>::value,
"implementation bug");
149 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
151 to_chars_result __res;
153 const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
155 if (__builtin_expect((__last - __first) < __len, 0))
158 __res.ec = errc::value_too_large;
162 static constexpr
char __digits[] = {
163 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
164 'a',
'b',
'c',
'd',
'e',
'f'
166 unsigned __pos = __len - 1;
167 while (__val >= 0x100)
169 auto __num = __val & 0xF;
171 __first[__pos] = __digits[__num];
174 __first[__pos - 1] = __digits[__num];
179 const auto __num = __val & 0xF;
181 __first[1] = __digits[__num];
182 __first[0] = __digits[__val];
185 __first[0] = __digits[__val];
186 __res.ptr = __first + __len;
191 template<
typename _Tp>
192 inline __integer_to_chars_result_type<_Tp>
193 __to_chars_10(
char* __first,
char* __last, _Tp __val) noexcept
195 static_assert(is_integral<_Tp>::value,
"implementation bug");
196 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
198 to_chars_result __res;
200 const unsigned __len = __to_chars_len(__val, 10);
202 if (__builtin_expect((__last - __first) < __len, 0))
205 __res.ec = errc::value_too_large;
209 __detail::__to_chars_10_impl(__first, __len, __val);
210 __res.ptr = __first + __len;
215 template<
typename _Tp>
216 __integer_to_chars_result_type<_Tp>
217 __to_chars_8(
char* __first,
char* __last, _Tp __val) noexcept
219 static_assert(is_integral<_Tp>::value,
"implementation bug");
220 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
222 to_chars_result __res;
227 __len = __val > 077777u ? 6u
228 : __val > 07777u ? 5u
235 __len = (__to_chars_len_2(__val) + 2) / 3;
237 if (__builtin_expect((__last - __first) < __len, 0))
240 __res.ec = errc::value_too_large;
244 unsigned __pos = __len - 1;
245 while (__val >= 0100)
247 auto __num = __val & 7;
249 __first[__pos] =
'0' + __num;
252 __first[__pos - 1] =
'0' + __num;
257 auto const __num = __val & 7;
259 __first[1] =
'0' + __num;
260 __first[0] =
'0' + __val;
263 __first[0] =
'0' + __val;
264 __res.ptr = __first + __len;
269 template<
typename _Tp>
270 __integer_to_chars_result_type<_Tp>
271 __to_chars_2(
char* __first,
char* __last, _Tp __val) noexcept
273 static_assert(is_integral<_Tp>::value,
"implementation bug");
274 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
276 to_chars_result __res;
278 const unsigned __len = __to_chars_len_2(__val);
280 if (__builtin_expect((__last - __first) < __len, 0))
283 __res.ec = errc::value_too_large;
287 unsigned __pos = __len - 1;
291 __first[__pos--] =
'0' + (__val & 1);
299 __res.ptr = __first + __len;
306 template<
typename _Tp>
307 __detail::__integer_to_chars_result_type<_Tp>
308 __to_chars_i(
char* __first,
char* __last, _Tp __value,
int __base = 10)
312 using _Up = __detail::__unsigned_least_t<_Tp>;
313 _Up __unsigned_val = __value;
315 if (__value == 0 && __first != __last)
318 return { __first + 1, errc{} };
321 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
324 if (__builtin_expect(__first != __last, 1))
326 __unsigned_val = _Up(~__value) + _Up(1);
332 return __detail::__to_chars_16(__first, __last, __unsigned_val);
334 return __detail::__to_chars_10(__first, __last, __unsigned_val);
336 return __detail::__to_chars_8(__first, __last, __unsigned_val);
338 return __detail::__to_chars_2(__first, __last, __unsigned_val);
340 return __detail::__to_chars(__first, __last, __unsigned_val,
__base);
344 #define _GLIBCXX_TO_CHARS(T) \
345 inline to_chars_result \
346 to_chars(char* __first, char* __last, T __value, int __base = 10) \
347 { return std::__to_chars_i<T>(__first, __last, __value, __base); }
348 _GLIBCXX_TO_CHARS(
char)
349 _GLIBCXX_TO_CHARS(
signed char)
350 _GLIBCXX_TO_CHARS(
unsigned char)
351 _GLIBCXX_TO_CHARS(
signed short)
352 _GLIBCXX_TO_CHARS(
unsigned short)
353 _GLIBCXX_TO_CHARS(
signed int)
354 _GLIBCXX_TO_CHARS(
unsigned int)
355 _GLIBCXX_TO_CHARS(
signed long)
356 _GLIBCXX_TO_CHARS(
unsigned long)
357 _GLIBCXX_TO_CHARS(
signed long long)
358 _GLIBCXX_TO_CHARS(
unsigned long long)
359 #if defined(__GLIBCXX_TYPE_INT_N_0)
360 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_0)
361 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_0)
363 #if defined(__GLIBCXX_TYPE_INT_N_1)
364 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_1)
365 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_1)
367 #if defined(__GLIBCXX_TYPE_INT_N_2)
368 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_2)
369 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_2)
371 #if defined(__GLIBCXX_TYPE_INT_N_3)
372 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_3)
373 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_3)
375 #undef _GLIBCXX_TO_CHARS
379 to_chars_result to_chars(
char*,
char*,
bool,
int = 10) =
delete;
383 template<
typename _Tp>
385 __raise_and_add(_Tp& __val,
int __base,
unsigned char __c)
387 if (__builtin_mul_overflow(__val,
__base, &__val)
388 || __builtin_add_overflow(__val, __c, &__val))
394 template<
typename _Tp>
399 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
401 const ptrdiff_t __len = __last - __first;
405 const unsigned char __c = (unsigned)__first[__i] -
'0';
407 __val = (__val << 1) | __c;
413 return __i <= numeric_limits<_Tp>::digits;
417 template<
typename _Tp>
423 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
425 auto __matches = [
__base](
char __c) {
426 return '0' <= __c && __c <= (
'0' + (
__base - 1));
429 while (__first != __last)
431 const char __c = *__first;
434 if (!__raise_and_add(__val,
__base, __c -
'0'))
436 while (++__first != __last && __matches(*__first))
448 constexpr
unsigned char
449 __from_chars_alpha_to_num(
char __c)
536 template<
typename _Tp>
542 while (__first != __last)
544 unsigned char __c = *__first;
549 __c = __from_chars_alpha_to_num(__c);
554 if (__builtin_expect(__valid, 1))
555 __valid = __raise_and_add(__val,
__base, __c);
561 template<
typename _Tp>
562 using __integer_from_chars_result_type
564 __is_unsigned_integer<_Tp>,
571 template<
typename _Tp>
572 __detail::__integer_from_chars_result_type<_Tp>
573 from_chars(
const char* __first,
const char* __last, _Tp& __value,
581 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
582 if (__first != __last && *__first ==
'-')
588 using _Up = __detail::__unsigned_least_t<_Tp>;
591 const auto __start = __first;
600 if (__builtin_expect(__first == __start, 0))
601 __res.ec = errc::invalid_argument;
606 __res.ec = errc::result_out_of_range;
609 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
612 if (__builtin_mul_overflow(__val, __sign, &__tmp))
613 __res.ec = errc::result_out_of_range;
619 if _GLIBCXX17_CONSTEXPR
623 __res.ec = errc::result_out_of_range;
643 {
return (
chars_format)((unsigned)__lhs | (
unsigned)__rhs); }
647 {
return (
chars_format)((unsigned)__lhs & (
unsigned)__rhs); }
651 {
return (
chars_format)((unsigned)__lhs ^ (
unsigned)__rhs); }
659 {
return __lhs = __lhs | __rhs; }
663 {
return __lhs = __lhs & __rhs; }
667 {
return __lhs = __lhs ^ __rhs; }
669 _GLIBCXX_END_NAMESPACE_VERSION
672 #endif // _GLIBCXX_CHARCONV