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:
Charlie Barto 2020-02-24 19:00:15 -08:00 коммит произвёл GitHub
Родитель 6d138d55e3
Коммит e03429600e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 122 добавлений и 122 удалений

Просмотреть файл

@ -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