[committed] libstdc++ P1956R1 On the names of low-level bit manipulation functions

Message ID 20200217171124.GA1561265@redhat.com
State New
Headers show
Series
  • [committed] libstdc++ P1956R1 On the names of low-level bit manipulation functions
Related show

Commit Message

Jonathan Wakely Feb. 17, 2020, 5:11 p.m.
Implement this change for C++20 that was just approved in Prague.

	P1956R1 On the names of low-level bit manipulation functions
	* include/bits/hashtable_policy.h: Update comment.
	* include/std/bit (__ispow2, __ceil2, __floor2, __log2p1): Rename.
	(ispow2, ceil2, floor2, log2p1): Likewise.
	(__cpp_lib_int_pow2): Add feature test macro.
	* include/std/charconv (__to_chars_len_2): Adjust use of __log2p1.
	* include/std/memory (assume_aligned): Adjust use of ispow2.
	* include/std/version (__cpp_lib_int_pow2): Add.
	* libsupc++/new_opa.cc: Adjust use of __ispow2.
	* src/c++17/memory_resource.cc: Likewise, and for __ceil2 and __log2p1.
	* testsuite/17_intro/freestanding.cc: Adjust use of ispow2.
	* testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Rename to ...
	* testsuite/26_numerics/bit/bit.pow.two/bit_ceil.cc: ... here.
	* testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: Rename to ...
	* testsuite/26_numerics/bit/bit.pow.two/bit_ceil_neg.cc: ... here.
	* testsuite/26_numerics/bit/bit.pow.two/floor2.cc: Rename to ...
	* testsuite/26_numerics/bit/bit.pow.two/bit_floor.cc: ... here.
	* testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: Rename to ...
	* testsuite/26_numerics/bit/bit.pow.two/bit_width.cc: ... here.
	* testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: Rename to ...
	* testsuite/26_numerics/bit/bit.pow.two/has_single_bit.cc: ... here.

Tested powerpc64le-linux, committed to master.
commit 9866abe31ec47f493ff40f525ad970bb60906c4b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 17 16:03:48 2020 +0000

    libstdc++ P1956R1 On the names of low-level bit manipulation functions
    
    Implement this change for C++20 that was just approved in Prague.
    
            P1956R1 On the names of low-level bit manipulation functions
            * include/bits/hashtable_policy.h: Update comment.
            * include/std/bit (__ispow2, __ceil2, __floor2, __log2p1): Rename.
            (ispow2, ceil2, floor2, log2p1): Likewise.
            (__cpp_lib_int_pow2): Add feature test macro.
            * include/std/charconv (__to_chars_len_2): Adjust use of __log2p1.
            * include/std/memory (assume_aligned): Adjust use of ispow2.
            * include/std/version (__cpp_lib_int_pow2): Add.
            * libsupc++/new_opa.cc: Adjust use of __ispow2.
            * src/c++17/memory_resource.cc: Likewise, and for __ceil2 and __log2p1.
            * testsuite/17_intro/freestanding.cc: Adjust use of ispow2.
            * testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Rename to ...
            * testsuite/26_numerics/bit/bit.pow.two/bit_ceil.cc: ... here.
            * testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: Rename to ...
            * testsuite/26_numerics/bit/bit.pow.two/bit_ceil_neg.cc: ... here.
            * testsuite/26_numerics/bit/bit.pow.two/floor2.cc: Rename to ...
            * testsuite/26_numerics/bit/bit.pow.two/bit_floor.cc: ... here.
            * testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: Rename to ...
            * testsuite/26_numerics/bit/bit.pow.two/bit_width.cc: ... here.
            * testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: Rename to ...
            * testsuite/26_numerics/bit/bit.pow.two/has_single_bit.cc: ... here.

Patch

diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 4024e6c37fa..22bc4472e32 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -508,7 +508,7 @@  namespace __detail
   inline std::size_t
   __clp2(std::size_t __n) noexcept
   {
-    // Equivalent to return __n ? std::ceil2(__n) : 0;
+    // Equivalent to return __n ? std::bit_ceil(__n) : 0;
     if (__n < 2)
       return __n;
     const unsigned __lz = sizeof(size_t) > sizeof(long)
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index dc0a77e1a5f..69e955458f3 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -211,12 +211,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp>
     constexpr bool
-    __ispow2(_Tp __x) noexcept
+    __has_single_bit(_Tp __x) noexcept
     { return std::__popcount(__x) == 1; }
 
   template<typename _Tp>
     constexpr _Tp
-    __ceil2(_Tp __x) noexcept
+    __bit_ceil(_Tp __x) noexcept
     {
       using std::__detail::__int_limits;
       constexpr auto _Nd = __int_limits<_Tp>::digits;
@@ -249,7 +249,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp>
     constexpr _Tp
-    __floor2(_Tp __x) noexcept
+    __bit_floor(_Tp __x) noexcept
     {
       constexpr auto _Nd = __detail::__int_limits<_Tp>::digits;
       if (__x == 0)
@@ -259,7 +259,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp>
     constexpr _Tp
-    __log2p1(_Tp __x) noexcept
+    __bit_width(_Tp __x) noexcept
     {
       constexpr auto _Nd = __detail::__int_limits<_Tp>::digits;
       return _Nd - std::__countl_zero(__x);
@@ -325,29 +325,31 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // [bit.pow.two], integral powers of 2
 
+#define __cpp_lib_int_pow2 202002L
+
   /// True if `x` is a power of two, false otherwise.
   template<typename _Tp>
     constexpr _If_is_unsigned_integer<_Tp, bool>
-    ispow2(_Tp __x) noexcept
-    { return std::__ispow2(__x); }
+    has_single_bit(_Tp __x) noexcept
+    { return std::__has_single_bit(__x); }
 
   /// The smallest power-of-two not less than `x`.
   template<typename _Tp>
     constexpr _If_is_unsigned_integer<_Tp>
-    ceil2(_Tp __x) noexcept
-    { return std::__ceil2(__x); }
+    bit_ceil(_Tp __x) noexcept
+    { return std::__bit_ceil(__x); }
 
   /// The largest power-of-two not greater than `x`.
   template<typename _Tp>
     constexpr _If_is_unsigned_integer<_Tp>
-    floor2(_Tp __x) noexcept
-    { return std::__floor2(__x); }
+    bit_floor(_Tp __x) noexcept
+    { return std::__bit_floor(__x); }
 
   /// The smallest integer greater than the base-2 logarithm of `x`.
   template<typename _Tp>
     constexpr _If_is_unsigned_integer<_Tp>
-    log2p1(_Tp __x) noexcept
-    { return std::__log2p1(__x); }
+    bit_width(_Tp __x) noexcept
+    { return std::__bit_width(__x); }
 
 #define __cpp_lib_endian 201907L
 
diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
index ff7dfa12268..35f8efc7e35 100644
--- a/libstdc++-v3/include/std/charconv
+++ b/libstdc++-v3/include/std/charconv
@@ -38,7 +38,7 @@ 
 #if __cplusplus >= 201402L
 
 #include <type_traits>
-#include <bit>			// for __log2p1
+#include <bit>			// for __bit_width
 #include <cctype>		// for isdigit
 #include <bits/charconv.h>	// for __to_chars_len, __to_chars_10_impl
 #include <bits/error_constants.h> // for std::errc
@@ -101,7 +101,7 @@  namespace __detail
   template<typename _Tp>
     constexpr unsigned
     __to_chars_len_2(_Tp __value) noexcept
-    { return std::__log2p1(__value); }
+    { return std::__bit_width(__value); }
 
   // Generic implementation for arbitrary bases.
   template<typename _Tp>
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 823bd21a5ad..14aedb70dac 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -93,7 +93,7 @@ 
 #if __cplusplus >= 201103L
 #include <cstdint>
 #if __cplusplus > 201703L
-# include <bit>			// for ispow2
+# include <bit>			// for has_single_bit
 # include <new>			// for placement operator new
 # include <tuple>		// for tuple, make_tuple, make_from_tuple
 #endif
@@ -191,7 +191,7 @@  get_pointer_safety() noexcept { return pointer_safety::relaxed; }
     [[nodiscard,__gnu__::__always_inline__]]
     constexpr _Tp* assume_aligned(_Tp* __ptr)
     {
-      static_assert(std::ispow2(_Align));
+      static_assert(std::has_single_bit(_Align));
       _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
       return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
     }
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 6db569c2ff2..f9877ef04ca 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -174,6 +174,7 @@ 
 # define __cpp_lib_destroying_delete 201806L
 #endif
 #define __cpp_lib_endian 201907L
+#define __cpp_lib_int_pow2 202002L
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
 # define __cpp_lib_is_constant_evaluated 201811L
 #endif
diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
index 8fac193cc7e..b935936e19a 100644
--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -115,7 +115,7 @@  operator new (std::size_t sz, std::align_val_t al)
 
   /* Alignment must be a power of two.  */
   /* XXX This should be checked by the compiler (PR 86878).  */
-  if (__builtin_expect (!std::__ispow2(align), false))
+  if (__builtin_expect (!std::__has_single_bit(align), false))
     _GLIBCXX_THROW_OR_ABORT(bad_alloc());
 
   /* malloc (0) is unpredictable; avoid it.  */
diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc
index 37386cdddfd..56a87844da0 100644
--- a/libstdc++-v3/src/c++17/memory_resource.cc
+++ b/libstdc++-v3/src/c++17/memory_resource.cc
@@ -25,7 +25,7 @@ 
 #include <memory_resource>
 #include <algorithm>			// lower_bound, rotate
 #include <atomic>
-#include <bit>				// __ceil2, __log2p1
+#include <bit>				// has_single_bit, bit_ceil, bit_width
 #include <new>
 #if ATOMIC_POINTER_LOCK_FREE != 2
 # include <bits/std_mutex.h>	// std::mutex, std::lock_guard
@@ -189,7 +189,7 @@  namespace pmr
     allocate(memory_resource* __r, size_t __size, size_t __align,
 	     _Chunk*& __head)
     {
-      __size = std::__ceil2(__size + sizeof(_Chunk));
+      __size = std::__bit_ceil(__size + sizeof(_Chunk));
 
       if constexpr (alignof(_Chunk) > 1)
 	{
@@ -237,8 +237,8 @@  namespace pmr
 
   private:
     _Chunk(size_t __size, size_t __align, _Chunk* __next) noexcept
-    : _M_size(std::__log2p1(__size) - 1),
-      _M_align(std::__log2p1(__align) - 1)
+    : _M_size(std::__bit_width(__size) - 1),
+      _M_align(std::__bit_width(__align) - 1)
     {
       __builtin_memcpy(_M_next, &__next, sizeof(__next));
       _M_canary = _M_size | _M_align;
@@ -430,7 +430,7 @@  namespace pmr
   private:
     static constexpr unsigned _S_size_digits
       = (numeric_limits<size_type>::digits
-	  + std::__log2p1(bits_per_word) - 1) / 2;
+	  + std::__bit_width(bits_per_word) - 1) / 2;
 
     word* _M_words = nullptr;
     // Number of blocks represented by the bitset:
@@ -553,7 +553,7 @@  namespace pmr
     // Alignment must be a power-of-two so we only need to use enough bits
     // to store the power, not the actual value:
     static constexpr unsigned _S_alignbits
-      = std::__log2p1((unsigned)numeric_limits<size_t>::digits - 1);
+      = std::__bit_width((unsigned)numeric_limits<size_t>::digits - 1);
     // Use the remaining bits to store the size:
     static constexpr unsigned _S_sizebits
       = numeric_limits<size_t>::digits - _S_alignbits;
@@ -564,7 +564,7 @@  namespace pmr
 
     big_block(size_t bytes, size_t alignment)
     : _M_size(alloc_size(bytes) >> _S_alignbits),
-      _M_align_exp(std::__log2p1(alignment) - 1u)
+      _M_align_exp(std::__bit_width(alignment) - 1u)
     { }
 
     void* pointer = nullptr;
@@ -686,7 +686,7 @@  namespace pmr
       const size_t __words = (__blocks + __bits - 1) / __bits;
       const size_t __block_size = block_size();
       size_t __bytes = __blocks * __block_size + __words * sizeof(word);
-      size_t __alignment = std::__ceil2(__block_size);
+      size_t __alignment = std::__bit_ceil(__block_size);
       void* __p = __r->allocate(__bytes, __alignment);
       __try
 	{
@@ -713,7 +713,7 @@  namespace pmr
 
     void release(memory_resource* __r)
     {
-      const size_t __alignment = std::__ceil2(block_size());
+      const size_t __alignment = std::__bit_ceil(block_size());
       for (auto& __c : _M_chunks)
 	if (__c._M_p)
 	  __r->deallocate(__c._M_p, __c._M_bytes, __alignment);
@@ -894,7 +894,7 @@  namespace pmr
     else
       {
 	// Round to preferred granularity
-	static_assert(std::__ispow2(pool_sizes[0]));
+	static_assert(std::__has_single_bit(pool_sizes[0]));
 	constexpr size_t mask = pool_sizes[0] - 1;
 	opts.largest_required_pool_block += mask;
 	opts.largest_required_pool_block &= ~mask;
diff --git a/libstdc++-v3/testsuite/17_intro/freestanding.cc b/libstdc++-v3/testsuite/17_intro/freestanding.cc
index b85851d4232..8dac1810b8c 100644
--- a/libstdc++-v3/testsuite/17_intro/freestanding.cc
+++ b/libstdc++-v3/testsuite/17_intro/freestanding.cc
@@ -52,7 +52,7 @@  int main()
   std::initializer_list<int> ilisti __attribute__((unused));
 
 #if __cplusplus > 201703L
-  static_assert( std::ispow2(256u) );
+  static_assert( std::has_single_bit(256u) );
   static_assert( __cpp_lib_void_t >= 201411L );
 #endif
 
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil.cc
similarity index 66%
rename from libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
rename to libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil.cc
@@ -27,62 +27,62 @@  template<typename T>
 template<typename T>
   constexpr T maxpow2 = T(1) << (std::numeric_limits<T>::digits - 1);
 
-// Detect whether std::ceil2(N) is a constant expression.
+// Detect whether std::bit_ceil(N) is a constant expression.
 template<auto N, typename = void>
-  struct ceil2_valid
+  struct bit_ceil_valid
   : std::false_type { };
 
 template<auto N>
-  struct ceil2_valid<N, std::void_t<char[(std::ceil2(N), 1)]>>
+  struct bit_ceil_valid<N, std::void_t<char[(std::bit_ceil(N), 1)]>>
   : std::true_type { };
 
 template<typename UInt>
 constexpr auto
 test(UInt x)
--> decltype(std::ceil2(x))
+-> decltype(std::bit_ceil(x))
 {
-  static_assert( noexcept(std::ceil2(x)) );
+  static_assert( noexcept(std::bit_ceil(x)) );
 
-  static_assert( std::ceil2(UInt(0)) == 1 );
-  static_assert( std::ceil2(UInt(1)) == 1 );
-  static_assert( std::ceil2(UInt(2)) == 2 );
-  static_assert( std::ceil2(UInt(3)) == 4 );
-  static_assert( std::ceil2(UInt(4)) == 4 );
-  static_assert( std::ceil2(UInt(0x11)) == 0x20 );
-  static_assert( std::ceil2(UInt(0x20)) == 0x20 );
+  static_assert( std::bit_ceil(UInt(0)) == 1 );
+  static_assert( std::bit_ceil(UInt(1)) == 1 );
+  static_assert( std::bit_ceil(UInt(2)) == 2 );
+  static_assert( std::bit_ceil(UInt(3)) == 4 );
+  static_assert( std::bit_ceil(UInt(4)) == 4 );
+  static_assert( std::bit_ceil(UInt(0x11)) == 0x20 );
+  static_assert( std::bit_ceil(UInt(0x20)) == 0x20 );
 
   if constexpr (std::numeric_limits<UInt>::digits > 8)
   {
-    static_assert( std::ceil2(UInt(0x201)) == 0x400 );
-    static_assert( std::ceil2(UInt(0x8ff)) == 0x1000 );
-    static_assert( std::ceil2(UInt(0x1000)) == 0x1000 );
+    static_assert( std::bit_ceil(UInt(0x201)) == 0x400 );
+    static_assert( std::bit_ceil(UInt(0x8ff)) == 0x1000 );
+    static_assert( std::bit_ceil(UInt(0x1000)) == 0x1000 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 32)
   {
-    static_assert( std::ceil2(UInt(0xabcdef)) == 0x1000000 );
-    static_assert( std::ceil2(UInt(0x1000000)) == 0x1000000 );
-    static_assert( std::ceil2(UInt(0x1000001)) == 0x2000000 );
+    static_assert( std::bit_ceil(UInt(0xabcdef)) == 0x1000000 );
+    static_assert( std::bit_ceil(UInt(0x1000000)) == 0x1000000 );
+    static_assert( std::bit_ceil(UInt(0x1000001)) == 0x2000000 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 64)
   {
-    static_assert( std::ceil2(UInt(1) << 64) == (UInt(1) << 64) );
-    static_assert( std::ceil2(UInt(3) << 64) == (UInt(4) << 64) );
+    static_assert( std::bit_ceil(UInt(1) << 64) == (UInt(1) << 64) );
+    static_assert( std::bit_ceil(UInt(3) << 64) == (UInt(4) << 64) );
   }
 
   constexpr UInt msb = maxpow2<UInt>;
-  static_assert( ceil2_valid<msb>() );
-  static_assert( std::ceil2( msb ) == msb );
-  static_assert( std::ceil2( UInt(msb - 1) ) == msb );
-  static_assert( std::ceil2( UInt(msb - 2) ) == msb );
-  static_assert( std::ceil2( UInt(msb - 3) ) == msb );
+  static_assert( bit_ceil_valid<msb>() );
+  static_assert( std::bit_ceil( msb ) == msb );
+  static_assert( std::bit_ceil( UInt(msb - 1) ) == msb );
+  static_assert( std::bit_ceil( UInt(msb - 2) ) == msb );
+  static_assert( std::bit_ceil( UInt(msb - 3) ) == msb );
 
   // P1355R2: not a constant expression if the result is not representable
-  static_assert( !ceil2_valid<UInt(msb + 1)>() );
-  static_assert( !ceil2_valid<max<UInt>>() );
-  static_assert( !ceil2_valid<UInt(max<UInt> - 1)>() );
-  static_assert( !ceil2_valid<UInt(max<UInt> - 2)>() );
+  static_assert( !bit_ceil_valid<UInt(msb + 1)>() );
+  static_assert( !bit_ceil_valid<max<UInt>>() );
+  static_assert( !bit_ceil_valid<UInt(max<UInt> - 1)>() );
+  static_assert( !bit_ceil_valid<UInt(max<UInt> - 2)>() );
 
   return true;
 }
@@ -93,7 +93,7 @@  static_assert( test( (unsigned int)0 ) );
 static_assert( test( (unsigned long)0 ) );
 static_assert( test( (unsigned long long)0 ) );
 
-// std::ceil2(T) shall not participate in overload resolution
+// std::bit_ceil(T) shall not participate in overload resolution
 // unless T is an unsigned integer type.
 struct X { constexpr bool did_not_match() { return true; } };
 constexpr X test(...) { return X{}; }
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil_neg.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil_neg.cc
new file mode 100644
index 00000000000..96cd08a2017
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_ceil_neg.cc
@@ -0,0 +1,75 @@ 
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -D_GLIBCXX_ASSERTIONS" }
+// { dg-do run { target c++2a } }
+// { dg-xfail-run-if "__glibcxx_assert in bit_ceil should fail" { *-*-* } }
+
+#include <bit>
+#include <limits>
+
+// P1355R2: not a constant expression if the result is not representable
+
+template<auto N, typename = void>
+  struct bit_ceil_valid
+  : std::false_type { };
+
+template<auto N>
+  struct bit_ceil_valid<N, std::void_t<char[(std::bit_ceil(N), 1)]>>
+  : std::true_type { };
+
+template<typename T>
+  constexpr T max = std::numeric_limits<T>::max();
+template<typename T>
+  constexpr T maxpow2 = T(1) << (std::numeric_limits<T>::digits - 1);
+
+static_assert( bit_ceil_valid<maxpow2<unsigned char>>() );
+static_assert( !bit_ceil_valid<maxpow2<unsigned char> + (unsigned char)1>() );
+
+static_assert( !bit_ceil_valid<max<unsigned char>>() );
+static_assert( !bit_ceil_valid<max<unsigned char> - (unsigned char)1>() );
+
+static_assert( bit_ceil_valid<maxpow2<unsigned short>>() );
+static_assert( !bit_ceil_valid<maxpow2<unsigned short> + (unsigned short)1>() );
+static_assert( !bit_ceil_valid<max<unsigned short>>() );
+static_assert( !bit_ceil_valid<max<unsigned short> - (unsigned short)1>() );
+
+static_assert( bit_ceil_valid<maxpow2<unsigned int>>() );
+static_assert( !bit_ceil_valid<maxpow2<unsigned int> + 1u>() );
+static_assert( !bit_ceil_valid<max<unsigned int>>() );
+static_assert( !bit_ceil_valid<max<unsigned int> - 1u>() );
+
+static_assert( bit_ceil_valid<maxpow2<unsigned long>>() );
+static_assert( !bit_ceil_valid<maxpow2<unsigned long> + 1ul>() );
+static_assert( !bit_ceil_valid<max<unsigned long>>() );
+static_assert( !bit_ceil_valid<max<unsigned long> - 1ul>() );
+
+static_assert( bit_ceil_valid<maxpow2<unsigned long long>>() );
+static_assert( !bit_ceil_valid<maxpow2<unsigned long long> + 1ull>() );
+static_assert( !bit_ceil_valid<max<unsigned long long>>() );
+static_assert( !bit_ceil_valid<max<unsigned long long> - 1ull>() );
+
+void
+test01()
+{
+  std::bit_ceil( maxpow2<unsigned> + 1u ); // should fail __glibcxx_assert
+}
+
+int main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_floor.cc
similarity index 72%
rename from libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc
rename to libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_floor.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_floor.cc
@@ -24,36 +24,36 @@ 
 template<typename UInt>
 constexpr auto
 test(UInt x)
--> decltype(std::floor2(x))
+-> decltype(std::bit_floor(x))
 {
-  static_assert( noexcept(std::floor2(x)) );
+  static_assert( noexcept(std::bit_floor(x)) );
 
-  static_assert( std::floor2(UInt(0)) == 0 );
-  static_assert( std::floor2(UInt(1)) == 1 );
-  static_assert( std::floor2(UInt(2)) == 2 );
-  static_assert( std::floor2(UInt(3)) == 2 );
-  static_assert( std::floor2(UInt(4)) == 4 );
-  static_assert( std::floor2(UInt(0x11)) == 0x10 );
-  static_assert( std::floor2(UInt(0x20)) == 0x20 );
+  static_assert( std::bit_floor(UInt(0)) == 0 );
+  static_assert( std::bit_floor(UInt(1)) == 1 );
+  static_assert( std::bit_floor(UInt(2)) == 2 );
+  static_assert( std::bit_floor(UInt(3)) == 2 );
+  static_assert( std::bit_floor(UInt(4)) == 4 );
+  static_assert( std::bit_floor(UInt(0x11)) == 0x10 );
+  static_assert( std::bit_floor(UInt(0x20)) == 0x20 );
 
   if constexpr (std::numeric_limits<UInt>::digits > 8)
   {
-    static_assert( std::floor2(UInt(0x201)) == 0x200 );
-    static_assert( std::floor2(UInt(0x8ff)) == 0x800 );
-    static_assert( std::floor2(UInt(0x1000)) == 0x1000 );
+    static_assert( std::bit_floor(UInt(0x201)) == 0x200 );
+    static_assert( std::bit_floor(UInt(0x8ff)) == 0x800 );
+    static_assert( std::bit_floor(UInt(0x1000)) == 0x1000 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 32)
   {
-    static_assert( std::floor2(UInt(0xabcdef)) == 0x800000 );
-    static_assert( std::floor2(UInt(0x1000000)) == 0x1000000 );
-    static_assert( std::floor2(UInt(0x1000001)) == 0x1000000 );
+    static_assert( std::bit_floor(UInt(0xabcdef)) == 0x800000 );
+    static_assert( std::bit_floor(UInt(0x1000000)) == 0x1000000 );
+    static_assert( std::bit_floor(UInt(0x1000001)) == 0x1000000 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 64)
   {
-    static_assert( std::floor2(UInt(1) << 64) == (UInt(1) << 64) );
-    static_assert( std::floor2(UInt(3) << 64) == (UInt(2) << 64) );
+    static_assert( std::bit_floor(UInt(1) << 64) == (UInt(1) << 64) );
+    static_assert( std::bit_floor(UInt(3) << 64) == (UInt(2) << 64) );
   }
 
   return true;
@@ -65,7 +65,7 @@  static_assert( test( (unsigned int)0 ) );
 static_assert( test( (unsigned long)0 ) );
 static_assert( test( (unsigned long long)0 ) );
 
-// std::floor2(T) shall not participate in overload resolution
+// std::bit_floor(T) shall not participate in overload resolution
 // unless T is an unsigned integer type.
 struct X { constexpr bool did_not_match() { return true; } };
 constexpr X test(...) { return X{}; }
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_width.cc
similarity index 73%
rename from libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc
rename to libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_width.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/bit_width.cc
@@ -24,36 +24,36 @@ 
 template<typename UInt>
 constexpr auto
 test(UInt x)
--> decltype(std::log2p1(x))
+-> decltype(std::bit_width(x))
 {
-  static_assert( noexcept(std::log2p1(x)) );
+  static_assert( noexcept(std::bit_width(x)) );
 
-  static_assert( std::log2p1(UInt(0)) == 0 );
-  static_assert( std::log2p1(UInt(1)) == 1 );
-  static_assert( std::log2p1(UInt(2)) == 2 );
-  static_assert( std::log2p1(UInt(3)) == 2 );
-  static_assert( std::log2p1(UInt(4)) == 3 );
-  static_assert( std::log2p1(UInt(0x11)) == 5 );
-  static_assert( std::log2p1(UInt(0x20)) == 6 );
+  static_assert( std::bit_width(UInt(0)) == 0 );
+  static_assert( std::bit_width(UInt(1)) == 1 );
+  static_assert( std::bit_width(UInt(2)) == 2 );
+  static_assert( std::bit_width(UInt(3)) == 2 );
+  static_assert( std::bit_width(UInt(4)) == 3 );
+  static_assert( std::bit_width(UInt(0x11)) == 5 );
+  static_assert( std::bit_width(UInt(0x20)) == 6 );
 
   if constexpr (std::numeric_limits<UInt>::digits > 8)
   {
-    static_assert( std::log2p1(UInt(0x201)) == 10 );
-    static_assert( std::log2p1(UInt(0x8ff)) == 12 );
-    static_assert( std::log2p1(UInt(0x1000)) == 13 );
+    static_assert( std::bit_width(UInt(0x201)) == 10 );
+    static_assert( std::bit_width(UInt(0x8ff)) == 12 );
+    static_assert( std::bit_width(UInt(0x1000)) == 13 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 32)
   {
-    static_assert( std::log2p1(UInt(0xabcdef)) == 24 );
-    static_assert( std::log2p1(UInt(0x1000000)) == 25 );
-    static_assert( std::log2p1(UInt(0x1000001)) == 25 );
+    static_assert( std::bit_width(UInt(0xabcdef)) == 24 );
+    static_assert( std::bit_width(UInt(0x1000000)) == 25 );
+    static_assert( std::bit_width(UInt(0x1000001)) == 25 );
   }
 
   if constexpr (std::numeric_limits<UInt>::digits > 64)
   {
-    static_assert( std::log2p1(UInt(1) << 64) == 65 );
-    static_assert( std::log2p1(UInt(3) << 64) == 66 );
+    static_assert( std::bit_width(UInt(1) << 64) == 65 );
+    static_assert( std::bit_width(UInt(3) << 64) == 66 );
   }
 
   return true;
@@ -65,7 +65,7 @@  static_assert( test( (unsigned int)0 ) );
 static_assert( test( (unsigned long)0 ) );
 static_assert( test( (unsigned long long)0 ) );
 
-// std::log2p1(T) shall not participate in overload resolution
+// std::bit_width(T) shall not participate in overload resolution
 // unless T is an unsigned integer type.
 struct X { constexpr bool did_not_match() { return true; } };
 constexpr X test(...) { return X{}; }
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
deleted file mode 100644
index b5391936e3d..00000000000
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
+++ /dev/null
@@ -1,75 +0,0 @@ 
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-std=gnu++2a -D_GLIBCXX_ASSERTIONS" }
-// { dg-do run { target c++2a } }
-// { dg-xfail-run-if "__glibcxx_assert in ceil2 should fail" { *-*-* } }
-
-#include <bit>
-#include <limits>
-
-// P1355R2: not a constant expression if the result is not representable
-
-template<auto N, typename = void>
-  struct ceil2_valid
-  : std::false_type { };
-
-template<auto N>
-  struct ceil2_valid<N, std::void_t<char[(std::ceil2(N), 1)]>>
-  : std::true_type { };
-
-template<typename T>
-  constexpr T max = std::numeric_limits<T>::max();
-template<typename T>
-  constexpr T maxpow2 = T(1) << (std::numeric_limits<T>::digits - 1);
-
-static_assert( ceil2_valid<maxpow2<unsigned char>>() );
-static_assert( !ceil2_valid<maxpow2<unsigned char> + (unsigned char)1>() );
-
-static_assert( !ceil2_valid<max<unsigned char>>() );
-static_assert( !ceil2_valid<max<unsigned char> - (unsigned char)1>() );
-
-static_assert( ceil2_valid<maxpow2<unsigned short>>() );
-static_assert( !ceil2_valid<maxpow2<unsigned short> + (unsigned short)1>() );
-static_assert( !ceil2_valid<max<unsigned short>>() );
-static_assert( !ceil2_valid<max<unsigned short> - (unsigned short)1>() );
-
-static_assert( ceil2_valid<maxpow2<unsigned int>>() );
-static_assert( !ceil2_valid<maxpow2<unsigned int> + 1u>() );
-static_assert( !ceil2_valid<max<unsigned int>>() );
-static_assert( !ceil2_valid<max<unsigned int> - 1u>() );
-
-static_assert( ceil2_valid<maxpow2<unsigned long>>() );
-static_assert( !ceil2_valid<maxpow2<unsigned long> + 1ul>() );
-static_assert( !ceil2_valid<max<unsigned long>>() );
-static_assert( !ceil2_valid<max<unsigned long> - 1ul>() );
-
-static_assert( ceil2_valid<maxpow2<unsigned long long>>() );
-static_assert( !ceil2_valid<maxpow2<unsigned long long> + 1ull>() );
-static_assert( !ceil2_valid<max<unsigned long long>>() );
-static_assert( !ceil2_valid<max<unsigned long long> - 1ull>() );
-
-void
-test01()
-{
-  std::ceil2( maxpow2<unsigned> + 1u ); // should fail __glibcxx_assert
-}
-
-int main()
-{
-  test01();
-}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/has_single_bit.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/has_single_bit.cc
new file mode 100644
index 00000000000..ac115ef4c5e
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/has_single_bit.cc
@@ -0,0 +1,148 @@ 
+// Copyright (C) 2018-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <bit>
+#include <limits>
+
+template<typename UInt>
+constexpr auto
+test(UInt x)
+-> decltype(std::has_single_bit(x))
+{
+  static_assert( noexcept(std::has_single_bit(x)) );
+
+  static_assert( ! std::has_single_bit( (UInt)0 ) );
+  static_assert( ! std::has_single_bit( (UInt)-1 ) );
+  static_assert( ! std::has_single_bit( (UInt)3 ) );
+  static_assert( ! std::has_single_bit( (UInt)0x0f ) );
+  static_assert( ! std::has_single_bit( (UInt)0xff ) );
+  static_assert( ! std::has_single_bit( (UInt)0x0a ) );
+  static_assert( ! std::has_single_bit( (UInt)0xa0 ) );
+
+  constexpr UInt one = 1;
+  static_assert( std::has_single_bit( (UInt)(one << 0) ) );
+
+  static_assert( std::has_single_bit( (UInt)(one << 1) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 2) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 3) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 4) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 5) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 6) ) );
+  static_assert( std::has_single_bit( (UInt)(one << 7) ) );
+
+  if constexpr (std::numeric_limits<UInt>::digits > 8)
+  {
+    static_assert( std::has_single_bit( (UInt)(one << 8) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 9) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 10) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 11) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 12) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 13) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 14) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 15) ) );
+
+    static_assert( ! std::has_single_bit( (UInt)0xf000 ) );
+    static_assert( ! std::has_single_bit( (UInt)0xff00 ) );
+    static_assert( ! std::has_single_bit( (UInt)0xf0f0 ) );
+    static_assert( ! std::has_single_bit( (UInt)0xf00f ) );
+    static_assert( ! std::has_single_bit( (UInt)0x0f0f ) );
+    static_assert( ! std::has_single_bit( (UInt)0x00ff ) );
+  }
+
+  if constexpr (std::numeric_limits<UInt>::digits > 16)
+  {
+    static_assert( std::has_single_bit( (UInt)(one << 16) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 17) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 16) + 1) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 16) + 0x10) ) );
+  }
+
+  // msp340 target has 20-bit __GLIBCXX_TYPE_INT_N_0 type
+  if constexpr (std::numeric_limits<UInt>::digits > 20)
+  {
+    static_assert( std::has_single_bit( (UInt)(one << 20) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 21) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 24) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 28) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 31) ) );
+  }
+
+  if constexpr (std::numeric_limits<UInt>::digits > 32)
+  {
+    static_assert( std::has_single_bit( (UInt)(one << 32) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 33) ) );
+    static_assert( std::has_single_bit( (UInt)(one << 41) ) );
+
+    static_assert( ! std::has_single_bit( (UInt)((one << 32) + 1) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 32) + (one << 31)) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 33) + 1) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 33) + (one << 32)) ) );
+  }
+
+  if constexpr (std::numeric_limits<UInt>::digits == 64)
+  {
+    static_assert( std::has_single_bit( (UInt)(one << 63) ) );
+
+    static_assert( ! std::has_single_bit( (UInt)((one << 63) + 1) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 63) + (one << 8)) ) );
+    static_assert( ! std::has_single_bit( (UInt)((one << 63) + (one << 32)) ) );
+  }
+  return true;
+}
+
+static_assert( test( (unsigned char)0 ) );
+static_assert( test( (unsigned short)0 ) );
+static_assert( test( (unsigned int)0 ) );
+static_assert( test( (unsigned long)0 ) );
+static_assert( test( (unsigned long long)0 ) );
+
+// std::has_single_bit(T) shall not participate in overload resolution
+// unless T is an unsigned integer type.
+struct X { constexpr bool did_not_match() { return true; } };
+constexpr X test(...) { return X{}; }
+static_assert( test( (bool)0 ).did_not_match() );
+static_assert( test( (char)0 ).did_not_match() );
+static_assert( test( (int)0 ).did_not_match() );
+static_assert( test( (char16_t)0 ).did_not_match() );
+static_assert( test( (float)0 ).did_not_match() );
+static_assert( test( (void*)0 ).did_not_match() );
+static_assert( test( X{} ).did_not_match() );
+enum E : unsigned { e };
+static_assert( test( e ).did_not_match() );
+
+#if !defined(__STRICT_ANSI__) && defined _GLIBCXX_USE_INT128
+static_assert( test( (unsigned __int128)0 ) );
+static_assert( test( (__int128)0 ).did_not_match() );
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_0)0 ) );
+static_assert( test( (__GLIBCXX_TYPE_INT_N_0)0 ).did_not_match() );
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_1)0 ) );
+static_assert( test( (__GLIBCXX_TYPE_INT_N_1)0 ).did_not_match() );
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_2)0 ) );
+static_assert( test( (__GLIBCXX_TYPE_INT_N_2)0 ).did_not_match() );
+#endif
+
+#include <cstddef>
+static_assert( test( (std::byte)0 ).did_not_match() );
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc
deleted file mode 100644
index a0a4d89a54f..00000000000
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc
+++ /dev/null
@@ -1,148 +0,0 @@ 
-// Copyright (C) 2018-2020 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-std=gnu++2a" }
-// { dg-do compile { target c++2a } }
-
-#include <bit>
-#include <limits>
-
-template<typename UInt>
-constexpr auto
-test(UInt x)
--> decltype(std::ispow2(x))
-{
-  static_assert( noexcept(std::ispow2(x)) );
-
-  static_assert( ! std::ispow2( (UInt)0 ) );
-  static_assert( ! std::ispow2( (UInt)-1 ) );
-  static_assert( ! std::ispow2( (UInt)3 ) );
-  static_assert( ! std::ispow2( (UInt)0x0f ) );
-  static_assert( ! std::ispow2( (UInt)0xff ) );
-  static_assert( ! std::ispow2( (UInt)0x0a ) );
-  static_assert( ! std::ispow2( (UInt)0xa0 ) );
-
-  constexpr UInt one = 1;
-  static_assert( std::ispow2( (UInt)(one << 0) ) );
-
-  static_assert( std::ispow2( (UInt)(one << 1) ) );
-  static_assert( std::ispow2( (UInt)(one << 2) ) );
-  static_assert( std::ispow2( (UInt)(one << 3) ) );
-  static_assert( std::ispow2( (UInt)(one << 4) ) );
-  static_assert( std::ispow2( (UInt)(one << 5) ) );
-  static_assert( std::ispow2( (UInt)(one << 6) ) );
-  static_assert( std::ispow2( (UInt)(one << 7) ) );
-
-  if constexpr (std::numeric_limits<UInt>::digits > 8)
-  {
-    static_assert( std::ispow2( (UInt)(one << 8) ) );
-    static_assert( std::ispow2( (UInt)(one << 9) ) );
-    static_assert( std::ispow2( (UInt)(one << 10) ) );
-    static_assert( std::ispow2( (UInt)(one << 11) ) );
-    static_assert( std::ispow2( (UInt)(one << 12) ) );
-    static_assert( std::ispow2( (UInt)(one << 13) ) );
-    static_assert( std::ispow2( (UInt)(one << 14) ) );
-    static_assert( std::ispow2( (UInt)(one << 15) ) );
-
-    static_assert( ! std::ispow2( (UInt)0xf000 ) );
-    static_assert( ! std::ispow2( (UInt)0xff00 ) );
-    static_assert( ! std::ispow2( (UInt)0xf0f0 ) );
-    static_assert( ! std::ispow2( (UInt)0xf00f ) );
-    static_assert( ! std::ispow2( (UInt)0x0f0f ) );
-    static_assert( ! std::ispow2( (UInt)0x00ff ) );
-  }
-
-  if constexpr (std::numeric_limits<UInt>::digits > 16)
-  {
-    static_assert( std::ispow2( (UInt)(one << 16) ) );
-    static_assert( std::ispow2( (UInt)(one << 17) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 16) + 1) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 16) + 0x10) ) );
-  }
-
-  // msp340 target has 20-bit __GLIBCXX_TYPE_INT_N_0 type
-  if constexpr (std::numeric_limits<UInt>::digits > 20)
-  {
-    static_assert( std::ispow2( (UInt)(one << 20) ) );
-    static_assert( std::ispow2( (UInt)(one << 21) ) );
-    static_assert( std::ispow2( (UInt)(one << 24) ) );
-    static_assert( std::ispow2( (UInt)(one << 28) ) );
-    static_assert( std::ispow2( (UInt)(one << 31) ) );
-  }
-
-  if constexpr (std::numeric_limits<UInt>::digits > 32)
-  {
-    static_assert( std::ispow2( (UInt)(one << 32) ) );
-    static_assert( std::ispow2( (UInt)(one << 33) ) );
-    static_assert( std::ispow2( (UInt)(one << 41) ) );
-
-    static_assert( ! std::ispow2( (UInt)((one << 32) + 1) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 32) + (one << 31)) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 33) + 1) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 33) + (one << 32)) ) );
-  }
-
-  if constexpr (std::numeric_limits<UInt>::digits == 64)
-  {
-    static_assert( std::ispow2( (UInt)(one << 63) ) );
-
-    static_assert( ! std::ispow2( (UInt)((one << 63) + 1) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 63) + (one << 8)) ) );
-    static_assert( ! std::ispow2( (UInt)((one << 63) + (one << 32)) ) );
-  }
-  return true;
-}
-
-static_assert( test( (unsigned char)0 ) );
-static_assert( test( (unsigned short)0 ) );
-static_assert( test( (unsigned int)0 ) );
-static_assert( test( (unsigned long)0 ) );
-static_assert( test( (unsigned long long)0 ) );
-
-// std::ispow2(T) shall not participate in overload resolution
-// unless T is an unsigned integer type.
-struct X { constexpr bool did_not_match() { return true; } };
-constexpr X test(...) { return X{}; }
-static_assert( test( (bool)0 ).did_not_match() );
-static_assert( test( (char)0 ).did_not_match() );
-static_assert( test( (int)0 ).did_not_match() );
-static_assert( test( (char16_t)0 ).did_not_match() );
-static_assert( test( (float)0 ).did_not_match() );
-static_assert( test( (void*)0 ).did_not_match() );
-static_assert( test( X{} ).did_not_match() );
-enum E : unsigned { e };
-static_assert( test( e ).did_not_match() );
-
-#if !defined(__STRICT_ANSI__) && defined _GLIBCXX_USE_INT128
-static_assert( test( (unsigned __int128)0 ) );
-static_assert( test( (__int128)0 ).did_not_match() );
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_0)
-static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_0)0 ) );
-static_assert( test( (__GLIBCXX_TYPE_INT_N_0)0 ).did_not_match() );
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_1)
-static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_1)0 ) );
-static_assert( test( (__GLIBCXX_TYPE_INT_N_1)0 ).did_not_match() );
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_2)
-static_assert( test( (unsigned __GLIBCXX_TYPE_INT_N_2)0 ) );
-static_assert( test( (__GLIBCXX_TYPE_INT_N_2)0 ).did_not_match() );
-#endif
-
-#include <cstddef>
-static_assert( test( (std::byte)0 ).did_not_match() );