From patchwork Mon Feb 17 17:11:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1239375 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-519664-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=mhE5QlyL; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=HhcDRC8S; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48LrBG1JKmz9sRJ for ; Tue, 18 Feb 2020 04:11:47 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=cSbW4tOTpva+CEXqGBeYurRYpgpRz0mrUbpMeX1qUzG/elZebBDUC ZGA0fQVtEA0VVlwfDMn9i5fUN+gAo+Wo4e5d/SvpgT5mHDUIWSoOS+528aQZfOvJ J23S5Ojd1LI6QPsvW82w0nyRUlK37ax4c+q+tLZ1REOBXX3X2Yd140= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=y7Be2tdr3RpQMOwUKWpELDUJK74=; b=mhE5QlyLphIfiJtITX2V J/STEQVTTvBYSZnHeAlJFOU7h8rOOpJERW0Imjr2Sym6W+t7HcWRpJ4jNrpKHx69 xW2nwYPx4J8W2co5XZJoFINL3Yd23+mRyt57dSNzO5VN4DIVlOIh46ThQHkWHiZ0 iQPvKF8MJl2l+2MmbzblC98= Received: (qmail 49100 invoked by alias); 17 Feb 2020 17:11:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 49086 invoked by uid 89); 17 Feb 2020 17:11:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy= X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-2.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (205.139.110.61) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 17 Feb 2020 17:11:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581959490; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=ecHS6/vUOwgwyHSEqX6X/IhZDfEMhCfeLb3zhKJHe5E=; b=HhcDRC8SNBWnLhSjLvhlNjsgxeOJ++sl65MSbK3CngNY9PGYttntbxPxy7wTN0e2G+h0nF qAvjTHS98CzhYIwdb27vu966qqQCD5hOlKnuMLngM0zZa/+xfqEjBxhqv3C1grgZdneDIq bxQl71iYqlXbmYFNsH25MC1jwbTlMr8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-216-5g7w1FxfMMWly5TclbHh5A-1; Mon, 17 Feb 2020 12:11:27 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8462497903; Mon, 17 Feb 2020 17:11:26 +0000 (UTC) Received: from localhost (unknown [10.33.36.167]) by smtp.corp.redhat.com (Postfix) with ESMTP id BF8991001B28; Mon, 17 Feb 2020 17:11:25 +0000 (UTC) Date: Mon, 17 Feb 2020 17:11:24 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++ P1956R1 On the names of low-level bit manipulation functions Message-ID: <20200217171124.GA1561265@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline 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 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. 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 constexpr bool - __ispow2(_Tp __x) noexcept + __has_single_bit(_Tp __x) noexcept { return std::__popcount(__x) == 1; } template 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 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 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 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 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 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 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 -#include // for __log2p1 +#include // for __bit_width #include // for isdigit #include // for __to_chars_len, __to_chars_10_impl #include // for std::errc @@ -101,7 +101,7 @@ namespace __detail template constexpr unsigned __to_chars_len_2(_Tp __value) noexcept - { return std::__log2p1(__value); } + { return std::__bit_width(__value); } // Generic implementation for arbitrary bases. template 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 #if __cplusplus > 201703L -# include // for ispow2 +# include // for has_single_bit # include // for placement operator new # include // 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 #include // lower_bound, rotate #include -#include // __ceil2, __log2p1 +#include // has_single_bit, bit_ceil, bit_width #include #if ATOMIC_POINTER_LOCK_FREE != 2 # include // 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::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::digits - 1); + = std::__bit_width((unsigned)numeric_limits::digits - 1); // Use the remaining bits to store the size: static constexpr unsigned _S_sizebits = numeric_limits::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 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 template constexpr T maxpow2 = T(1) << (std::numeric_limits::digits - 1); -// Detect whether std::ceil2(N) is a constant expression. +// Detect whether std::bit_ceil(N) is a constant expression. template - struct ceil2_valid + struct bit_ceil_valid : std::false_type { }; template - struct ceil2_valid> + struct bit_ceil_valid> : std::true_type { }; template 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::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::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::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; - static_assert( ceil2_valid() ); - 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() ); + 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() ); - static_assert( !ceil2_valid>() ); - static_assert( !ceil2_valid - 1)>() ); - static_assert( !ceil2_valid - 2)>() ); + static_assert( !bit_ceil_valid() ); + static_assert( !bit_ceil_valid>() ); + static_assert( !bit_ceil_valid - 1)>() ); + static_assert( !bit_ceil_valid - 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 +// . + +// { 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 +#include + +// P1355R2: not a constant expression if the result is not representable + +template + struct bit_ceil_valid + : std::false_type { }; + +template + struct bit_ceil_valid> + : std::true_type { }; + +template + constexpr T max = std::numeric_limits::max(); +template + constexpr T maxpow2 = T(1) << (std::numeric_limits::digits - 1); + +static_assert( bit_ceil_valid>() ); +static_assert( !bit_ceil_valid + (unsigned char)1>() ); + +static_assert( !bit_ceil_valid>() ); +static_assert( !bit_ceil_valid - (unsigned char)1>() ); + +static_assert( bit_ceil_valid>() ); +static_assert( !bit_ceil_valid + (unsigned short)1>() ); +static_assert( !bit_ceil_valid>() ); +static_assert( !bit_ceil_valid - (unsigned short)1>() ); + +static_assert( bit_ceil_valid>() ); +static_assert( !bit_ceil_valid + 1u>() ); +static_assert( !bit_ceil_valid>() ); +static_assert( !bit_ceil_valid - 1u>() ); + +static_assert( bit_ceil_valid>() ); +static_assert( !bit_ceil_valid + 1ul>() ); +static_assert( !bit_ceil_valid>() ); +static_assert( !bit_ceil_valid - 1ul>() ); + +static_assert( bit_ceil_valid>() ); +static_assert( !bit_ceil_valid + 1ull>() ); +static_assert( !bit_ceil_valid>() ); +static_assert( !bit_ceil_valid - 1ull>() ); + +void +test01() +{ + std::bit_ceil( maxpow2 + 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 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::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::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::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 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::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::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::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 -// . - -// { 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 -#include - -// P1355R2: not a constant expression if the result is not representable - -template - struct ceil2_valid - : std::false_type { }; - -template - struct ceil2_valid> - : std::true_type { }; - -template - constexpr T max = std::numeric_limits::max(); -template - constexpr T maxpow2 = T(1) << (std::numeric_limits::digits - 1); - -static_assert( ceil2_valid>() ); -static_assert( !ceil2_valid + (unsigned char)1>() ); - -static_assert( !ceil2_valid>() ); -static_assert( !ceil2_valid - (unsigned char)1>() ); - -static_assert( ceil2_valid>() ); -static_assert( !ceil2_valid + (unsigned short)1>() ); -static_assert( !ceil2_valid>() ); -static_assert( !ceil2_valid - (unsigned short)1>() ); - -static_assert( ceil2_valid>() ); -static_assert( !ceil2_valid + 1u>() ); -static_assert( !ceil2_valid>() ); -static_assert( !ceil2_valid - 1u>() ); - -static_assert( ceil2_valid>() ); -static_assert( !ceil2_valid + 1ul>() ); -static_assert( !ceil2_valid>() ); -static_assert( !ceil2_valid - 1ul>() ); - -static_assert( ceil2_valid>() ); -static_assert( !ceil2_valid + 1ull>() ); -static_assert( !ceil2_valid>() ); -static_assert( !ceil2_valid - 1ull>() ); - -void -test01() -{ - std::ceil2( maxpow2 + 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include +#include + +template +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::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::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::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::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::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 +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 -// . - -// { dg-options "-std=gnu++2a" } -// { dg-do compile { target c++2a } } - -#include -#include - -template -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::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::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::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::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::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 -static_assert( test( (std::byte)0 ).did_not_match() );