2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
11 #define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
13 #include <__algorithm/copy_n.h>
14 #include <__bit/countl.h>
15 #include <__charconv/tables.h>
16 #include <__charconv/to_chars_base_10.h>
17 #include <__charconv/to_chars_result.h>
18 #include <__charconv/traits.h>
20 #include <__system_error/errc.h>
21 #include <__type_traits/enable_if.h>
22 #include <__type_traits/integral_constant.h>
23 #include <__type_traits/is_same.h>
24 #include <__type_traits/make_32_64_or_128_bit.h>
25 #include <__type_traits/make_unsigned.h>
26 #include <__utility/unreachable.h>
31 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32 # pragma GCC system_header
36 #include <__undef_macros>
38 _LIBCPP_BEGIN_NAMESPACE_STD
40 #if _LIBCPP_STD_VER >= 17
42 to_chars_result
to_chars(char*, char*, bool, int = 10) = delete;
44 template <typename _Tp
>
45 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
46 __to_chars_itoa(char* __first
, char* __last
, _Tp __value
, false_type
);
48 template <typename _Tp
>
49 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
50 __to_chars_itoa(char* __first
, char* __last
, _Tp __value
, true_type
) {
51 auto __x
= std::__to_unsigned_like(__value
);
52 if (__value
< 0 && __first
!= __last
) {
54 __x
= std::__complement(__x
);
57 return std::__to_chars_itoa(__first
, __last
, __x
, false_type());
60 template <typename _Tp
>
61 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
62 __to_chars_itoa(char* __first
, char* __last
, _Tp __value
, false_type
) {
63 using __tx
= __itoa::__traits
<_Tp
>;
64 auto __diff
= __last
- __first
;
66 if (__tx::digits
<= __diff
|| __tx::__width(__value
) <= __diff
)
67 return {__tx::__convert(__first
, __value
), errc(0)};
69 return {__last
, errc::value_too_large
};
72 # ifndef _LIBCPP_HAS_NO_INT128
74 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
75 __to_chars_itoa(char* __first
, char* __last
, __uint128_t __value
, false_type
) {
76 // When the value fits in 64-bits use the 64-bit code path. This reduces
77 // the number of expensive calculations on 128-bit values.
79 // NOTE the 128-bit code path requires this optimization.
80 if (__value
<= numeric_limits
<uint64_t>::max())
81 return __to_chars_itoa(__first
, __last
, static_cast<uint64_t>(__value
), false_type());
83 using __tx
= __itoa::__traits
<__uint128_t
>;
84 auto __diff
= __last
- __first
;
86 if (__tx::digits
<= __diff
|| __tx::__width(__value
) <= __diff
)
87 return {__tx::__convert(__first
, __value
), errc(0)};
89 return {__last
, errc::value_too_large
};
94 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
95 __to_chars_integral(char* __first
, char* __last
, _Tp __value
, int __base
, false_type
);
97 template <typename _Tp
>
98 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
99 __to_chars_integral(char* __first
, char* __last
, _Tp __value
, int __base
, true_type
) {
100 auto __x
= std::__to_unsigned_like(__value
);
101 if (__value
< 0 && __first
!= __last
) {
103 __x
= std::__complement(__x
);
106 return std::__to_chars_integral(__first
, __last
, __x
, __base
, false_type());
111 template <unsigned _Base
>
112 struct _LIBCPP_HIDDEN __integral
;
115 struct _LIBCPP_HIDDEN __integral
<2> {
116 template <typename _Tp
>
117 _LIBCPP_HIDE_FROM_ABI
static constexpr int __width(_Tp __value
) noexcept
{
118 // If value == 0 still need one digit. If the value != this has no
119 // effect since the code scans for the most significant bit set. (Note
120 // that __libcpp_clz doesn't work for 0.)
121 return numeric_limits
<_Tp
>::digits
- std::__libcpp_clz(__value
| 1);
124 template <typename _Tp
>
125 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
static to_chars_result
126 __to_chars(char* __first
, char* __last
, _Tp __value
) {
127 ptrdiff_t __cap
= __last
- __first
;
128 int __n
= __width(__value
);
130 return {__last
, errc::value_too_large
};
132 __last
= __first
+ __n
;
134 const unsigned __divisor
= 16;
135 while (__value
> __divisor
) {
136 unsigned __c
= __value
% __divisor
;
137 __value
/= __divisor
;
139 std::copy_n(&__base_2_lut
[4 * __c
], 4, __p
);
142 unsigned __c
= __value
% 2;
145 } while (__value
!= 0);
146 return {__last
, errc(0)};
151 struct _LIBCPP_HIDDEN __integral
<8> {
152 template <typename _Tp
>
153 _LIBCPP_HIDE_FROM_ABI
static constexpr int __width(_Tp __value
) noexcept
{
154 // If value == 0 still need one digit. If the value != this has no
155 // effect since the code scans for the most significat bit set. (Note
156 // that __libcpp_clz doesn't work for 0.)
157 return ((numeric_limits
<_Tp
>::digits
- std::__libcpp_clz(__value
| 1)) + 2) / 3;
160 template <typename _Tp
>
161 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
static to_chars_result
162 __to_chars(char* __first
, char* __last
, _Tp __value
) {
163 ptrdiff_t __cap
= __last
- __first
;
164 int __n
= __width(__value
);
166 return {__last
, errc::value_too_large
};
168 __last
= __first
+ __n
;
170 unsigned __divisor
= 64;
171 while (__value
> __divisor
) {
172 unsigned __c
= __value
% __divisor
;
173 __value
/= __divisor
;
175 std::copy_n(&__base_8_lut
[2 * __c
], 2, __p
);
178 unsigned __c
= __value
% 8;
180 *--__p
= "01234567"[__c
];
181 } while (__value
!= 0);
182 return {__last
, errc(0)};
187 struct _LIBCPP_HIDDEN __integral
<16> {
188 template <typename _Tp
>
189 _LIBCPP_HIDE_FROM_ABI
static constexpr int __width(_Tp __value
) noexcept
{
190 // If value == 0 still need one digit. If the value != this has no
191 // effect since the code scans for the most significat bit set. (Note
192 // that __libcpp_clz doesn't work for 0.)
193 return (numeric_limits
<_Tp
>::digits
- std::__libcpp_clz(__value
| 1) + 3) / 4;
196 template <typename _Tp
>
197 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
static to_chars_result
198 __to_chars(char* __first
, char* __last
, _Tp __value
) {
199 ptrdiff_t __cap
= __last
- __first
;
200 int __n
= __width(__value
);
202 return {__last
, errc::value_too_large
};
204 __last
= __first
+ __n
;
206 unsigned __divisor
= 256;
207 while (__value
> __divisor
) {
208 unsigned __c
= __value
% __divisor
;
209 __value
/= __divisor
;
211 std::copy_n(&__base_16_lut
[2 * __c
], 2, __p
);
213 if (__first
!= __last
)
215 unsigned __c
= __value
% 16;
217 *--__p
= "0123456789abcdef"[__c
];
218 } while (__value
!= 0);
219 return {__last
, errc(0)};
223 } // namespace __itoa
225 template <unsigned _Base
, typename _Tp
, __enable_if_t
<(sizeof(_Tp
) >= sizeof(unsigned)), int> = 0>
226 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
int __to_chars_integral_width(_Tp __value
) {
227 return __itoa::__integral
<_Base
>::__width(__value
);
230 template <unsigned _Base
, typename _Tp
, __enable_if_t
<(sizeof(_Tp
) < sizeof(unsigned)), int> = 0>
231 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
int __to_chars_integral_width(_Tp __value
) {
232 return std::__to_chars_integral_width
<_Base
>(static_cast<unsigned>(__value
));
235 template <unsigned _Base
, typename _Tp
, __enable_if_t
<(sizeof(_Tp
) >= sizeof(unsigned)), int> = 0>
236 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
237 __to_chars_integral(char* __first
, char* __last
, _Tp __value
) {
238 return __itoa::__integral
<_Base
>::__to_chars(__first
, __last
, __value
);
241 template <unsigned _Base
, typename _Tp
, __enable_if_t
<(sizeof(_Tp
) < sizeof(unsigned)), int> = 0>
242 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
243 __to_chars_integral(char* __first
, char* __last
, _Tp __value
) {
244 return std::__to_chars_integral
<_Base
>(__first
, __last
, static_cast<unsigned>(__value
));
247 template <typename _Tp
>
248 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
int __to_chars_integral_width(_Tp __value
, unsigned __base
) {
249 _LIBCPP_ASSERT_UNCATEGORIZED(__value
>= 0, "The function requires a non-negative value.");
251 unsigned __base_2
= __base
* __base
;
252 unsigned __base_3
= __base_2
* __base
;
253 unsigned __base_4
= __base_2
* __base_2
;
257 if (__value
< __base
)
259 if (__value
< __base_2
)
261 if (__value
< __base_3
)
263 if (__value
< __base_4
)
270 __libcpp_unreachable();
273 template <typename _Tp
>
274 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
275 __to_chars_integral(char* __first
, char* __last
, _Tp __value
, int __base
, false_type
) {
276 if (__base
== 10) [[likely
]]
277 return std::__to_chars_itoa(__first
, __last
, __value
, false_type());
281 return std::__to_chars_integral
<2>(__first
, __last
, __value
);
283 return std::__to_chars_integral
<8>(__first
, __last
, __value
);
285 return std::__to_chars_integral
<16>(__first
, __last
, __value
);
288 ptrdiff_t __cap
= __last
- __first
;
289 int __n
= std::__to_chars_integral_width(__value
, __base
);
291 return {__last
, errc::value_too_large
};
293 __last
= __first
+ __n
;
296 unsigned __c
= __value
% __base
;
298 *--__p
= "0123456789abcdefghijklmnopqrstuvwxyz"[__c
];
299 } while (__value
!= 0);
300 return {__last
, errc(0)};
303 template <typename _Tp
, __enable_if_t
<is_integral
<_Tp
>::value
, int> = 0>
304 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
305 to_chars(char* __first
, char* __last
, _Tp __value
) {
306 using _Type
= __make_32_64_or_128_bit_t
<_Tp
>;
307 static_assert(!is_same
<_Type
, void>::value
, "unsupported integral type used in to_chars");
308 return std::__to_chars_itoa(__first
, __last
, static_cast<_Type
>(__value
), is_signed
<_Tp
>());
311 template <typename _Tp
, __enable_if_t
<is_integral
<_Tp
>::value
, int> = 0>
312 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
313 to_chars(char* __first
, char* __last
, _Tp __value
, int __base
) {
314 _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base
&& __base
<= 36, "base not in [2, 36]");
316 using _Type
= __make_32_64_or_128_bit_t
<_Tp
>;
317 return std::__to_chars_integral(__first
, __last
, static_cast<_Type
>(__value
), __base
, is_signed
<_Tp
>());
320 #endif // _LIBCPP_STD_VER >= 17
322 _LIBCPP_END_NAMESPACE_STD
326 #endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H