29 #ifndef _GLIBCXX_CHARCONV
30 #define _GLIBCXX_CHARCONV 1
32 #pragma GCC system_header
38 #if __cplusplus >= 201402L
49 namespace std _GLIBCXX_VISIBILITY(default)
51 _GLIBCXX_BEGIN_NAMESPACE_VERSION
69 template<
typename _Tp>
70 using __integer_to_chars_result_type
72 __is_unsigned_integer<_Tp>,
81 template<
typename _Tp>
82 struct __to_chars_unsigned_type : __make_unsigned_selector_base
84 using _UInts = _List<
unsigned int,
unsigned long,
unsigned long long
85 #if _GLIBCXX_USE_INT128
89 using type =
typename __select<
sizeof(_Tp), _UInts>::__type;
92 template<
typename _Tp>
93 using __unsigned_least_t =
typename __to_chars_unsigned_type<_Tp>::type;
97 template<
typename _Tp>
99 __to_chars_len(_Tp __value,
int __base ) noexcept;
101 template<
typename _Tp>
103 __to_chars_len_2(_Tp __value) noexcept
104 {
return std::__bit_width(__value); }
107 template<
typename _Tp>
109 __to_chars(
char* __first,
char* __last, _Tp __val,
int __base) noexcept
111 static_assert(is_integral<_Tp>::value,
"implementation bug");
112 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
114 to_chars_result __res;
116 const unsigned __len = __to_chars_len(__val,
__base);
118 if (__builtin_expect((__last - __first) < __len, 0))
121 __res.ec = errc::value_too_large;
125 unsigned __pos = __len - 1;
127 static constexpr
char __digits[] = {
128 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
129 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
130 'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
131 'u',
'v',
'w',
'x',
'y',
'z'
136 auto const __quo = __val /
__base;
137 auto const __rem = __val %
__base;
138 __first[__pos--] = __digits[__rem];
141 *__first = __digits[__val];
143 __res.ptr = __first + __len;
148 template<
typename _Tp>
149 __integer_to_chars_result_type<_Tp>
150 __to_chars_16(
char* __first,
char* __last, _Tp __val) noexcept
152 static_assert(is_integral<_Tp>::value,
"implementation bug");
153 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
155 to_chars_result __res;
157 const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
159 if (__builtin_expect((__last - __first) < __len, 0))
162 __res.ec = errc::value_too_large;
166 static constexpr
char __digits[] = {
167 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
168 'a',
'b',
'c',
'd',
'e',
'f'
170 unsigned __pos = __len - 1;
171 while (__val >= 0x100)
173 auto __num = __val & 0xF;
175 __first[__pos] = __digits[__num];
178 __first[__pos - 1] = __digits[__num];
183 const auto __num = __val & 0xF;
185 __first[1] = __digits[__num];
186 __first[0] = __digits[__val];
189 __first[0] = __digits[__val];
190 __res.ptr = __first + __len;
195 template<
typename _Tp>
196 inline __integer_to_chars_result_type<_Tp>
197 __to_chars_10(
char* __first,
char* __last, _Tp __val) noexcept
199 static_assert(is_integral<_Tp>::value,
"implementation bug");
200 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
202 to_chars_result __res;
204 const unsigned __len = __to_chars_len(__val, 10);
206 if (__builtin_expect((__last - __first) < __len, 0))
209 __res.ec = errc::value_too_large;
213 __detail::__to_chars_10_impl(__first, __len, __val);
214 __res.ptr = __first + __len;
219 template<
typename _Tp>
220 __integer_to_chars_result_type<_Tp>
221 __to_chars_8(
char* __first,
char* __last, _Tp __val) noexcept
223 static_assert(is_integral<_Tp>::value,
"implementation bug");
224 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
226 to_chars_result __res;
229 if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Tp>::digits <= 16)
231 __len = __val > 077777u ? 6u
232 : __val > 07777u ? 5u
239 __len = (__to_chars_len_2(__val) + 2) / 3;
241 if (__builtin_expect((__last - __first) < __len, 0))
244 __res.ec = errc::value_too_large;
248 unsigned __pos = __len - 1;
249 while (__val >= 0100)
251 auto __num = __val & 7;
253 __first[__pos] =
'0' + __num;
256 __first[__pos - 1] =
'0' + __num;
261 auto const __num = __val & 7;
263 __first[1] =
'0' + __num;
264 __first[0] =
'0' + __val;
267 __first[0] =
'0' + __val;
268 __res.ptr = __first + __len;
273 template<
typename _Tp>
274 __integer_to_chars_result_type<_Tp>
275 __to_chars_2(
char* __first,
char* __last, _Tp __val) noexcept
277 static_assert(is_integral<_Tp>::value,
"implementation bug");
278 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
280 to_chars_result __res;
282 const unsigned __len = __to_chars_len_2(__val);
284 if (__builtin_expect((__last - __first) < __len, 0))
287 __res.ec = errc::value_too_large;
291 unsigned __pos = __len - 1;
295 __first[__pos--] =
'0' + (__val & 1);
303 __res.ptr = __first + __len;
310 template<
typename _Tp>
311 __detail::__integer_to_chars_result_type<_Tp>
312 __to_chars_i(
char* __first,
char* __last, _Tp __value,
int __base = 10)
316 using _Up = __detail::__unsigned_least_t<_Tp>;
317 _Up __unsigned_val = __value;
319 if (__value == 0 && __first != __last)
322 return { __first + 1, errc{} };
325 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
328 if (__builtin_expect(__first != __last, 1))
330 __unsigned_val = _Up(~__value) + _Up(1);
336 return __detail::__to_chars_16(__first, __last, __unsigned_val);
338 return __detail::__to_chars_10(__first, __last, __unsigned_val);
340 return __detail::__to_chars_8(__first, __last, __unsigned_val);
342 return __detail::__to_chars_2(__first, __last, __unsigned_val);
344 return __detail::__to_chars(__first, __last, __unsigned_val,
__base);
348 #define _GLIBCXX_TO_CHARS(T) \
349 inline to_chars_result \
350 to_chars(char* __first, char* __last, T __value, int __base = 10) \
351 { return std::__to_chars_i<T>(__first, __last, __value, __base); }
352 _GLIBCXX_TO_CHARS(
char)
353 _GLIBCXX_TO_CHARS(
signed char)
354 _GLIBCXX_TO_CHARS(
unsigned char)
355 _GLIBCXX_TO_CHARS(
signed short)
356 _GLIBCXX_TO_CHARS(
unsigned short)
357 _GLIBCXX_TO_CHARS(
signed int)
358 _GLIBCXX_TO_CHARS(
unsigned int)
359 _GLIBCXX_TO_CHARS(
signed long)
360 _GLIBCXX_TO_CHARS(
unsigned long)
361 _GLIBCXX_TO_CHARS(
signed long long)
362 _GLIBCXX_TO_CHARS(
unsigned long long)
363 #if defined(__GLIBCXX_TYPE_INT_N_0)
364 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_0)
365 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_0)
367 #if defined(__GLIBCXX_TYPE_INT_N_1)
368 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_1)
369 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_1)
371 #if defined(__GLIBCXX_TYPE_INT_N_2)
372 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_2)
373 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_2)
375 #if defined(__GLIBCXX_TYPE_INT_N_3)
376 _GLIBCXX_TO_CHARS(
signed __GLIBCXX_TYPE_INT_N_3)
377 _GLIBCXX_TO_CHARS(
unsigned __GLIBCXX_TYPE_INT_N_3)
379 #undef _GLIBCXX_TO_CHARS
383 to_chars_result to_chars(
char*,
char*,
bool,
int = 10) =
delete;
387 template<
typename _Tp>
389 __raise_and_add(_Tp& __val,
int __base,
unsigned char __c)
391 if (__builtin_mul_overflow(__val,
__base, &__val)
392 || __builtin_add_overflow(__val, __c, &__val))
398 template<
typename _Tp>
403 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
405 const ptrdiff_t __len = __last - __first;
409 const unsigned char __c = (unsigned)__first[__i] -
'0';
411 __val = (__val << 1) | __c;
417 return __i <= __detail::__int_limits<_Tp>::digits;
421 template<
typename _Tp>
427 static_assert(is_unsigned<_Tp>::value,
"implementation bug");
429 auto __matches = [
__base](
char __c) {
430 return '0' <= __c && __c <= (
'0' + (
__base - 1));
433 while (__first != __last)
435 const char __c = *__first;
438 if (!__raise_and_add(__val,
__base, __c -
'0'))
440 while (++__first != __last && __matches(*__first))
452 constexpr
unsigned char
453 __from_chars_alpha_to_num(
char __c)
540 template<
typename _Tp>
546 while (__first != __last)
548 unsigned char __c = *__first;
553 __c = __from_chars_alpha_to_num(__c);
558 if (__builtin_expect(__valid, 1))
559 __valid = __raise_and_add(__val,
__base, __c);
565 template<
typename _Tp>
566 using __integer_from_chars_result_type
568 __is_unsigned_integer<_Tp>,
575 template<
typename _Tp>
576 __detail::__integer_from_chars_result_type<_Tp>
577 from_chars(
const char* __first,
const char* __last, _Tp& __value,
585 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
586 if (__first != __last && *__first ==
'-')
592 using _Up = __detail::__unsigned_least_t<_Tp>;
595 const auto __start = __first;
604 if (__builtin_expect(__first == __start, 0))
605 __res.ec = errc::invalid_argument;
610 __res.ec = errc::result_out_of_range;
613 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
616 if (__builtin_mul_overflow(__val, __sign, &__tmp))
617 __res.ec = errc::result_out_of_range;
627 __res.ec = errc::result_out_of_range;
647 {
return (
chars_format)((unsigned)__lhs | (
unsigned)__rhs); }
651 {
return (
chars_format)((unsigned)__lhs & (
unsigned)__rhs); }
655 {
return (
chars_format)((unsigned)__lhs ^ (
unsigned)__rhs); }
663 {
return __lhs = __lhs | __rhs; }
667 {
return __lhs = __lhs & __rhs; }
671 {
return __lhs = __lhs ^ __rhs; }
673 _GLIBCXX_END_NAMESPACE_VERSION
676 #endif // _GLIBCXX_CHARCONV