aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
authorMark de Wever <koraq@xs4all.nl>2020-11-24 14:50:49 +0100
committerMark de Wever <koraq@xs4all.nl>2020-11-24 17:37:06 +0100
commit1a036e9cc82a7f6d6f4675d631fa5eecd8748784 (patch)
treeb572cf452a9e526e1077f5763481fcca55f0c8e7 /libcxx
parent11b76258331659daa57e15fe86c1f1234267a78d (diff)
downloadllvm-project-1a036e9cc82a7f6d6f4675d631fa5eecd8748784.tar.gz
[libcxx] Implement P1956 rename low-level bit functions
Implements P1956: On the names of low-level bit manipulation functions. Users may use older versions of libc++ or other standard libraries with the old names. In order to keep compatibility the old functions are kept, but marked as deprecated. The patch also adds a new config macro `_LIBCPP_DEPRECATED_MSG`. Do you prefer a this is a separate patch? Reviewed By: ldionne, #libc Differential Revision: https://reviews.llvm.org/D90551
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/docs/FeatureTestMacroTable.rst2
-rw-r--r--libcxx/docs/ReleaseNotes.rst7
-rw-r--r--libcxx/include/bit27
-rw-r--r--libcxx/include/version2
-rw-r--r--libcxx/test/libcxx/numerics/bit.ops.pass.cpp6
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp20
-rw-r--r--libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp20
-rw-r--r--libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp (renamed from libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp)4
-rw-r--r--libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.pass.cpp (renamed from libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp)52
-rw-r--r--libcxx/test/std/numerics/bit/bit.pow.two/bit_floor.pass.cpp (renamed from libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp)70
-rw-r--r--libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp (renamed from libcxx/test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp)92
-rw-r--r--libcxx/test/std/numerics/bit/bit.pow.two/has_single_bit.pass.cpp (renamed from libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp)66
-rwxr-xr-xlibcxx/utils/generate_feature_test_macro_components.py4
-rw-r--r--libcxx/www/cxx2a_status.html2
14 files changed, 214 insertions, 160 deletions
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 8d7bfd45fc56..637a4849e471 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -208,6 +208,8 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_generic_unordered_lookup`` ``201811L``
------------------------------------------------- -----------------
+ ``__cpp_lib_int_pow2`` ``202002L``
+ ------------------------------------------------- -----------------
``__cpp_lib_interpolate`` ``201902L``
------------------------------------------------- -----------------
``__cpp_lib_is_constant_evaluated`` ``201811L``
diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 6079b6fa47be..719115fded67 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -49,3 +49,10 @@ API Changes
in both libc++ and libc++abi, which is technically an ODR violation. Also
note that we couldn't decide to put the operators in libc++ only, because
they are needed from libc++abi (which would create a circular dependency).
+- During the C++20 standardization process some new low-level bit functions
+ have been renamed. Libc++ has renamed these functions to match the C++20
+ Standard.
+ - ``ispow2`` has been renamed to ``has_single_bit``
+ - ``ceil2`` has been renamed to ``bit_ceil``
+ - ``floor2`` has been renamed to ``bit_floor``
+ - ``log2p1`` has been renamed to ``bit_width``
diff --git a/libcxx/include/bit b/libcxx/include/bit
index ae4605b19166..a720b2e6513f 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -17,13 +17,13 @@ namespace std {
// [bit.pow.two], integral powers of 2
template <class T>
- constexpr bool ispow2(T x) noexcept; // C++20
+ constexpr bool has_single_bit(T x) noexcept; // C++20
template <class T>
- constexpr T ceil2(T x); // C++20
+ constexpr T bit_ceil(T x); // C++20
template <class T>
- constexpr T floor2(T x) noexcept; // C++20
+ constexpr T bit_floor(T x) noexcept; // C++20
template <class T>
- constexpr T log2p1(T x) noexcept; // C++20
+ constexpr T bit_width(T x) noexcept; // C++20
// [bit.rotate], rotating
template<class T>
@@ -348,9 +348,9 @@ unsigned __bit_log2(_Tp __t) _NOEXCEPT
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-bool __ispow2(_Tp __t) _NOEXCEPT
+bool __has_single_bit(_Tp __t) _NOEXCEPT
{
- static_assert(__bitop_unsigned_integer<_Tp>::value, "__ispow2 requires unsigned");
+ static_assert(__bitop_unsigned_integer<_Tp>::value, "__has_single_bit requires unsigned");
return __t != 0 && (((__t & (__t - 1)) == 0));
}
@@ -399,7 +399,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
countr_zero(_Tp __t) noexcept
{
- return __countr_zero(__t);
+ return __countr_zero(__t);
}
@@ -424,15 +424,15 @@ popcount(_Tp __t) noexcept
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<__bitop_unsigned_integer<_Tp>::value, bool>
-ispow2(_Tp __t) noexcept
+has_single_bit(_Tp __t) noexcept
{
- return __ispow2(__t);
+ return __has_single_bit(__t);
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-floor2(_Tp __t) noexcept
+bit_floor(_Tp __t) noexcept
{
return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t);
}
@@ -440,11 +440,11 @@ floor2(_Tp __t) noexcept
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-ceil2(_Tp __t) noexcept
+bit_ceil(_Tp __t) noexcept
{
if (__t < 2) return 1;
const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u));
- _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to ceil2");
+ _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
if constexpr (sizeof(_Tp) >= sizeof(unsigned))
return _Tp{1} << __n;
@@ -459,12 +459,11 @@ ceil2(_Tp __t) noexcept
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-log2p1(_Tp __t) noexcept
+bit_width(_Tp __t) noexcept
{
return __t == 0 ? 0 : __bit_log2(__t) + 1;
}
-
enum class endian
{
little = 0xDEAD,
diff --git a/libcxx/include/version b/libcxx/include/version
index 1f05f3a851cc..58f676548fe7 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -66,6 +66,7 @@ __cpp_lib_hardware_interference_size 201703L <new>
__cpp_lib_has_unique_object_representations 201606L <type_traits>
__cpp_lib_hypot 201603L <cmath>
__cpp_lib_incomplete_container_elements 201505L <forward_list> <list> <vector>
+__cpp_lib_int_pow2 202002L <bit>
__cpp_lib_integer_sequence 201304L <utility>
__cpp_lib_integral_constant_callable 201304L <type_traits>
__cpp_lib_interpolate 201902L <numeric>
@@ -261,6 +262,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_endian 201907L
# define __cpp_lib_erase_if 202002L
# define __cpp_lib_generic_unordered_lookup 201811L
+# define __cpp_lib_int_pow2 202002L
# define __cpp_lib_interpolate 201902L
# if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
# define __cpp_lib_is_constant_evaluated 201811L
diff --git a/libcxx/test/libcxx/numerics/bit.ops.pass.cpp b/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
index 084728971e45..3850ba65c7c5 100644
--- a/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
+++ b/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
@@ -32,7 +32,7 @@ int main(int, char **)
static_assert( std::__libcpp_popcount(v) == 7, "");
static_assert( std::__bit_log2(v) == 12, "");
- static_assert(!std::__ispow2(v), "");
+ static_assert(!std::__has_single_bit(v), "");
}
#endif
@@ -49,7 +49,7 @@ int main(int, char **)
ASSERT_SAME_TYPE(int, decltype(std::__libcpp_popcount(v)));
ASSERT_SAME_TYPE(unsigned, decltype(std::__bit_log2(v)));
- ASSERT_SAME_TYPE(bool, decltype(std::__ispow2(v)));
+ ASSERT_SAME_TYPE(bool, decltype(std::__has_single_bit(v)));
assert( std::__rotl(v, 3) == 0x91a2b3c0U);
@@ -62,7 +62,7 @@ int main(int, char **)
assert( std::__libcpp_popcount(v) == 13);
assert( std::__bit_log2(v) == 28);
- assert(!std::__ispow2(v));
+ assert(!std::__has_single_bit(v));
}
return 0;
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp
index 4f99d8d86a72..92a8ada73feb 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp
@@ -16,6 +16,7 @@
/* Constant Value
__cpp_lib_bit_cast 201806L [C++2a]
__cpp_lib_endian 201907L [C++2a]
+ __cpp_lib_int_pow2 202002L [C++2a]
*/
#include <bit>
@@ -31,6 +32,10 @@
# error "__cpp_lib_endian should not be defined before c++2a"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
#elif TEST_STD_VER == 14
# ifdef __cpp_lib_bit_cast
@@ -41,6 +46,10 @@
# error "__cpp_lib_endian should not be defined before c++2a"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
#elif TEST_STD_VER == 17
# ifdef __cpp_lib_bit_cast
@@ -51,6 +60,10 @@
# error "__cpp_lib_endian should not be defined before c++2a"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
#elif TEST_STD_VER > 17
# if !defined(_LIBCPP_VERSION)
@@ -73,6 +86,13 @@
# error "__cpp_lib_endian should have the value 201907L in c++2a"
# endif
+# ifndef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should be defined in c++2a"
+# endif
+# if __cpp_lib_int_pow2 != 202002L
+# error "__cpp_lib_int_pow2 should have the value 202002L in c++2a"
+# endif
+
#endif // TEST_STD_VER > 17
int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
index c625753ca2bd..efb8416924ce 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
@@ -58,6 +58,7 @@
__cpp_lib_has_unique_object_representations 201606L [C++17]
__cpp_lib_hypot 201603L [C++17]
__cpp_lib_incomplete_container_elements 201505L [C++17]
+ __cpp_lib_int_pow2 202002L [C++2a]
__cpp_lib_integer_sequence 201304L [C++14]
__cpp_lib_integral_constant_callable 201304L [C++14]
__cpp_lib_interpolate 201902L [C++2a]
@@ -290,6 +291,10 @@
# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
# ifdef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should not be defined before c++14"
# endif
@@ -684,6 +689,10 @@
# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
# ifndef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should be defined in c++14"
# endif
@@ -1228,6 +1237,10 @@
# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
# endif
+# ifdef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should not be defined before c++2a"
+# endif
+
# ifndef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should be defined in c++17"
# endif
@@ -2039,6 +2052,13 @@
# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++2a"
# endif
+# ifndef __cpp_lib_int_pow2
+# error "__cpp_lib_int_pow2 should be defined in c++2a"
+# endif
+# if __cpp_lib_int_pow2 != 202002L
+# error "__cpp_lib_int_pow2 should have the value 202002L in c++2a"
+# endif
+
# ifndef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should be defined in c++2a"
# endif
diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp
index d1257672f126..ff6f29e8817f 100644
--- a/libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp
+++ b/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp
@@ -9,7 +9,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// template <class T>
-// constexpr T ceil2(T x) noexcept;
+// constexpr T bit_ceil(T x) noexcept;
// Remarks: This function shall not participate in overload resolution unless
// T is an unsigned integer type
@@ -28,7 +28,7 @@ enum class E2 : unsigned char { red };
template <typename T>
constexpr bool toobig()
{
- return 0 == std::ceil2(std::numeric_limits<T>::max());
+ return 0 == std::bit_ceil(std::numeric_limits<T>::max());
}
int main(int, char**)
diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.pass.cpp
index 1959eb05580c..3945c0744919 100644
--- a/libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp
+++ b/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.pass.cpp
@@ -9,9 +9,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// template <class T>
-// constexpr T ceil2(T x) noexcept;
+// constexpr T bit_ceil(T x) noexcept;
-// Returns: The minimal value y such that ispow2(y) is true and y >= x;
+// Returns: The minimal value y such that has_single_bit(y) is true and y >= x;
// if y is not representable as a value of type T, the result is an unspecified value.
// Remarks: This function shall not participate in overload resolution unless
// T is an unsigned integer type
@@ -30,16 +30,16 @@ enum class E2 : unsigned char { red };
template <typename T>
constexpr bool constexpr_test()
{
- return std::ceil2(T(0)) == T(1)
- && std::ceil2(T(1)) == T(1)
- && std::ceil2(T(2)) == T(2)
- && std::ceil2(T(3)) == T(4)
- && std::ceil2(T(4)) == T(4)
- && std::ceil2(T(5)) == T(8)
- && std::ceil2(T(6)) == T(8)
- && std::ceil2(T(7)) == T(8)
- && std::ceil2(T(8)) == T(8)
- && std::ceil2(T(9)) == T(16)
+ return std::bit_ceil(T(0)) == T(1)
+ && std::bit_ceil(T(1)) == T(1)
+ && std::bit_ceil(T(2)) == T(2)
+ && std::bit_ceil(T(3)) == T(4)
+ && std::bit_ceil(T(4)) == T(4)
+ && std::bit_ceil(T(5)) == T(8)
+ && std::bit_ceil(T(6)) == T(8)
+ && std::bit_ceil(T(7)) == T(8)
+ && std::bit_ceil(T(8)) == T(8)
+ && std::bit_ceil(T(9)) == T(16)
;
}
@@ -47,26 +47,26 @@ constexpr bool constexpr_test()
template <typename T>
void runtime_test()
{
- ASSERT_SAME_TYPE(T, decltype(std::ceil2(T(0))));
- LIBCPP_ASSERT_NOEXCEPT( std::ceil2(T(0)));
-
- assert( std::ceil2(T(60)) == T( 64));
- assert( std::ceil2(T(61)) == T( 64));
- assert( std::ceil2(T(62)) == T( 64));
- assert( std::ceil2(T(63)) == T( 64));
- assert( std::ceil2(T(64)) == T( 64));
- assert( std::ceil2(T(65)) == T(128));
- assert( std::ceil2(T(66)) == T(128));
- assert( std::ceil2(T(67)) == T(128));
- assert( std::ceil2(T(68)) == T(128));
- assert( std::ceil2(T(69)) == T(128));
+ ASSERT_SAME_TYPE(T, decltype(std::bit_ceil(T(0))));
+ LIBCPP_ASSERT_NOEXCEPT( std::bit_ceil(T(0)));
+
+ assert( std::bit_ceil(T(60)) == T( 64));
+ assert( std::bit_ceil(T(61)) == T( 64));
+ assert( std::bit_ceil(T(62)) == T( 64));
+ assert( std::bit_ceil(T(63)) == T( 64));
+ assert( std::bit_ceil(T(64)) == T( 64));
+ assert( std::bit_ceil(T(65)) == T(128));
+ assert( std::bit_ceil(T(66)) == T(128));
+ assert( std::bit_ceil(T(67)) == T(128));
+ assert( std::bit_ceil(T(68)) == T(128));
+ assert( std::bit_ceil(T(69)) == T(128));
}
int main(int, char**)
{
{
- auto lambda = [](auto x) -> decltype(std::ceil2(x)) {};
+ auto lambda = [](auto x) -> decltype(std::bit_ceil(x)) {};
using L = decltype(lambda);
static_assert( std::is_invocable_v<L, unsigned char>, "");
diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/bit_floor.pass.cpp
index 83afdf92f066..3b7e245d979a 100644
--- a/libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp
+++ b/libcxx/test/std/numerics/bit/bit.pow.two/bit_floor.pass.cpp
@@ -9,9 +9,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// template <class T>
-// constexpr T floor2(T x) noexcept;
+// constexpr T bit_floor(T x) noexcept;
-// Returns: If x == 0, 0; otherwise the maximal value y such that floor2(y) is true and y <= x.
+// Returns: If x == 0, 0; otherwise the maximal value y such that bit_floor(y) is true and y <= x.
// Remarks: This function shall not participate in overload resolution unless
// T is an unsigned integer type
@@ -29,16 +29,16 @@ enum class E2 : unsigned char { red };
template <typename T>
constexpr bool constexpr_test()
{
- return std::floor2(T(0)) == T(0)
- && std::floor2(T(1)) == T(1)
- && std::floor2(T(2)) == T(2)
- && std::floor2(T(3)) == T(2)
- && std::floor2(T(4)) == T(4)
- && std::floor2(T(5)) == T(4)
- && std::floor2(T(6)) == T(4)
- && std::floor2(T(7)) == T(4)
- && std::floor2(T(8)) == T(8)
- && std::floor2(T(9)) == T(8)
+ return std::bit_floor(T(0)) == T(0)
+ && std::bit_floor(T(1)) == T(1)
+ && std::bit_floor(T(2)) == T(2)
+ && std::bit_floor(T(3)) == T(2)
+ && std::bit_floor(T(4)) == T(4)
+ && std::bit_floor(T(5)) == T(4)
+ && std::bit_floor(T(6)) == T(4)
+ && std::bit_floor(T(7)) == T(4)
+ && std::bit_floor(T(8)) == T(8)
+ && std::bit_floor(T(9)) == T(8)
;
}
@@ -46,26 +46,26 @@ constexpr bool constexpr_test()
template <typename T>
void runtime_test()
{
- ASSERT_SAME_TYPE(T, decltype(std::floor2(T(0))));
- ASSERT_NOEXCEPT( std::floor2(T(0)));
-
- assert( std::floor2(T(121)) == T(64));
- assert( std::floor2(T(122)) == T(64));
- assert( std::floor2(T(123)) == T(64));
- assert( std::floor2(T(124)) == T(64));
- assert( std::floor2(T(125)) == T(64));
- assert( std::floor2(T(126)) == T(64));
- assert( std::floor2(T(127)) == T(64));
- assert( std::floor2(T(128)) == T(128));
- assert( std::floor2(T(129)) == T(128));
- assert( std::floor2(T(130)) == T(128));
+ ASSERT_SAME_TYPE(T, decltype(std::bit_floor(T(0))));
+ ASSERT_NOEXCEPT( std::bit_floor(T(0)));
+
+ assert( std::bit_floor(T(121)) == T(64));
+ assert( std::bit_floor(T(122)) == T(64));
+ assert( std::bit_floor(T(123)) == T(64));
+ assert( std::bit_floor(T(124)) == T(64));
+ assert( std::bit_floor(T(125)) == T(64));
+ assert( std::bit_floor(T(126)) == T(64));
+ assert( std::bit_floor(T(127)) == T(64));
+ assert( std::bit_floor(T(128)) == T(128));
+ assert( std::bit_floor(T(129)) == T(128));
+ assert( std::bit_floor(T(130)) == T(128));
}
int main(int, char**)
{
{
- auto lambda = [](auto x) -> decltype(std::floor2(x)) {};
+ auto lambda = [](auto x) -> decltype(std::bit_floor(x)) {};
using L = decltype(lambda);
static_assert( std::is_invocable_v<L, unsigned char>, "");
@@ -147,17 +147,17 @@ int main(int, char**)
{
__uint128_t val = 128;
val <<= 32;
- assert( std::floor2(val-1) == val/2);
- assert( std::floor2(val) == val);
- assert( std::floor2(val+1) == val);
+ assert( std::bit_floor(val-1) == val/2);
+ assert( std::bit_floor(val) == val);
+ assert( std::bit_floor(val+1) == val);
val <<= 2;
- assert( std::floor2(val-1) == val/2);
- assert( std::floor2(val) == val);
- assert( std::floor2(val+1) == val);
+ assert( std::bit_floor(val-1) == val/2);
+ assert( std::bit_floor(val) == val);
+ assert( std::bit_floor(val+1) == val);
val <<= 3;
- assert( std::floor2(val-1) == val/2);
- assert( std::floor2(val) == val);
- assert( std::floor2(val+1) == val);
+ assert( std::bit_floor(val-1) == val/2);
+ assert( std::bit_floor(val) == val);
+ assert( std::bit_floor(val+1) == val);
}
#endif
diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp
index ffa57196fd6a..71587988abf6 100644
--- a/libcxx/test/std/numerics/bit/bit.pow.two/log2p1.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 log2p1(T x) noexcept;
+// constexpr T bit_width(T x) noexcept;
// If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded.
@@ -29,16 +29,16 @@ enum class E2 : unsigned char { red };
template <typename T>
constexpr bool constexpr_test()
{
- return std::log2p1(T(0)) == T(0)
- && std::log2p1(T(1)) == T(1)
- && std::log2p1(T(2)) == T(2)
- && std::log2p1(T(3)) == T(2)
- && std::log2p1(T(4)) == T(3)
- && std::log2p1(T(5)) == T(3)
- && std::log2p1(T(6)) == T(3)
- && std::log2p1(T(7)) == T(3)
- && std::log2p1(T(8)) == T(4)
- && std::log2p1(T(9)) == T(4)
+ return std::bit_width(T(0)) == T(0)
+ && std::bit_width(T(1)) == T(1)
+ && std::bit_width(T(2)) == T(2)
+ && std::bit_width(T(3)) == T(2)
+ && std::bit_width(T(4)) == T(3)
+ && std::bit_width(T(5)) == T(3)
+ && std::bit_width(T(6)) == T(3)
+ && std::bit_width(T(7)) == T(3)
+ && std::bit_width(T(8)) == T(4)
+ && std::bit_width(T(9)) == T(4)
;
}
@@ -46,38 +46,38 @@ constexpr bool constexpr_test()
template <typename T>
void runtime_test()
{
- ASSERT_SAME_TYPE(T, decltype(std::log2p1(T(0))));
- ASSERT_NOEXCEPT( std::log2p1(T(0)));
-
- assert( std::log2p1(T(0)) == T(0));
- assert( std::log2p1(T(1)) == T(1));
- assert( std::log2p1(T(2)) == T(2));
- assert( std::log2p1(T(3)) == T(2));
- assert( std::log2p1(T(4)) == T(3));
- assert( std::log2p1(T(5)) == T(3));
- assert( std::log2p1(T(6)) == T(3));
- assert( std::log2p1(T(7)) == T(3));
- assert( std::log2p1(T(8)) == T(4));
- assert( std::log2p1(T(9)) == T(4));
-
-
- assert( std::log2p1(T(121)) == T(7));
- assert( std::log2p1(T(122)) == T(7));
- assert( std::log2p1(T(123)) == T(7));
- assert( std::log2p1(T(124)) == T(7));
- assert( std::log2p1(T(125)) == T(7));
- assert( std::log2p1(T(126)) == T(7));
- assert( std::log2p1(T(127)) == T(7));
- assert( std::log2p1(T(128)) == T(8));
- assert( std::log2p1(T(129)) == T(8));
- assert( std::log2p1(T(130)) == T(8));
+ ASSERT_SAME_TYPE(T, decltype(std::bit_width(T(0))));
+ ASSERT_NOEXCEPT( std::bit_width(T(0)));
+
+ 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(121)) == T(7));
+ assert( std::bit_width(T(122)) == T(7));
+ assert( std::bit_width(T(123)) == T(7));
+ assert( std::bit_width(T(124)) == T(7));
+ 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));
}
int main(int, char**)
{
{
- auto lambda = [](auto x) -> decltype(std::log2p1(x)) {};
+ auto lambda = [](auto x) -> decltype(std::bit_width(x)) {};
using L = decltype(lambda);
static_assert( std::is_invocable_v<L, unsigned char>, "");
@@ -160,17 +160,17 @@ int main(int, char**)
{
__uint128_t val = 128;
val <<= 32;
- assert( std::log2p1(val-1) == 39);
- assert( std::log2p1(val) == 40);
- assert( std::log2p1(val+1) == 40);
+ assert( std::bit_width(val-1) == 39);
+ assert( std::bit_width(val) == 40);
+ assert( std::bit_width(val+1) == 40);
val <<= 2;
- assert( std::log2p1(val-1) == 41);
- assert( std::log2p1(val) == 42);
- assert( std::log2p1(val+1) == 42);
+ assert( std::bit_width(val-1) == 41);
+ assert( std::bit_width(val) == 42);
+ assert( std::bit_width(val+1) == 42);
val <<= 3;
- assert( std::log2p1(val-1) == 44);
- assert( std::log2p1(val) == 45);
- assert( std::log2p1(val+1) == 45);
+ assert( std::bit_width(val-1) == 44);
+ assert( std::bit_width(val) == 45);
+ assert( std::bit_width(val+1) == 45);
}
#endif
diff --git a/libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp b/libcxx/test/std/numerics/bit/bit.pow.two/has_single_bit.pass.cpp
index 52e3e5f299ee..8816fc9a1626 100644
--- a/libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp
+++ b/libcxx/test/std/numerics/bit/bit.pow.two/has_single_bit.pass.cpp
@@ -9,7 +9,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// template <class T>
-// constexpr bool ispow2(T x) noexcept;
+// constexpr bool has_single_bit(T x) noexcept;
// Remarks: This function shall not participate in overload resolution unless
// T is an unsigned integer type
@@ -28,15 +28,15 @@ enum class E2 : unsigned char { red };
template <typename T>
constexpr bool constexpr_test()
{
- return std::ispow2(T(1))
- && std::ispow2(T(2))
- && !std::ispow2(T(3))
- && std::ispow2(T(4))
- && !std::ispow2(T(5))
- && !std::ispow2(T(6))
- && !std::ispow2(T(7))
- && std::ispow2(T(8))
- && !std::ispow2(T(9))
+ return std::has_single_bit(T(1))
+ && std::has_single_bit(T(2))
+ && !std::has_single_bit(T(3))
+ && std::has_single_bit(T(4))
+ && !std::has_single_bit(T(5))
+ && !std::has_single_bit(T(6))
+ && !std::has_single_bit(T(7))
+ && std::has_single_bit(T(8))
+ && !std::has_single_bit(T(9))
;
}
@@ -44,26 +44,26 @@ constexpr bool constexpr_test()
template <typename T>
void runtime_test()
{
- ASSERT_SAME_TYPE(bool, decltype(std::ispow2(T(0))));
- ASSERT_NOEXCEPT( std::ispow2(T(0)));
-
- assert(!std::ispow2(T(121)));
- assert(!std::ispow2(T(122)));
- assert(!std::ispow2(T(123)));
- assert(!std::ispow2(T(124)));
- assert(!std::ispow2(T(125)));
- assert(!std::ispow2(T(126)));
- assert(!std::ispow2(T(127)));
- assert( std::ispow2(T(128)));
- assert(!std::ispow2(T(129)));
- assert(!std::ispow2(T(130)));
+ ASSERT_SAME_TYPE(bool, decltype(std::has_single_bit(T(0))));
+ ASSERT_NOEXCEPT( std::has_single_bit(T(0)));
+
+ assert(!std::has_single_bit(T(121)));
+ assert(!std::has_single_bit(T(122)));
+ assert(!std::has_single_bit(T(123)));
+ assert(!std::has_single_bit(T(124)));
+ assert(!std::has_single_bit(T(125)));
+ assert(!std::has_single_bit(T(126)));
+ assert(!std::has_single_bit(T(127)));
+ assert( std::has_single_bit(T(128)));
+ assert(!std::has_single_bit(T(129)));
+ assert(!std::has_single_bit(T(130)));
}
int main(int, char**)
{
{
- auto lambda = [](auto x) -> decltype(std::ispow2(x)) {};
+ auto lambda = [](auto x) -> decltype(std::has_single_bit(x)) {};
using L = decltype(lambda);
static_assert( std::is_invocable_v<L, unsigned char>, "");
@@ -145,17 +145,17 @@ int main(int, char**)
{
__uint128_t val = 128;
val <<= 32;
- assert(!std::ispow2(val-1));
- assert( std::ispow2(val));
- assert(!std::ispow2(val+1));
+ assert(!std::has_single_bit(val-1));
+ assert( std::has_single_bit(val));
+ assert(!std::has_single_bit(val+1));
val <<= 2;
- assert(!std::ispow2(val-1));
- assert( std::ispow2(val));
- assert(!std::ispow2(val+1));
+ assert(!std::has_single_bit(val-1));
+ assert( std::has_single_bit(val));
+ assert(!std::has_single_bit(val+1));
val <<= 3;
- assert(!std::ispow2(val-1));
- assert( std::ispow2(val));
- assert(!std::ispow2(val+1));
+ assert(!std::has_single_bit(val-1));
+ assert( std::has_single_bit(val));
+ assert(!std::has_single_bit(val+1));
}
#endif
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 06eb57d8b3fc..22389f85f4ad 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -411,6 +411,10 @@ feature_test_macros = sorted([ add_version_header(x) for x in [
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
}, {
+ "name": "__cpp_lib_int_pow2",
+ "values": { "c++2a": int(202002) },
+ "headers": ["bit"],
+ }, {
"name": "__cpp_lib_interpolate",
"values": { "c++2a": int(201902) },
"headers": ["numeric"],
diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html
index f90714493f8f..bd112d8573bb 100644
--- a/libcxx/www/cxx2a_status.html
+++ b/libcxx/www/cxx2a_status.html
@@ -235,7 +235,7 @@
<tr><td><a href="https://wg21.link/P1868">P1868</a></td><td>LWG</td><td>width: clarifying units of width and precision in std::format</td><td>Prague</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1908">P1908</a></td><td>CWG</td><td>Reserving Attribute Namespaces for Future Use</td><td>Prague</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1937">P1937</a></td><td>CWG</td><td>Fixing inconsistencies between constexpr and consteval functions</td><td>Prague</td><td><i> </i></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P1956">P1956</a></td><td>LWG</td><td>On the names of low-level bit manipulation functions</td><td>Prague</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1956">P1956</a></td><td>LWG</td><td>On the names of low-level bit manipulation functions</td><td>Prague</td><td>Complete</td><td>12.0</td></tr>
<tr><td><a href="https://wg21.link/P1957">P1957</a></td><td>CWG</td><td>Converting from T* to bool should be considered narrowing (re: US 212)</td><td>Prague</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1963">P1963</a></td><td>LWG</td><td>Fixing US 313</td><td>Prague</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1964">P1964</a></td><td>LWG</td><td>Wording for boolean-testable</td><td>Prague</td><td><i> </i></td><td></td></tr>