Implement LWG-3656: Inconsistent bit operations returning a count (#2880)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
A. Jiang 2022-07-28 10:10:23 +08:00 коммит произвёл GitHub
Родитель f67fef19aa
Коммит da41fe1a74
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 17 добавлений и 6 удалений

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

@ -82,8 +82,8 @@ _NODISCARD constexpr _Ty bit_floor(const _Ty _Val) noexcept {
}
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_NODISCARD constexpr _Ty bit_width(const _Ty _Val) noexcept {
return static_cast<_Ty>(numeric_limits<_Ty>::digits - _STD countl_zero(_Val));
_NODISCARD constexpr int bit_width(const _Ty _Val) noexcept {
return numeric_limits<_Ty>::digits - _STD countl_zero(_Val);
}
template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>

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

@ -2939,7 +2939,7 @@ _NODISCARD _OutputIt _Fmt_write(
// Add 3 to the bit width so we always round up on the division.
// Divide that by the amount of bits a hexit represents (log2(16) = log2(2^4) = 4).
// Add 2 for the 0x prefix.
_Width = static_cast<int>(2 + (_STD bit_width(reinterpret_cast<uintptr_t>(_Value)) + 3) / 4);
_Width = 2 + (_STD bit_width(reinterpret_cast<uintptr_t>(_Value)) + 3) / 4;
}
return _Write_aligned(_STD move(_Out), _Width, _Specs, _Fmt_align::_Right,

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

@ -652,6 +652,9 @@ std/utilities/charconv/charconv.msvc/test.pass.cpp FAIL
std/ranges/range.adaptors/range.transform/end.pass.cpp FAIL
std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp FAIL
# libc++ doesn't yet implement LWG-3656 (https://reviews.llvm.org/D120444)
std/numerics/bit/bit.pow.two/bit_width.pass.cpp FAIL
# MaybePOCCAAllocator doesn't meet the allocator requirements
std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp FAIL

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

@ -652,6 +652,9 @@ utilities\charconv\charconv.msvc\test.pass.cpp
ranges\range.adaptors\range.transform\end.pass.cpp
ranges\range.adaptors\range.transform\iterator\base.pass.cpp
# libc++ doesn't yet implement LWG-3656 (https://reviews.llvm.org/D120444)
numerics\bit\bit.pow.two\bit_width.pass.cpp
# MaybePOCCAAllocator doesn't meet the allocator requirements
containers\sequences\vector\vector.cons\assign_copy.pass.cpp

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

@ -3,6 +3,7 @@
#include <bit>
#include <cassert>
#include <limits>
#include <type_traits>
#include <utility>
using namespace std;
@ -76,12 +77,16 @@ constexpr bool test_bit_floor() {
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(T{0}) == 0);
assert(bit_width(numeric_limits<T>::max()) == digits);
assert(bit_width(T{1}) == T{1});
assert(bit_width(T{1}) == 1);
for (int i = 1; i < digits; ++i) {
assert(bit_width(static_cast<T>(T{1} << i)) == static_cast<T>(i + 1));
assert(bit_width(static_cast<T>(T{1} << i)) == i + 1);
}
// LWG-3656: bit_width returns int
static_assert(is_same_v<decltype(bit_width(T{0})), int>);
return true;
}