blob: b8add04876267867dc3bd14ae2e6b4251f786a6f [file] [log] [blame]
// Copyright (C) 2019-2021 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();
}