diff options
author | Arthur O'Dwyer <arthur.j.odwyer@gmail.com> | 2022-02-24 04:08:28 +0300 |
---|---|---|
committer | Arthur O'Dwyer <arthur.j.odwyer@gmail.com> | 2022-03-05 01:31:09 +0300 |
commit | 3347e7d40fd83ae762dcdb7c6161550e4190d6cf (patch) | |
tree | 1e8f74740237731e53851608078d2708bce27198 /libcxx | |
parent | 988d4b0d62e4e63122f3b8ac856585e85973508d (diff) |
[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
Diffstat (limited to 'libcxx')
-rw-r--r-- | libcxx/docs/Status/Cxx2bIssues.csv | 5 | ||||
-rw-r--r-- | libcxx/include/bit | 4 | ||||
-rw-r--r-- | libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp | 40 |
3 files changed, 25 insertions, 24 deletions
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index ba8aea2ffcf3..0b2dbf4eef9e 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -157,7 +157,8 @@ "`3654 <https://wg21.link/LWG3654>`__","``basic_format_context::arg(size_t)`` should be ``noexcept`` ","February 2022","|Complete|","15.0","|format|" "`3657 <https://wg21.link/LWG3657>`__","``std::hash<std::filesystem::path>`` is not enabled","February 2022","","" "`3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to ยง[iterator.traits]","February 2022","|Complete|","14.0" -"`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a (nullptr);`` should work","February 2022","","" +"`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","","" "","","","","" -`3645 <https://wg21.link/LWG3645>`__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0","" +"`3645 <https://wg21.link/LWG3645>`__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0","" +"`3656 <https://wg21.link/LWG3656>`__","Inconsistent bit operations returning a count","Not voted in","|Complete|","15.0","" "","","","","" diff --git a/libcxx/include/bit b/libcxx/include/bit index 7f9318ecde1e..aaefd8a362cf 100644 --- a/libcxx/include/bit +++ b/libcxx/include/bit @@ -30,7 +30,7 @@ namespace std { template <class T> constexpr T bit_floor(T x) noexcept; // C++20 template <class T> - constexpr T bit_width(T x) noexcept; // C++20 + constexpr int bit_width(T x) noexcept; // C++20 // [bit.rotate], rotating template<class T> @@ -322,7 +322,7 @@ bit_ceil(_Tp __t) noexcept template <class _Tp> _LIBCPP_INLINE_VISIBILITY constexpr -enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, _Tp> +enable_if_t<__libcpp_is_unsigned_integer<_Tp>::value, int> bit_width(_Tp __t) noexcept { return __t == 0 ? 0 : __bit_log2(__t) + 1; diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp index 84b00efa7ed4..c191015e16ee 100644 --- a/libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp +++ b/libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp @@ -9,7 +9,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // template <class T> -// constexpr T bit_width(T x) noexcept; +// constexpr int bit_width(T x) noexcept; // Constraints: T is an unsigned integer type // 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 }; template <class T> constexpr bool test() { - ASSERT_SAME_TYPE(decltype(std::bit_width(T())), T); + ASSERT_SAME_TYPE(decltype(std::bit_width(T())), int); ASSERT_NOEXCEPT(std::bit_width(T())); T max = std::numeric_limits<T>::max(); - assert(std::bit_width(T(0)) == T(0)); - assert(std::bit_width(T(1)) == T(1)); - assert(std::bit_width(T(2)) == T(2)); - assert(std::bit_width(T(3)) == T(2)); - assert(std::bit_width(T(4)) == T(3)); - assert(std::bit_width(T(5)) == T(3)); - assert(std::bit_width(T(6)) == T(3)); - assert(std::bit_width(T(7)) == T(3)); - assert(std::bit_width(T(8)) == T(4)); - assert(std::bit_width(T(9)) == T(4)); - assert(std::bit_width(T(125)) == T(7)); - assert(std::bit_width(T(126)) == T(7)); - assert(std::bit_width(T(127)) == T(7)); - assert(std::bit_width(T(128)) == T(8)); - assert(std::bit_width(T(129)) == T(8)); - assert(std::bit_width(T(130)) == T(8)); - assert(std::bit_width(T(max - 1)) == T(std::numeric_limits<T>::digits)); - assert(std::bit_width(max) == T(std::numeric_limits<T>::digits)); + assert(std::bit_width(T(0)) == 0); + assert(std::bit_width(T(1)) == 1); + assert(std::bit_width(T(2)) == 2); + assert(std::bit_width(T(3)) == 2); + assert(std::bit_width(T(4)) == 3); + assert(std::bit_width(T(5)) == 3); + assert(std::bit_width(T(6)) == 3); + assert(std::bit_width(T(7)) == 3); + assert(std::bit_width(T(8)) == 4); + assert(std::bit_width(T(9)) == 4); + assert(std::bit_width(T(125)) == 7); + assert(std::bit_width(T(126)) == 7); + assert(std::bit_width(T(127)) == 7); + assert(std::bit_width(T(128)) == 8); + assert(std::bit_width(T(129)) == 8); + assert(std::bit_width(T(130)) == 8); + assert(std::bit_width(T(max - 1)) == std::numeric_limits<T>::digits); + assert(std::bit_width(max) == std::numeric_limits<T>::digits); #ifndef TEST_HAS_NO_INT128 if constexpr (std::is_same_v<T, __uint128_t>) { |