Skip to content

Commit

Permalink
[libc++] Don't use static constexpr in headers.
Browse files Browse the repository at this point in the history
This was noticed in the review of D125704. In that commit only the new
table has been adapted. This adapts the existing tables.

Note since libc++'s charconv is backported to C++11 it's not possible to
use inline constexpr variables. The were introduced in C++17.

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D126887
  • Loading branch information
mordante committed Jun 7, 2022
1 parent 907aedb commit dea7a8e
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 90 deletions.
85 changes: 82 additions & 3 deletions libcxx/include/__charconv/tables.h
Expand Up @@ -11,6 +11,7 @@
#define _LIBCPP___CHARCONV_TABLES

#include <__config>
#include <cstdint>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -22,13 +23,91 @@ _LIBCPP_BEGIN_NAMESPACE_STD

namespace __itoa {

/// Contains the charconv helper tables.
///
/// In C++17 these could be inline constexpr variable, but libc++ supports
/// charconv for integrals in C++11 mode.
template <class = void>
struct __digits_base_10 {
static const char __value[200];
struct __table {
static const char __base_2_lut[64];
static const char __base_8_lut[128];
static const char __base_16_lut[512];

static const uint32_t __pow10_32[10];
static const uint64_t __pow10_64[20];
static const char __digits_base_10[200];
};

template <class _Tp>
const char __digits_base_10<_Tp>::__value[200] = {
const char __table<_Tp>::__base_2_lut[64] = {
'0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '0', '0', '0', '1',
'0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '0',
'1', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '1', '1'};

template <class _Tp>
const char __table<_Tp>::__base_8_lut[128] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '1', '0', '1', '1', '1', '2',
'1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5',
'2', '6', '2', '7', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '4', '0',
'4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '5', '0', '5', '1', '5', '2', '5', '3',
'5', '4', '5', '5', '5', '6', '5', '7', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6',
'6', '7', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7'};

template <class _Tp>
const char __table<_Tp>::__base_16_lut[512] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'a', '0',
'b', '0', 'c', '0', 'd', '0', 'e', '0', 'f', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6',
'1', '7', '1', '8', '1', '9', '1', 'a', '1', 'b', '1', 'c', '1', 'd', '1', 'e', '1', 'f', '2', '0', '2', '1', '2',
'2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'a', '2', 'b', '2', 'c', '2', 'd',
'2', 'e', '2', 'f', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3',
'9', '3', 'a', '3', 'b', '3', 'c', '3', 'd', '3', 'e', '3', 'f', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
'4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '4', 'a', '4', 'b', '4', 'c', '4', 'd', '4', 'e', '4', 'f', '5',
'0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', '5', 'a', '5', 'b',
'5', 'c', '5', 'd', '5', 'e', '5', 'f', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
'7', '6', '8', '6', '9', '6', 'a', '6', 'b', '6', 'c', '6', 'd', '6', 'e', '6', 'f', '7', '0', '7', '1', '7', '2',
'7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '7', 'a', '7', 'b', '7', 'c', '7', 'd', '7',
'e', '7', 'f', '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
'8', 'a', '8', 'b', '8', 'c', '8', 'd', '8', 'e', '8', 'f', '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9',
'5', '9', '6', '9', '7', '9', '8', '9', '9', '9', 'a', '9', 'b', '9', 'c', '9', 'd', '9', 'e', '9', 'f', 'a', '0',
'a', '1', 'a', '2', 'a', '3', 'a', '4', 'a', '5', 'a', '6', 'a', '7', 'a', '8', 'a', '9', 'a', 'a', 'a', 'b', 'a',
'c', 'a', 'd', 'a', 'e', 'a', 'f', 'b', '0', 'b', '1', 'b', '2', 'b', '3', 'b', '4', 'b', '5', 'b', '6', 'b', '7',
'b', '8', 'b', '9', 'b', 'a', 'b', 'b', 'b', 'c', 'b', 'd', 'b', 'e', 'b', 'f', 'c', '0', 'c', '1', 'c', '2', 'c',
'3', 'c', '4', 'c', '5', 'c', '6', 'c', '7', 'c', '8', 'c', '9', 'c', 'a', 'c', 'b', 'c', 'c', 'c', 'd', 'c', 'e',
'c', 'f', 'd', '0', 'd', '1', 'd', '2', 'd', '3', 'd', '4', 'd', '5', 'd', '6', 'd', '7', 'd', '8', 'd', '9', 'd',
'a', 'd', 'b', 'd', 'c', 'd', 'd', 'd', 'e', 'd', 'f', 'e', '0', 'e', '1', 'e', '2', 'e', '3', 'e', '4', 'e', '5',
'e', '6', 'e', '7', 'e', '8', 'e', '9', 'e', 'a', 'e', 'b', 'e', 'c', 'e', 'd', 'e', 'e', 'e', 'f', 'f', '0', 'f',
'1', 'f', '2', 'f', '3', 'f', '4', 'f', '5', 'f', '6', 'f', '7', 'f', '8', 'f', '9', 'f', 'a', 'f', 'b', 'f', 'c',
'f', 'd', 'f', 'e', 'f', 'f'};

template <class _Tp>
const uint32_t __table<_Tp>::__pow10_32[10] = {
UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000),
UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)};

