Skip to content

Commit 3347e7d

Browse files
committed
[libc++] [LWG3656] Update the return type of std::bit_width.
Fixes LWG3656, "Inconsistent bit operations returning a count". https://cplusplus.github.io/LWG/issue3656 The fix has been approved for C++23 and left to vendors' discretion in C++20 (but it sounds like everyone's on the same page that of course it should be DR'ed back to C++20 too). Differential Revision: https://reviews.llvm.org/D120444
1 parent 988d4b0 commit 3347e7d

File tree

3 files changed

+25
-24
lines changed

3 files changed

+25
-24
lines changed

libcxx/docs/Status/Cxx2bIssues.csv

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@
157157
"`3654 <https://wg21.link/LWG3654>`__","``basic_format_context::arg(size_t)`` should be ``noexcept`` ","February 2022","|Complete|","15.0","|format|"
158158
"`3657 <https://wg21.link/LWG3657>`__","``std::hash<std::filesystem::path>`` is not enabled","February 2022","",""
159159
"`3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to §[iterator.traits]","February 2022","|Complete|","14.0"
160-
"`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a (nullptr);`` should work","February 2022","",""
160+
"`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","",""
161161
"","","","",""
162-
`3645 <https://wg21.link/LWG3645>`__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0",""
162+
"`3645 <https://wg21.link/LWG3645>`__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0",""
163+
"`3656 <https://wg21.link/LWG3656>`__","Inconsistent bit operations returning a count","Not voted in","|Complete|","15.0",""
163164
"","","","",""

libcxx/include/bit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace std {
3030
template <class T>
3131
constexpr T bit_floor(T x) noexcept; // C++20
3232
template <class T>
33-
constexpr T bit_width(T x) noexcept; // C++20
33+
constexpr int bit_width(T x) noexcept; // C++20
3434
3535
// [bit.rotate], rotating
3636
template<class T>
@@ -322,7 +322,7 @@ bit_ceil(_Tp __t) noexcept
322322

323323
template <class _Tp>
324324
_LIBCPP_INLINE_VISIBILITY constexpr
325-
enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
325+
enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int>
326326
bit_width(_Tp __t) noexcept
327327
{
328328
return __t == 0 ? 0 : __bit_log2(__t) + 1;

libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// UNSUPPORTED: c++03, c++11, c++14, c++17
1010

1111
// template <class T>
12-
// constexpr T bit_width(T x) noexcept;
12+
// constexpr int bit_width(T x) noexcept;
1313

1414
// Constraints: T is an unsigned integer type
1515
// Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded.
@@ -29,28 +29,28 @@ enum class E2 : unsigned char { red };
2929
template <class T>
3030
constexpr bool test()
3131
{
32-
ASSERT_SAME_TYPE(decltype(std::bit_width(T())), T);
32+
ASSERT_SAME_TYPE(decltype(std::bit_width(T())), int);
3333
ASSERT_NOEXCEPT(std::bit_width(T()));
3434
T max = std::numeric_limits<T>::max();
3535

36-
assert(std::bit_width(T(0)) == T(0));
37-
assert(std::bit_width(T(1)) == T(1));
38-
assert(std::bit_width(T(2)) == T(2));
39-
assert(std::bit_width(T(3)) == T(2));
40-
assert(std::bit_width(T(4)) == T(3));
41-
assert(std::bit_width(T(5)) == T(3));
42-
assert(std::bit_width(T(6)) == T(3));
43-
assert(std::bit_width(T(7)) == T(3));
44-
assert(std::bit_width(T(8)) == T(4));
45-
assert(std::bit_width(T(9)) == T(4));
46-
assert(std::bit_width(T(125)) == T(7));
47-
assert(std::bit_width(T(126)) == T(7));
48-
assert(std::bit_width(T(127)) == T(7));
49-
assert(std::bit_width(T(128)) == T(8));
50-
assert(std::bit_width(T(129)) == T(8));
51-
assert(std::bit_width(T(130)) == T(8));
52-
assert(std::bit_width(T(max - 1)) == T(std::numeric_limits<T>::digits));
53-
assert(std::bit_width(max) == T(std::numeric_limits<T>::digits));
36+
assert(std::bit_width(T(0)) == 0);
37+
assert(std::bit_width(T(1)) == 1);
38+
assert(std::bit_width(T(2)) == 2);
39+
assert(std::bit_width(T(3)) == 2);
40+
assert(std::bit_width(T(4)) == 3);
41+
assert(std::bit_width(T(5)) == 3);
42+
assert(std::bit_width(T(6)) == 3);
43+
assert(std::bit_width(T(7)) == 3);
44+
assert(std::bit_width(T(8)) == 4);
45+
assert(std::bit_width(T(9)) == 4);
46+
assert(std::bit_width(T(125)) == 7);
47+
assert(std::bit_width(T(126)) == 7);
48+
assert(std::bit_width(T(127)) == 7);
49+
assert(std::bit_width(T(128)) == 8);
50+
assert(std::bit_width(T(129)) == 8);
51+
assert(std::bit_width(T(130)) == 8);
52+
assert(std::bit_width(T(max - 1)) == std::numeric_limits<T>::digits);
53+
assert(std::bit_width(max) == std::numeric_limits<T>::digits);
5454

5555
#ifndef TEST_HAS_NO_INT128
5656
if constexpr (std::is_same_v<T, __uint128_t>) {

0 commit comments

Comments
 (0)