зеркало из https://github.com/microsoft/STL.git
P1956R1 <bit> has_single_bit(), bit_ceil(), bit_floor(), bit_width() (#524)
* apply P1956R1 Mirror of MSVC-PR-231381 * rename test folder and update yvals_core naming * repair test.lst * fix nitpicks
This commit is contained in:
Родитель
6d138d55e3
Коммит
e03429600e
|
@ -35,12 +35,12 @@ template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
|
|||
_NODISCARD constexpr int countl_zero(_Ty _Val) noexcept;
|
||||
|
||||
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
|
||||
_NODISCARD constexpr bool ispow2(const _Ty _Val) noexcept {
|
||||
_NODISCARD constexpr bool has_single_bit(const _Ty _Val) noexcept {
|
||||
return _Val != 0 && (_Val & (_Val - 1)) == 0;
|
||||
}
|
||||
|
||||
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
|
||||
_NODISCARD constexpr _Ty ceil2(const _Ty _Val) noexcept /* strengthened */ {
|
||||
_NODISCARD constexpr _Ty bit_ceil(const _Ty _Val) noexcept /* strengthened */ {
|
||||
if (_Val == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ _NODISCARD constexpr _Ty ceil2(const _Ty _Val) noexcept /* strengthened */ {
|
|||
}
|
||||
|
||||
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
|
||||
_NODISCARD constexpr _Ty floor2(const _Ty _Val) noexcept {
|
||||
_NODISCARD constexpr _Ty bit_floor(const _Ty _Val) noexcept {
|
||||
if (_Val == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ _NODISCARD constexpr _Ty floor2(const _Ty _Val) noexcept {
|
|||
}
|
||||
|
||||
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
|
||||
_NODISCARD constexpr _Ty bit_length(const _Ty _Val) noexcept {
|
||||
_NODISCARD constexpr _Ty bit_width(const _Ty _Val) noexcept {
|
||||
return static_cast<_Ty>(numeric_limits<_Ty>::digits - _STD countl_zero(_Val));
|
||||
}
|
||||
|
||||
|
|
|
@ -145,8 +145,7 @@
|
|||
// P0487R1 Fixing operator>>(basic_istream&, CharT*)
|
||||
// P0550R2 remove_cvref
|
||||
// P0553R4 <bit> Rotating And Counting Functions
|
||||
// P0556R3 <bit> ispow2(), ceil2(), floor2(), log2p1()
|
||||
// (log2p1() is called bit_length() as of D1956)
|
||||
// P0556R3 <bit> Integral Power-Of-2 Operations (renamed by P1956R1)
|
||||
// P0595R2 is_constant_evaluated()
|
||||
// P0616R0 Using move() In <numeric>
|
||||
// P0631R8 <numbers> Math Constants
|
||||
|
@ -182,6 +181,7 @@
|
|||
// P1754R1 Rename Concepts To standard_case
|
||||
// P1870R1 safe_range
|
||||
// P1872R0 span Should Have size_type, Not index_type
|
||||
// P1956R1 <bit> has_single_bit(), bit_ceil(), bit_floor(), bit_width()
|
||||
// P1959R0 Removing weak_equality And strong_equality
|
||||
// P????R? directory_entry::clear_cache()
|
||||
|
||||
|
@ -1084,7 +1084,7 @@
|
|||
#define __cpp_lib_endian 201907L
|
||||
#define __cpp_lib_erase_if 201811L
|
||||
#define __cpp_lib_generic_unordered_lookup 201811L
|
||||
#define __cpp_lib_int_pow2 201806L
|
||||
#define __cpp_lib_int_pow2 202002L
|
||||
#define __cpp_lib_is_constant_evaluated 201811L
|
||||
#define __cpp_lib_is_nothrow_convertible 201806L
|
||||
#define __cpp_lib_list_remove_return_type 201806L
|
||||
|
|
|
@ -212,7 +212,7 @@ tests\P0433R2_deduction_guides
|
|||
tests\P0487R1_fixing_operator_shl_basic_istream_char_pointer
|
||||
tests\P0513R0_poisoning_the_hash
|
||||
tests\P0553R4_bit_rotating_and_counting_functions
|
||||
tests\P0556R3_bit_ispow2_ceil2_floor2_log2p1
|
||||
tests\P0556R3_bit_integral_power_of_two_operations
|
||||
tests\P0595R2_is_constant_evaluated
|
||||
tests\P0607R0_inline_variables
|
||||
tests\P0616R0_using_move_in_numeric
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#include <assert.h>
|
||||
#include <bit>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212
|
||||
template <typename T>
|
||||
constexpr bool test_has_single_bit() {
|
||||
assert(!has_single_bit(T{0}));
|
||||
assert(!has_single_bit(numeric_limits<T>::max()));
|
||||
assert(has_single_bit(T{1}));
|
||||
assert(has_single_bit(T{2}));
|
||||
for (int i = 2; i < numeric_limits<T>::digits; ++i) {
|
||||
const T ith_power_of_two = static_cast<T>(T{1} << i);
|
||||
assert(has_single_bit(ith_power_of_two));
|
||||
assert(!has_single_bit(static_cast<T>(ith_power_of_two - 1)));
|
||||
assert(!has_single_bit(static_cast<T>(ith_power_of_two + 1)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool test_bit_ceil_specialcases_unsigned() {
|
||||
assert(bit_ceil(0x6FFFFFFFu) == 0x80000000u);
|
||||
assert(bit_ceil(0x6FFFFFFF'FFFFFFFFull) == 0x80000000'00000000ull);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_bit_ceil() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(bit_ceil(T{0}) == T{1});
|
||||
assert(bit_ceil(T{1}) == T{1});
|
||||
assert(bit_ceil(T{2}) == T{2});
|
||||
assert(bit_ceil(T{3}) == T{4});
|
||||
for (int i = 2; i < digits - 1; ++i) {
|
||||
const auto one_in_ith_place = static_cast<T>(T{1} << i);
|
||||
assert(bit_ceil(static_cast<T>(one_in_ith_place - 1)) == one_in_ith_place);
|
||||
assert(bit_ceil(one_in_ith_place) == one_in_ith_place);
|
||||
assert(bit_ceil(static_cast<T>(one_in_ith_place + 1)) == static_cast<T>(one_in_ith_place << 1));
|
||||
}
|
||||
constexpr auto one_in_last_place = static_cast<T>(T{1} << (digits - 1));
|
||||
assert(bit_ceil(one_in_last_place) == one_in_last_place);
|
||||
assert(bit_ceil(static_cast<T>(one_in_last_place - 1)) == one_in_last_place);
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool test_bit_floor_specialcases_unsigned() {
|
||||
assert(bit_floor(0xFFFFFFFFu) == 0x80000000u);
|
||||
// some hex literals are never hungry
|
||||
assert(bit_floor(0xFFFFFFFF'FFFFFFFFull) == 0x80000000'00000000ull);
|
||||
assert(bit_floor(0x0A930432u) == 0x8000000u);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_bit_floor() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(bit_floor(T{0}) == T{0});
|
||||
assert(bit_floor(T{1}) == T{1});
|
||||
for (int i = 1; i < digits - 1; ++i) {
|
||||
const auto one_in_ith_place = static_cast<T>(T{1} << i);
|
||||
assert(bit_floor(static_cast<T>(one_in_ith_place - 1)) == static_cast<T>(one_in_ith_place >> 1));
|
||||
assert(bit_floor(one_in_ith_place) == one_in_ith_place);
|
||||
assert(bit_floor(static_cast<T>(one_in_ith_place + 1)) == one_in_ith_place);
|
||||
}
|
||||
constexpr auto one_in_last_place = static_cast<T>(T{1} << (digits - 1));
|
||||
assert(bit_floor(one_in_last_place) == one_in_last_place);
|
||||
assert(bit_floor(static_cast<T>(one_in_last_place - 1)) == static_cast<T>(one_in_last_place >> 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_bit_width() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(bit_width(T{0}) == T{0});
|
||||
assert(bit_width(numeric_limits<T>::max()) == digits);
|
||||
assert(bit_width(T{1}) == T{1});
|
||||
for (int i = 1; i < digits; ++i) {
|
||||
assert(bit_width(static_cast<T>(T{1} << i)) == static_cast<T>(i + 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_all() {
|
||||
static_assert(test_has_single_bit<T>());
|
||||
test_has_single_bit<T>();
|
||||
static_assert(test_bit_ceil<T>());
|
||||
test_bit_ceil<T>();
|
||||
static_assert(test_bit_floor<T>());
|
||||
test_bit_floor<T>();
|
||||
static_assert(test_bit_width<T>());
|
||||
test_bit_width<T>();
|
||||
}
|
||||
#endif // __cpp_lib_bitops
|
||||
|
||||
int main() {
|
||||
#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212
|
||||
test_all<unsigned char>();
|
||||
test_all<unsigned short>();
|
||||
test_all<unsigned int>();
|
||||
test_all<unsigned long>();
|
||||
test_all<unsigned long long>();
|
||||
test_bit_floor_specialcases_unsigned();
|
||||
test_bit_ceil_specialcases_unsigned();
|
||||
#endif // __cpp_lib_bitops
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#include <assert.h>
|
||||
#include <bit>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212
|
||||
template <typename T>
|
||||
constexpr bool test_ispow2() {
|
||||
assert(!ispow2(T{0}));
|
||||
assert(!ispow2(numeric_limits<T>::max()));
|
||||
assert(ispow2(T{1}));
|
||||
assert(ispow2(T{2}));
|
||||
for (int i = 2; i < numeric_limits<T>::digits; ++i) {
|
||||
const T ith_power_of_two = static_cast<T>(T{1} << i);
|
||||
assert(ispow2(ith_power_of_two));
|
||||
assert(!ispow2(static_cast<T>(ith_power_of_two - 1)));
|
||||
assert(!ispow2(static_cast<T>(ith_power_of_two + 1)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool test_ceil2_specialcases_unsigned() {
|
||||
assert(ceil2(0x6FFFFFFFu) == 0x80000000u);
|
||||
assert(ceil2(0x6FFFFFFF'FFFFFFFFull) == 0x80000000'00000000ull);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_ceil2() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(ceil2(T{0}) == T{1});
|
||||
assert(ceil2(T{1}) == T{1});
|
||||
assert(ceil2(T{2}) == T{2});
|
||||
assert(ceil2(T{3}) == T{4});
|
||||
for (int i = 2; i < digits - 1; ++i) {
|
||||
const auto one_in_ith_place = static_cast<T>(T{1} << i);
|
||||
assert(ceil2(static_cast<T>(one_in_ith_place - 1)) == one_in_ith_place);
|
||||
assert(ceil2(one_in_ith_place) == one_in_ith_place);
|
||||
assert(ceil2(static_cast<T>(one_in_ith_place + 1)) == static_cast<T>(one_in_ith_place << 1));
|
||||
}
|
||||
constexpr auto one_in_last_place = static_cast<T>(T{1} << (digits - 1));
|
||||
assert(ceil2(one_in_last_place) == one_in_last_place);
|
||||
assert(ceil2(static_cast<T>(one_in_last_place - 1)) == one_in_last_place);
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool test_floor2_specialcases_unsigned() {
|
||||
assert(floor2(0xFFFFFFFFu) == 0x80000000u);
|
||||
// some hex literals are never hungry
|
||||
assert(floor2(0xFFFFFFFF'FFFFFFFFull) == 0x80000000'00000000ull);
|
||||
assert(floor2(0x0A930432u) == 0x8000000u);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_floor2() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(floor2(T{0}) == T{0});
|
||||
assert(floor2(T{1}) == T{1});
|
||||
for (int i = 1; i < digits - 1; ++i) {
|
||||
const auto one_in_ith_place = static_cast<T>(T{1} << i);
|
||||
assert(floor2(static_cast<T>(one_in_ith_place - 1)) == static_cast<T>(one_in_ith_place >> 1));
|
||||
assert(floor2(one_in_ith_place) == one_in_ith_place);
|
||||
assert(floor2(static_cast<T>(one_in_ith_place + 1)) == one_in_ith_place);
|
||||
}
|
||||
constexpr auto one_in_last_place = static_cast<T>(T{1} << (digits - 1));
|
||||
assert(floor2(one_in_last_place) == one_in_last_place);
|
||||
assert(floor2(static_cast<T>(one_in_last_place - 1)) == static_cast<T>(one_in_last_place >> 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool test_bit_length() {
|
||||
constexpr int digits = numeric_limits<T>::digits;
|
||||
assert(bit_length(T{0}) == T{0});
|
||||
assert(bit_length(numeric_limits<T>::max()) == digits);
|
||||
assert(bit_length(T{1}) == T{1});
|
||||
for (int i = 1; i < digits; ++i) {
|
||||
assert(bit_length(static_cast<T>(T{1} << i)) == static_cast<T>(i + 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_all() {
|
||||
static_assert(test_ispow2<T>());
|
||||
test_ispow2<T>();
|
||||
static_assert(test_ceil2<T>());
|
||||
test_ceil2<T>();
|
||||
static_assert(test_floor2<T>());
|
||||
test_floor2<T>();
|
||||
static_assert(test_bit_length<T>());
|
||||
test_bit_length<T>();
|
||||
}
|
||||
#endif // __cpp_lib_bitops
|
||||
|
||||
int main() {
|
||||
#ifdef __cpp_lib_bitops // TRANSITION, VSO-1020212
|
||||
test_all<unsigned char>();
|
||||
test_all<unsigned short>();
|
||||
test_all<unsigned int>();
|
||||
test_all<unsigned long>();
|
||||
test_all<unsigned long long>();
|
||||
test_floor2_specialcases_unsigned();
|
||||
test_ceil2_specialcases_unsigned();
|
||||
#endif // __cpp_lib_bitops
|
||||
}
|
|
@ -1628,10 +1628,10 @@ STATIC_ASSERT(__cpp_lib_generic_unordered_lookup == 201811L);
|
|||
#if CXX20_MODE
|
||||
#ifndef __cpp_lib_int_pow2
|
||||
#error BOOM
|
||||
#elif __cpp_lib_int_pow2 != 201806L
|
||||
#elif __cpp_lib_int_pow2 != 202002L
|
||||
#error BOOM
|
||||
#else
|
||||
STATIC_ASSERT(__cpp_lib_int_pow2 == 201806L);
|
||||
STATIC_ASSERT(__cpp_lib_int_pow2 == 202002L);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cpp_lib_int_pow2
|
||||
|
|
Загрузка…
Ссылка в новой задаче