template <class _Tp>
const uint64_t __table<_Tp>::__pow10_64[20] = {UINT64_C(0),
UINT64_C(10),
UINT64_C(100),
UINT64_C(1000),
UINT64_C(10000),
UINT64_C(100000),
UINT64_C(1000000),
UINT64_C(10000000),
UINT64_C(100000000),
UINT64_C(1000000000),
UINT64_C(10000000000),
UINT64_C(100000000000),
UINT64_C(1000000000000),
UINT64_C(10000000000000),
UINT64_C(100000000000000),
UINT64_C(1000000000000000),
UINT64_C(10000000000000000),
UINT64_C(100000000000000000),
UINT64_C(1000000000000000000),
UINT64_C(10000000000000000000)};

template <class _Tp>
const char __table<_Tp>::__digits_base_10[200] = {
// clang-format off
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__charconv/to_chars_base_10.h
Expand Up @@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI char* __append1(char* __buffer, _Tp __value) noexcept {

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI char* __append2(char* __buffer, _Tp __value) noexcept {
std::memcpy(__buffer, &__digits_base_10<>::__value[(__value)*2], 2);
std::memcpy(__buffer, &__table<>::__digits_base_10[(__value)*2], 2);
return __buffer + 2;
}

Expand Down
92 changes: 7 additions & 85 deletions libcxx/include/charconv
Expand Up @@ -113,35 +113,6 @@ from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
namespace __itoa
{

static constexpr uint64_t __pow10_64[] = {
UINT64_C(0),
UINT64_C(10),
UINT64_C(100),
UINT64_C(1000),
UINT64_C(10000),
UINT64_C(100000),
UINT64_C(1000000),
UINT64_C(10000000),
UINT64_C(100000000),
UINT64_C(1000000000),
UINT64_C(10000000000),
UINT64_C(100000000000),
UINT64_C(1000000000000),
UINT64_C(10000000000000),
UINT64_C(100000000000000),
UINT64_C(1000000000000000),
UINT64_C(10000000000000000),
UINT64_C(100000000000000000),
UINT64_C(1000000000000000000),
UINT64_C(10000000000000000000),
};

static constexpr uint32_t __pow10_32[] = {
UINT32_C(0), UINT32_C(10), UINT32_C(100),
UINT32_C(1000), UINT32_C(10000), UINT32_C(100000),
UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000),
UINT32_C(1000000000),
};

template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
Expand All @@ -151,7 +122,7 @@ struct _LIBCPP_HIDDEN __traits_base
static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
{
auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
return __t - (__v < __pow10_64[__t]) + 1;
return __t - (__v < __table<>::__pow10_64[__t]) + 1;
}

_LIBCPP_AVAILABILITY_TO_CHARS
Expand All @@ -160,7 +131,7 @@ struct _LIBCPP_HIDDEN __traits_base
return __itoa::__base_10_u64(__v, __p);
}

static _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { return __pow10_64; }
static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_64)& __pow() { return __table<>::__pow10_64; }
};

template <typename _Tp>
Expand All @@ -172,7 +143,7 @@ struct _LIBCPP_HIDDEN
static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
{
auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
return __t - (__v < __pow10_32[__t]) + 1;
return __t - (__v < __table<>::__pow10_32[__t]) + 1;
}

_LIBCPP_AVAILABILITY_TO_CHARS
Expand All @@ -181,7 +152,7 @@ struct _LIBCPP_HIDDEN
return __itoa::__base_10_u32(__v, __p);
}

static _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { return __pow10_32; }
static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_32)& __pow() { return __table<>::__pow10_32; }
};

template <typename _Tp>
Expand Down Expand Up @@ -318,55 +289,6 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,

namespace __itoa {

static constexpr char __base_2_lut[64] = {
'0', '0', '0', '0',
'0', '0', '0', '1',
'0', '0', '1', '0',
'0', '0', '1', '1',
'0', '1', '0', '0',
'0', '1', '0', '1',
'0', '1', '1', '0',
'0', '1', '1', '1',
'1', '0', '0', '0',
'1', '0', '0', '1',
'1', '0', '1', '0',
'1', '0', '1', '1',
'1', '1', '0', '0',
'1', '1', '0', '1',
'1', '1', '1', '0',
'1', '1', '1', '1'
};

static constexpr char __base_8_lut[128] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7',
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7',
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7',
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7',
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7',
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7',
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7',
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7'
};

