106c3fb27SDimitry Andric // -*- C++ -*- 206c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 306c3fb27SDimitry Andric // 406c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 506c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 606c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 706c3fb27SDimitry Andric // 806c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 906c3fb27SDimitry Andric 1006c3fb27SDimitry Andric #ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H 1106c3fb27SDimitry Andric #define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric #include <__algorithm/copy_n.h> 14*0fca6ea1SDimitry Andric #include <__assert> 1506c3fb27SDimitry Andric #include <__bit/countl.h> 1606c3fb27SDimitry Andric #include <__charconv/tables.h> 1706c3fb27SDimitry Andric #include <__charconv/to_chars_base_10.h> 1806c3fb27SDimitry Andric #include <__charconv/to_chars_result.h> 1906c3fb27SDimitry Andric #include <__charconv/traits.h> 2006c3fb27SDimitry Andric #include <__config> 2106c3fb27SDimitry Andric #include <__system_error/errc.h> 2206c3fb27SDimitry Andric #include <__type_traits/enable_if.h> 2306c3fb27SDimitry Andric #include <__type_traits/integral_constant.h> 2406c3fb27SDimitry Andric #include <__type_traits/is_same.h> 2506c3fb27SDimitry Andric #include <__type_traits/make_32_64_or_128_bit.h> 2606c3fb27SDimitry Andric #include <__type_traits/make_unsigned.h> 2706c3fb27SDimitry Andric #include <__utility/unreachable.h> 2806c3fb27SDimitry Andric #include <cstddef> 2906c3fb27SDimitry Andric #include <cstdint> 3006c3fb27SDimitry Andric #include <limits> 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 3306c3fb27SDimitry Andric # pragma GCC system_header 3406c3fb27SDimitry Andric #endif 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 3706c3fb27SDimitry Andric #include <__undef_macros> 3806c3fb27SDimitry Andric 3906c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 4006c3fb27SDimitry Andric 4106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andric to_chars_result to_chars(char*, char*, bool, int = 10) = delete; 4406c3fb27SDimitry Andric 4506c3fb27SDimitry Andric template <typename _Tp> 4606c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 4706c3fb27SDimitry Andric __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type); 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric template <typename _Tp> 5006c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 5106c3fb27SDimitry Andric __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) { 5206c3fb27SDimitry Andric auto __x = std::__to_unsigned_like(__value); 5306c3fb27SDimitry Andric if (__value < 0 && __first != __last) { 5406c3fb27SDimitry Andric *__first++ = '-'; 5506c3fb27SDimitry Andric __x = std::__complement(__x); 5606c3fb27SDimitry Andric } 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric return std::__to_chars_itoa(__first, __last, __x, false_type()); 5906c3fb27SDimitry Andric } 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric template <typename _Tp> 6206c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 6306c3fb27SDimitry Andric __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) { 6406c3fb27SDimitry Andric using __tx = __itoa::__traits<_Tp>; 6506c3fb27SDimitry Andric auto __diff = __last - __first; 6606c3fb27SDimitry Andric 6706c3fb27SDimitry Andric if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) 6806c3fb27SDimitry Andric return {__tx::__convert(__first, __value), errc(0)}; 6906c3fb27SDimitry Andric else 7006c3fb27SDimitry Andric return {__last, errc::value_too_large}; 7106c3fb27SDimitry Andric } 7206c3fb27SDimitry Andric 7306c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_INT128 7406c3fb27SDimitry Andric template <> 7506c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 7606c3fb27SDimitry Andric __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) { 7706c3fb27SDimitry Andric // When the value fits in 64-bits use the 64-bit code path. This reduces 7806c3fb27SDimitry Andric // the number of expensive calculations on 128-bit values. 7906c3fb27SDimitry Andric // 8006c3fb27SDimitry Andric // NOTE the 128-bit code path requires this optimization. 8106c3fb27SDimitry Andric if (__value <= numeric_limits<uint64_t>::max()) 8206c3fb27SDimitry Andric return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type()); 8306c3fb27SDimitry Andric 8406c3fb27SDimitry Andric using __tx = __itoa::__traits<__uint128_t>; 8506c3fb27SDimitry Andric auto __diff = __last - __first; 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) 8806c3fb27SDimitry Andric return {__tx::__convert(__first, __value), errc(0)}; 8906c3fb27SDimitry Andric else 9006c3fb27SDimitry Andric return {__last, errc::value_too_large}; 9106c3fb27SDimitry Andric } 9206c3fb27SDimitry Andric # endif 9306c3fb27SDimitry Andric 9406c3fb27SDimitry Andric template <class _Tp> 9506c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 9606c3fb27SDimitry Andric __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type); 9706c3fb27SDimitry Andric 9806c3fb27SDimitry Andric template <typename _Tp> 9906c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 10006c3fb27SDimitry Andric __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) { 10106c3fb27SDimitry Andric auto __x = std::__to_unsigned_like(__value); 10206c3fb27SDimitry Andric if (__value < 0 && __first != __last) { 10306c3fb27SDimitry Andric *__first++ = '-'; 10406c3fb27SDimitry Andric __x = std::__complement(__x); 10506c3fb27SDimitry Andric } 10606c3fb27SDimitry Andric 10706c3fb27SDimitry Andric return std::__to_chars_integral(__first, __last, __x, __base, false_type()); 10806c3fb27SDimitry Andric } 10906c3fb27SDimitry Andric 11006c3fb27SDimitry Andric namespace __itoa { 11106c3fb27SDimitry Andric 11206c3fb27SDimitry Andric template <unsigned _Base> 11306c3fb27SDimitry Andric struct _LIBCPP_HIDDEN __integral; 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric template <> 11606c3fb27SDimitry Andric struct _LIBCPP_HIDDEN __integral<2> { 11706c3fb27SDimitry Andric template <typename _Tp> 11806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 11906c3fb27SDimitry Andric // If value == 0 still need one digit. If the value != this has no 12006c3fb27SDimitry Andric // effect since the code scans for the most significant bit set. (Note 12106c3fb27SDimitry Andric // that __libcpp_clz doesn't work for 0.) 12206c3fb27SDimitry Andric return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1); 12306c3fb27SDimitry Andric } 12406c3fb27SDimitry Andric 12506c3fb27SDimitry Andric template <typename _Tp> 12606c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result 12706c3fb27SDimitry Andric __to_chars(char* __first, char* __last, _Tp __value) { 12806c3fb27SDimitry Andric ptrdiff_t __cap = __last - __first; 12906c3fb27SDimitry Andric int __n = __width(__value); 13006c3fb27SDimitry Andric if (__n > __cap) 13106c3fb27SDimitry Andric return {__last, errc::value_too_large}; 13206c3fb27SDimitry Andric 13306c3fb27SDimitry Andric __last = __first + __n; 13406c3fb27SDimitry Andric char* __p = __last; 13506c3fb27SDimitry Andric const unsigned __divisor = 16; 13606c3fb27SDimitry Andric while (__value > __divisor) { 13706c3fb27SDimitry Andric unsigned __c = __value % __divisor; 13806c3fb27SDimitry Andric __value /= __divisor; 13906c3fb27SDimitry Andric __p -= 4; 14006c3fb27SDimitry Andric std::copy_n(&__base_2_lut[4 * __c], 4, __p); 14106c3fb27SDimitry Andric } 14206c3fb27SDimitry Andric do { 14306c3fb27SDimitry Andric unsigned __c = __value % 2; 14406c3fb27SDimitry Andric __value /= 2; 14506c3fb27SDimitry Andric *--__p = "01"[__c]; 14606c3fb27SDimitry Andric } while (__value != 0); 14706c3fb27SDimitry Andric return {__last, errc(0)}; 14806c3fb27SDimitry Andric } 14906c3fb27SDimitry Andric }; 15006c3fb27SDimitry Andric 15106c3fb27SDimitry Andric template <> 15206c3fb27SDimitry Andric struct _LIBCPP_HIDDEN __integral<8> { 15306c3fb27SDimitry Andric template <typename _Tp> 15406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 15506c3fb27SDimitry Andric // If value == 0 still need one digit. If the value != this has no 15606c3fb27SDimitry Andric // effect since the code scans for the most significat bit set. (Note 15706c3fb27SDimitry Andric // that __libcpp_clz doesn't work for 0.) 15806c3fb27SDimitry Andric return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3; 15906c3fb27SDimitry Andric } 16006c3fb27SDimitry Andric 16106c3fb27SDimitry Andric template <typename _Tp> 16206c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result 16306c3fb27SDimitry Andric __to_chars(char* __first, char* __last, _Tp __value) { 16406c3fb27SDimitry Andric ptrdiff_t __cap = __last - __first; 16506c3fb27SDimitry Andric int __n = __width(__value); 16606c3fb27SDimitry Andric if (__n > __cap) 16706c3fb27SDimitry Andric return {__last, errc::value_too_large}; 16806c3fb27SDimitry Andric 16906c3fb27SDimitry Andric __last = __first + __n; 17006c3fb27SDimitry Andric char* __p = __last; 17106c3fb27SDimitry Andric unsigned __divisor = 64; 17206c3fb27SDimitry Andric while (__value > __divisor) { 17306c3fb27SDimitry Andric unsigned __c = __value % __divisor; 17406c3fb27SDimitry Andric __value /= __divisor; 17506c3fb27SDimitry Andric __p -= 2; 17606c3fb27SDimitry Andric std::copy_n(&__base_8_lut[2 * __c], 2, __p); 17706c3fb27SDimitry Andric } 17806c3fb27SDimitry Andric do { 17906c3fb27SDimitry Andric unsigned __c = __value % 8; 18006c3fb27SDimitry Andric __value /= 8; 18106c3fb27SDimitry Andric *--__p = "01234567"[__c]; 18206c3fb27SDimitry Andric } while (__value != 0); 18306c3fb27SDimitry Andric return {__last, errc(0)}; 18406c3fb27SDimitry Andric } 18506c3fb27SDimitry Andric }; 18606c3fb27SDimitry Andric 18706c3fb27SDimitry Andric template <> 18806c3fb27SDimitry Andric struct _LIBCPP_HIDDEN __integral<16> { 18906c3fb27SDimitry Andric template <typename _Tp> 19006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 19106c3fb27SDimitry Andric // If value == 0 still need one digit. If the value != this has no 19206c3fb27SDimitry Andric // effect since the code scans for the most significat bit set. (Note 19306c3fb27SDimitry Andric // that __libcpp_clz doesn't work for 0.) 19406c3fb27SDimitry Andric return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4; 19506c3fb27SDimitry Andric } 19606c3fb27SDimitry Andric 19706c3fb27SDimitry Andric template <typename _Tp> 19806c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result 19906c3fb27SDimitry Andric __to_chars(char* __first, char* __last, _Tp __value) { 20006c3fb27SDimitry Andric ptrdiff_t __cap = __last - __first; 20106c3fb27SDimitry Andric int __n = __width(__value); 20206c3fb27SDimitry Andric if (__n > __cap) 20306c3fb27SDimitry Andric return {__last, errc::value_too_large}; 20406c3fb27SDimitry Andric 20506c3fb27SDimitry Andric __last = __first + __n; 20606c3fb27SDimitry Andric char* __p = __last; 20706c3fb27SDimitry Andric unsigned __divisor = 256; 20806c3fb27SDimitry Andric while (__value > __divisor) { 20906c3fb27SDimitry Andric unsigned __c = __value % __divisor; 21006c3fb27SDimitry Andric __value /= __divisor; 21106c3fb27SDimitry Andric __p -= 2; 21206c3fb27SDimitry Andric std::copy_n(&__base_16_lut[2 * __c], 2, __p); 21306c3fb27SDimitry Andric } 21406c3fb27SDimitry Andric if (__first != __last) 21506c3fb27SDimitry Andric do { 21606c3fb27SDimitry Andric unsigned __c = __value % 16; 21706c3fb27SDimitry Andric __value /= 16; 21806c3fb27SDimitry Andric *--__p = "0123456789abcdef"[__c]; 21906c3fb27SDimitry Andric } while (__value != 0); 22006c3fb27SDimitry Andric return {__last, errc(0)}; 22106c3fb27SDimitry Andric } 22206c3fb27SDimitry Andric }; 22306c3fb27SDimitry Andric 22406c3fb27SDimitry Andric } // namespace __itoa 22506c3fb27SDimitry Andric 2265f757f3fSDimitry Andric template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0> 22706c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { 22806c3fb27SDimitry Andric return __itoa::__integral<_Base>::__width(__value); 22906c3fb27SDimitry Andric } 23006c3fb27SDimitry Andric 2315f757f3fSDimitry Andric template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0> 23206c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { 23306c3fb27SDimitry Andric return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value)); 23406c3fb27SDimitry Andric } 23506c3fb27SDimitry Andric 2365f757f3fSDimitry Andric template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0> 23706c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 23806c3fb27SDimitry Andric __to_chars_integral(char* __first, char* __last, _Tp __value) { 23906c3fb27SDimitry Andric return __itoa::__integral<_Base>::__to_chars(__first, __last, __value); 24006c3fb27SDimitry Andric } 24106c3fb27SDimitry Andric 2425f757f3fSDimitry Andric template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0> 24306c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 24406c3fb27SDimitry Andric __to_chars_integral(char* __first, char* __last, _Tp __value) { 24506c3fb27SDimitry Andric return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value)); 24606c3fb27SDimitry Andric } 24706c3fb27SDimitry Andric 24806c3fb27SDimitry Andric template <typename _Tp> 24906c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) { 2501db9f3b2SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__value >= 0, "The function requires a non-negative value."); 25106c3fb27SDimitry Andric 25206c3fb27SDimitry Andric unsigned __base_2 = __base * __base; 25306c3fb27SDimitry Andric unsigned __base_3 = __base_2 * __base; 25406c3fb27SDimitry Andric unsigned __base_4 = __base_2 * __base_2; 25506c3fb27SDimitry Andric 25606c3fb27SDimitry Andric int __r = 0; 25706c3fb27SDimitry Andric while (true) { 25806c3fb27SDimitry Andric if (__value < __base) 25906c3fb27SDimitry Andric return __r + 1; 26006c3fb27SDimitry Andric if (__value < __base_2) 26106c3fb27SDimitry Andric return __r + 2; 26206c3fb27SDimitry Andric if (__value < __base_3) 26306c3fb27SDimitry Andric return __r + 3; 26406c3fb27SDimitry Andric if (__value < __base_4) 26506c3fb27SDimitry Andric return __r + 4; 26606c3fb27SDimitry Andric 26706c3fb27SDimitry Andric __value /= __base_4; 26806c3fb27SDimitry Andric __r += 4; 26906c3fb27SDimitry Andric } 27006c3fb27SDimitry Andric 27106c3fb27SDimitry Andric __libcpp_unreachable(); 27206c3fb27SDimitry Andric } 27306c3fb27SDimitry Andric 27406c3fb27SDimitry Andric template <typename _Tp> 27506c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 27606c3fb27SDimitry Andric __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) { 27706c3fb27SDimitry Andric if (__base == 10) [[likely]] 27806c3fb27SDimitry Andric return std::__to_chars_itoa(__first, __last, __value, false_type()); 27906c3fb27SDimitry Andric 28006c3fb27SDimitry Andric switch (__base) { 28106c3fb27SDimitry Andric case 2: 28206c3fb27SDimitry Andric return std::__to_chars_integral<2>(__first, __last, __value); 28306c3fb27SDimitry Andric case 8: 28406c3fb27SDimitry Andric return std::__to_chars_integral<8>(__first, __last, __value); 28506c3fb27SDimitry Andric case 16: 28606c3fb27SDimitry Andric return std::__to_chars_integral<16>(__first, __last, __value); 28706c3fb27SDimitry Andric } 28806c3fb27SDimitry Andric 28906c3fb27SDimitry Andric ptrdiff_t __cap = __last - __first; 29006c3fb27SDimitry Andric int __n = std::__to_chars_integral_width(__value, __base); 29106c3fb27SDimitry Andric if (__n > __cap) 29206c3fb27SDimitry Andric return {__last, errc::value_too_large}; 29306c3fb27SDimitry Andric 29406c3fb27SDimitry Andric __last = __first + __n; 29506c3fb27SDimitry Andric char* __p = __last; 29606c3fb27SDimitry Andric do { 29706c3fb27SDimitry Andric unsigned __c = __value % __base; 29806c3fb27SDimitry Andric __value /= __base; 29906c3fb27SDimitry Andric *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c]; 30006c3fb27SDimitry Andric } while (__value != 0); 30106c3fb27SDimitry Andric return {__last, errc(0)}; 30206c3fb27SDimitry Andric } 30306c3fb27SDimitry Andric 3045f757f3fSDimitry Andric template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 30506c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 30606c3fb27SDimitry Andric to_chars(char* __first, char* __last, _Tp __value) { 30706c3fb27SDimitry Andric using _Type = __make_32_64_or_128_bit_t<_Tp>; 30806c3fb27SDimitry Andric static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars"); 30906c3fb27SDimitry Andric return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>()); 31006c3fb27SDimitry Andric } 31106c3fb27SDimitry Andric 3125f757f3fSDimitry Andric template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 31306c3fb27SDimitry Andric inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result 31406c3fb27SDimitry Andric to_chars(char* __first, char* __last, _Tp __value, int __base) { 31506c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]"); 31606c3fb27SDimitry Andric 31706c3fb27SDimitry Andric using _Type = __make_32_64_or_128_bit_t<_Tp>; 31806c3fb27SDimitry Andric return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>()); 31906c3fb27SDimitry Andric } 32006c3fb27SDimitry Andric 32106c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 17 32206c3fb27SDimitry Andric 32306c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 32406c3fb27SDimitry Andric 32506c3fb27SDimitry Andric _LIBCPP_POP_MACROS 32606c3fb27SDimitry Andric 32706c3fb27SDimitry Andric #endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H 328