xref: /llvm-project/libcxx/include/__charconv/to_chars_base_10.h (revision ba87515fea90b5d55836a8e3be63a7e683ce299d)
1a15ae413SMark de Wever // -*- C++ -*-
2a15ae413SMark de Wever //===----------------------------------------------------------------------===//
3a15ae413SMark de Wever //
4a15ae413SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5a15ae413SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
6a15ae413SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7a15ae413SMark de Wever //
8a15ae413SMark de Wever //===----------------------------------------------------------------------===//
9a15ae413SMark de Wever 
10a15ae413SMark de Wever #ifndef _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
11a15ae413SMark de Wever #define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
12a15ae413SMark de Wever 
133561ee58SMark de Wever #include <__algorithm/copy_n.h>
1437dca605SLouis Dionne #include <__assert>
15a15ae413SMark de Wever #include <__charconv/tables.h>
16a15ae413SMark de Wever #include <__config>
17a15ae413SMark de Wever #include <cstdint>
183f786833SMark de Wever #include <limits>
19a15ae413SMark de Wever 
20a15ae413SMark de Wever #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21a15ae413SMark de Wever #  pragma GCC system_header
22a15ae413SMark de Wever #endif
23a15ae413SMark de Wever 
243f786833SMark de Wever _LIBCPP_PUSH_MACROS
253f786833SMark de Wever #include <__undef_macros>
263f786833SMark de Wever 
27a15ae413SMark de Wever _LIBCPP_BEGIN_NAMESPACE_STD
28a15ae413SMark de Wever 
294f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17
30a15ae413SMark de Wever 
31a15ae413SMark de Wever namespace __itoa {
32a15ae413SMark de Wever 
33a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append1(char* __first, uint32_t __value) noexcept {
343561ee58SMark de Wever   *__first = '0' + static_cast<char>(__value);
353561ee58SMark de Wever   return __first + 1;
36a15ae413SMark de Wever }
37a15ae413SMark de Wever 
38a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append2(char* __first, uint32_t __value) noexcept {
39a1e13a80SMark de Wever   return std::copy_n(&__digits_base_10[__value * 2], 2, __first);
40a15ae413SMark de Wever }
41a15ae413SMark de Wever 
42a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append3(char* __first, uint32_t __value) noexcept {
433561ee58SMark de Wever   return __itoa::__append2(__itoa::__append1(__first, __value / 100), __value % 100);
44a15ae413SMark de Wever }
45a15ae413SMark de Wever 
46a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append4(char* __first, uint32_t __value) noexcept {
473561ee58SMark de Wever   return __itoa::__append2(__itoa::__append2(__first, __value / 100), __value % 100);
48a15ae413SMark de Wever }
49a15ae413SMark de Wever 
50a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append5(char* __first, uint32_t __value) noexcept {
513561ee58SMark de Wever   return __itoa::__append4(__itoa::__append1(__first, __value / 10000), __value % 10000);
523561ee58SMark de Wever }
533561ee58SMark de Wever 
54a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append6(char* __first, uint32_t __value) noexcept {
553561ee58SMark de Wever   return __itoa::__append4(__itoa::__append2(__first, __value / 10000), __value % 10000);
563561ee58SMark de Wever }
573561ee58SMark de Wever 
58a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append7(char* __first, uint32_t __value) noexcept {
593561ee58SMark de Wever   return __itoa::__append6(__itoa::__append1(__first, __value / 1000000), __value % 1000000);
603561ee58SMark de Wever }
613561ee58SMark de Wever 
62a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append8(char* __first, uint32_t __value) noexcept {
633561ee58SMark de Wever   return __itoa::__append6(__itoa::__append2(__first, __value / 1000000), __value % 1000000);
643561ee58SMark de Wever }
653561ee58SMark de Wever 
66a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append9(char* __first, uint32_t __value) noexcept {
673561ee58SMark de Wever   return __itoa::__append8(__itoa::__append1(__first, __value / 100000000), __value % 100000000);
683561ee58SMark de Wever }
693561ee58SMark de Wever 
70a15ae413SMark de Wever template <class _Tp>
71a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __first, _Tp __value) noexcept {
723561ee58SMark de Wever   return __itoa::__append8(__itoa::__append2(__first, static_cast<uint32_t>(__value / 100000000)),
733561ee58SMark de Wever                            static_cast<uint32_t>(__value % 100000000));
743561ee58SMark de Wever }
753561ee58SMark de Wever 
76866fbb87SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
77866fbb87SMark de Wever __base_10_u32(char* __first, uint32_t __value) noexcept {
783561ee58SMark de Wever   if (__value < 1000000) {
793561ee58SMark de Wever     if (__value < 10000) {
803561ee58SMark de Wever       if (__value < 100) {
813561ee58SMark de Wever         // 0 <= __value < 100
82a15ae413SMark de Wever         if (__value < 10)
833561ee58SMark de Wever           return __itoa::__append1(__first, __value);
843561ee58SMark de Wever         return __itoa::__append2(__first, __value);
853561ee58SMark de Wever       }
863561ee58SMark de Wever       // 100 <= __value < 10'000
873561ee58SMark de Wever       if (__value < 1000)
883561ee58SMark de Wever         return __itoa::__append3(__first, __value);
893561ee58SMark de Wever       return __itoa::__append4(__first, __value);
90a15ae413SMark de Wever     }
91a15ae413SMark de Wever 
923561ee58SMark de Wever     // 10'000 <= __value < 1'000'000
933561ee58SMark de Wever     if (__value < 100000)
943561ee58SMark de Wever       return __itoa::__append5(__first, __value);
953561ee58SMark de Wever     return __itoa::__append6(__first, __value);
96a15ae413SMark de Wever   }
97a15ae413SMark de Wever 
983561ee58SMark de Wever   // __value => 1'000'000
993561ee58SMark de Wever   if (__value < 100000000) {
1003561ee58SMark de Wever     // 1'000'000 <= __value < 100'000'000
1013561ee58SMark de Wever     if (__value < 10000000)
1023561ee58SMark de Wever       return __itoa::__append7(__first, __value);
1033561ee58SMark de Wever     return __itoa::__append8(__first, __value);
104a15ae413SMark de Wever   }
105a15ae413SMark de Wever 
1063561ee58SMark de Wever   // 100'000'000 <= __value < max
1073561ee58SMark de Wever   if (__value < 1000000000)
1083561ee58SMark de Wever     return __itoa::__append9(__first, __value);
1093561ee58SMark de Wever   return __itoa::__append10(__first, __value);
110a15ae413SMark de Wever }
111a15ae413SMark de Wever 
112866fbb87SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
113866fbb87SMark de Wever __base_10_u64(char* __buffer, uint64_t __value) noexcept {
1143561ee58SMark de Wever   if (__value <= UINT32_MAX)
1153561ee58SMark de Wever     return __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value));
1163561ee58SMark de Wever 
1173561ee58SMark de Wever   // Numbers in the range UINT32_MAX <= val < 10'000'000'000 always contain 10
1183561ee58SMark de Wever   // digits and are outputted after this if statement.
1193561ee58SMark de Wever   if (__value >= 10000000000) {
1203561ee58SMark de Wever     // This function properly deterimines the first non-zero leading digit.
1213561ee58SMark de Wever     __buffer = __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value / 10000000000));
1223561ee58SMark de Wever     __value %= 10000000000;
123a15ae413SMark de Wever   }
1243561ee58SMark de Wever   return __itoa::__append10(__buffer, __value);
125a15ae413SMark de Wever }
126a15ae413SMark de Wever 
127*ba87515fSNikolas Klauser #  if _LIBCPP_HAS_INT128
1283f786833SMark de Wever /// \returns 10^\a exp
1293f786833SMark de Wever ///
1303f786833SMark de Wever /// \pre \a exp [19, 39]
1313f786833SMark de Wever ///
1323f786833SMark de Wever /// \note The lookup table contains a partial set of exponents limiting the
1333f786833SMark de Wever /// range that can be used. However the range is sufficient for
1343f786833SMark de Wever /// \ref __base_10_u128.
135a1e13a80SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept {
1364f215fddSKonstantin Varlamov   _LIBCPP_ASSERT_INTERNAL(__exp >= __pow10_128_offset, "Index out of bounds");
137a1e13a80SMark de Wever   return __pow10_128[__exp - __pow10_128_offset];
1383f786833SMark de Wever }
1393f786833SMark de Wever 
140866fbb87SMark de Wever _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char*
141866fbb87SMark de Wever __base_10_u128(char* __buffer, __uint128_t __value) noexcept {
1424f215fddSKonstantin Varlamov   _LIBCPP_ASSERT_INTERNAL(
1434f215fddSKonstantin Varlamov       __value > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fails when this isn't true.");
1443f786833SMark de Wever 
1453f786833SMark de Wever   // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be
1463f786833SMark de Wever   // stored in the "lower half". Instead we first need to handle the top most
1473f786833SMark de Wever   // digits separately.
1483f786833SMark de Wever   //
1493f786833SMark de Wever   // Maximum unsigned values
1503f786833SMark de Wever   // 64  bit                             18'446'744'073'709'551'615 (20 digits)
1513f786833SMark de Wever   // 128 bit    340'282'366'920'938'463'463'374'607'431'768'211'455 (39 digits)
1523f786833SMark de Wever   // step 1     ^                                                   ([0-1] digits)
1533f786833SMark de Wever   // step 2      ^^^^^^^^^^^^^^^^^^^^^^^^^                          ([0-19] digits)
1543f786833SMark de Wever   // step 3                               ^^^^^^^^^^^^^^^^^^^^^^^^^ (19 digits)
1553f786833SMark de Wever   if (__value >= __itoa::__pow_10(38)) {
1563f786833SMark de Wever     // step 1
1573f786833SMark de Wever     __buffer = __itoa::__append1(__buffer, static_cast<uint32_t>(__value / __itoa::__pow_10(38)));
1583f786833SMark de Wever     __value %= __itoa::__pow_10(38);
1593f786833SMark de Wever 
1603f786833SMark de Wever     // step 2 always 19 digits.
1613f786833SMark de Wever     // They are handled here since leading zeros need to be appended to the buffer,
1623f786833SMark de Wever     __buffer = __itoa::__append9(__buffer, static_cast<uint32_t>(__value / __itoa::__pow_10(29)));
1633f786833SMark de Wever     __value %= __itoa::__pow_10(29);
1643f786833SMark de Wever     __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
1653f786833SMark de Wever     __value %= __itoa::__pow_10(19);
166866fbb87SMark de Wever   } else {
1673f786833SMark de Wever     // step 2
1683f786833SMark de Wever     // This version needs to determine the position of the leading non-zero digit.
1693f786833SMark de Wever     __buffer = __base_10_u64(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
1703f786833SMark de Wever     __value %= __itoa::__pow_10(19);
1713f786833SMark de Wever   }
1723f786833SMark de Wever 
1733f786833SMark de Wever   // Step 3
1743f786833SMark de Wever   __buffer = __itoa::__append9(__buffer, static_cast<uint32_t>(__value / 10000000000));
1753f786833SMark de Wever   __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value % 10000000000));
1763f786833SMark de Wever 
1773f786833SMark de Wever   return __buffer;
1783f786833SMark de Wever }
1793f786833SMark de Wever #  endif
180a15ae413SMark de Wever } // namespace __itoa
181a15ae413SMark de Wever 
1824f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 17
183a15ae413SMark de Wever 
184a15ae413SMark de Wever _LIBCPP_END_NAMESPACE_STD
185a15ae413SMark de Wever 
1863f786833SMark de Wever _LIBCPP_POP_MACROS
1873f786833SMark de Wever 
188a15ae413SMark de Wever #endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
189