static constexpr char __base_16_lut[512] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'a', '0', 'b', '0', 'c', '0', 'd', '0', 'e', '0', 'f',
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '1', 'a', '1', 'b', '1', 'c', '1', 'd', '1', 'e', '1', 'f',
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'a', '2', 'b', '2', 'c', '2', 'd', '2', 'e', '2', 'f',
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', '3', 'a', '3', 'b', '3', 'c', '3', 'd', '3', 'e', '3', 'f',
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '4', 'a', '4', 'b', '4', 'c', '4', 'd', '4', 'e', '4', 'f',
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', '5', 'a', '5', 'b', '5', 'c', '5', 'd', '5', 'e', '5', 'f',
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', '6', 'a', '6', 'b', '6', 'c', '6', 'd', '6', 'e', '6', 'f',
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '7', 'a', '7', 'b', '7', 'c', '7', 'd', '7', 'e', '7', 'f',
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', '8', 'a', '8', 'b', '8', 'c', '8', 'd', '8', 'e', '8', 'f',
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', '9', 'a', '9', 'b', '9', 'c', '9', 'd', '9', 'e', '9', 'f',
'a', '0', 'a', '1', 'a', '2', 'a', '3', 'a', '4', 'a', '5', 'a', '6', 'a', '7', 'a', '8', 'a', '9', 'a', 'a', 'a', 'b', 'a', 'c', 'a', 'd', 'a', 'e', 'a', 'f',
'b', '0', 'b', '1', 'b', '2', 'b', '3', 'b', '4', 'b', '5', 'b', '6', 'b', '7', 'b', '8', 'b', '9', 'b', 'a', 'b', 'b', 'b', 'c', 'b', 'd', 'b', 'e', 'b', 'f',
'c', '0', 'c', '1', 'c', '2', 'c', '3', 'c', '4', 'c', '5', 'c', '6', 'c', '7', 'c', '8', 'c', '9', 'c', 'a', 'c', 'b', 'c', 'c', 'c', 'd', 'c', 'e', 'c', 'f',
'd', '0', 'd', '1', 'd', '2', 'd', '3', 'd', '4', 'd', '5', 'd', '6', 'd', '7', 'd', '8', 'd', '9', 'd', 'a', 'd', 'b', 'd', 'c', 'd', 'd', 'd', 'e', 'd', 'f',
'e', '0', 'e', '1', 'e', '2', 'e', '3', 'e', '4', 'e', '5', 'e', '6', 'e', '7', 'e', '8', 'e', '9', 'e', 'a', 'e', 'b', 'e', 'c', 'e', 'd', 'e', 'e', 'e', 'f',
'f', '0', 'f', '1', 'f', '2', 'f', '3', 'f', '4', 'f', '5', 'f', '6', 'f', '7', 'f', '8', 'f', '9', 'f', 'a', 'f', 'b', 'f', 'c', 'f', 'd', 'f', 'e', 'f', 'f'
};

template <unsigned _Base>
struct _LIBCPP_HIDDEN __integral;

Expand Down Expand Up @@ -394,7 +316,7 @@ struct _LIBCPP_HIDDEN __integral<2> {
unsigned __c = __value % __divisor;
__value /= __divisor;
__p -= 4;
std::memcpy(__p, &__base_2_lut[4 * __c], 4);
std::memcpy(__p, &__table<>::__base_2_lut[4 * __c], 4);
}
do {
unsigned __c = __value % 2;
Expand Down Expand Up @@ -429,7 +351,7 @@ struct _LIBCPP_HIDDEN __integral<8> {
unsigned __c = __value % __divisor;
__value /= __divisor;
__p -= 2;
std::memcpy(__p, &__base_8_lut[2 * __c], 2);
std::memcpy(__p, &__table<>::__base_8_lut[2 * __c], 2);
}
do {
unsigned __c = __value % 8;
Expand Down Expand Up @@ -465,7 +387,7 @@ struct _LIBCPP_HIDDEN __integral<16> {
unsigned __c = __value % __divisor;
__value /= __divisor;
__p -= 2;
std::memcpy(__p, &__base_16_lut[2 * __c], 2);
std::memcpy(__p, &__table<>::__base_16_lut[2 * __c], 2);
}
if (__first != __last)
do {
Expand Down
2 changes: 1 addition & 1 deletion libcxx/src/include/ryu/digit_table.h
Expand Up @@ -50,7 +50,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// In order to minimize the diff in the Ryu code between MSVC STL and libc++
// the code uses the name __DIGIT_TABLE. In order to avoid code duplication it
// reuses the table already available in libc++.
inline constexpr auto& __DIGIT_TABLE = __itoa::__digits_base_10<>::__value;
inline constexpr auto& __DIGIT_TABLE = __itoa::__table<>::__digits_base_10;

_LIBCPP_END_NAMESPACE_STD

Expand Down

0 comments on commit dea7a8e

Please sign in to comment.