Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement P2291R3 constexpr Integral <charconv> #3049

Merged
merged 9 commits into from
Aug 27, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 43 additions & 40 deletions stl/inc/charconv
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ inline constexpr char _Charconv_digits[] = {'0', '1', '2', '3', '4', '5', '6', '
_STL_INTERNAL_STATIC_ASSERT(_STD size(_Charconv_digits) == 36);

template <class _RawTy>
_NODISCARD to_chars_result _Integer_to_chars(
_NODISCARD _CONSTEXPR23 to_chars_result _Integer_to_chars(
char* _First, char* const _Last, const _RawTy _Raw_value, const int _Base) noexcept {
_Adl_verify_range(_First, _Last);
_STL_ASSERT(_Base >= 2 && _Base <= 36, "invalid base in to_chars()");
Expand Down Expand Up @@ -152,52 +152,55 @@ _NODISCARD to_chars_result _Integer_to_chars(
return {_Last, errc::value_too_large};
}

_CSTD memcpy(_First, _RNext, static_cast<size_t>(_Digits_written));
_STD copy_n(_RNext, static_cast<size_t>(_Digits_written), _First);
AdamBucior marked this conversation as resolved.
Show resolved Hide resolved

return {_First + _Digits_written, errc{}};
}

inline to_chars_result to_chars(char* const _First, char* const _Last, const char _Value, const int _Base = 10) noexcept
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const char _Value, const int _Base = 10) noexcept
/* strengthened */ {
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const signed char _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const unsigned char _Value,
_CONSTEXPR23 to_chars_result to_chars(char* const _First, char* const _Last, const unsigned char _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const short _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const unsigned short _Value,
_CONSTEXPR23 to_chars_result to_chars(char* const _First, char* const _Last, const unsigned short _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const int _Value, const int _Base = 10) noexcept
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const int _Value, const int _Base = 10) noexcept
/* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const unsigned int _Value,
_CONSTEXPR23 to_chars_result to_chars(char* const _First, char* const _Last, const unsigned int _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const long _Value, const int _Base = 10) noexcept
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const long _Value, const int _Base = 10) noexcept
/* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const unsigned long _Value,
_CONSTEXPR23 to_chars_result to_chars(char* const _First, char* const _Last, const unsigned long _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(
_CONSTEXPR23 to_chars_result to_chars(
char* const _First, char* const _Last, const long long _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
inline to_chars_result to_chars(char* const _First, char* const _Last, const unsigned long long _Value,
_CONSTEXPR23 to_chars_result to_chars(char* const _First, char* const _Last, const unsigned long long _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_to_chars(_First, _Last, _Value, _Base);
}
Expand All @@ -213,27 +216,27 @@ struct from_chars_result {
#endif // _HAS_CXX20
};

_NODISCARD inline unsigned char _Digit_from_char(const char _Ch) noexcept {
// convert ['0', '9'] ['A', 'Z'] ['a', 'z'] to [0, 35], everything else to 255
inline constexpr unsigned char _Digit_from_byte[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255,
255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
_STL_INTERNAL_STATIC_ASSERT(_STD size(_Digit_from_byte) == 256);

_NODISCARD _CONSTEXPR23 unsigned char _Digit_from_char(const char _Ch) noexcept {
// convert ['0', '9'] ['A', 'Z'] ['a', 'z'] to [0, 35], everything else to 255
static constexpr unsigned char _Digit_from_byte[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255};
_STL_INTERNAL_STATIC_ASSERT(_STD size(_Digit_from_byte) == 256);

return _Digit_from_byte[static_cast<unsigned char>(_Ch)];
}

template <class _RawTy>
_NODISCARD from_chars_result _Integer_from_chars(
_NODISCARD _CONSTEXPR23 from_chars_result _Integer_from_chars(
const char* const _First, const char* const _Last, _RawTy& _Raw_value, const int _Base) noexcept {
_Adl_verify_range(_First, _Last);
_STL_ASSERT(_Base >= 2 && _Base <= 36, "invalid base in from_chars()");
Expand Down Expand Up @@ -309,47 +312,47 @@ _NODISCARD from_chars_result _Integer_from_chars(
return {_Next, errc{}};
}

inline from_chars_result from_chars(
_CONSTEXPR23 from_chars_result from_chars(
const char* const _First, const char* const _Last, char& _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, signed char& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, signed char& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned char& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned char& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, short& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, short& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned short& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned short& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(
_CONSTEXPR23 from_chars_result from_chars(
const char* const _First, const char* const _Last, int& _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned int& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned int& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(
_CONSTEXPR23 from_chars_result from_chars(
const char* const _First, const char* const _Last, long& _Value, const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned long& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned long& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, long long& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, long long& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
inline from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned long long& _Value,
_CONSTEXPR23 from_chars_result from_chars(const char* const _First, const char* const _Last, unsigned long long& _Value,
const int _Base = 10) noexcept /* strengthened */ {
return _Integer_from_chars(_First, _Last, _Value, _Base);
}
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@
// P2166R1 Prohibiting basic_string And basic_string_view Construction From nullptr
// P2186R2 Removing Garbage Collection Support
// P2273R3 constexpr unique_ptr
// P2291R3 constexpr Integral <charconv>
// P2302R4 ranges::contains, ranges::contains_subrange
// P2321R2 zip
// (changes to pair, tuple, and vector<bool>::reference only)
Expand Down Expand Up @@ -1496,6 +1497,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#define __cpp_lib_bind_back 202202L
#define __cpp_lib_byteswap 202110L
#define __cpp_lib_constexpr_bitset 202207L
#define __cpp_lib_constexpr_charconv 202207L
#define __cpp_lib_constexpr_typeinfo 202106L

#ifdef __cpp_lib_concepts
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ tests\P2136R3_invoke_r
tests\P2162R2_std_visit_for_derived_classes_from_variant
tests\P2231R1_complete_constexpr_optional_variant
tests\P2273R3_constexpr_unique_ptr
tests\P2291R3_constexpr_integral_charconv
tests\P2302R4_ranges_alg_contains
tests\P2302R4_ranges_alg_contains_subrange
tests\P2321R2_proxy_reference
Expand Down
7 changes: 7 additions & 0 deletions tests/std/tests/P2291R3_constexpr_integral_charconv/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
RUNALL_CROSSLIST
PM_CL="/DTEST_PART=0"
PM_CL="/DTEST_PART=1"
Loading