//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 // UNSUPPORTED: libcpp-no-concepts // template // concept integral = // see below // template // concept signed_integral = // see below // template // concept unsigned_integral = // see below // template // concept floating_point = // see below #include #include namespace { template constexpr bool CheckIntegralQualifiers() { constexpr bool result = std::integral; static_assert(std::integral == result); static_assert(std::integral == result); static_assert(std::integral == result); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); static_assert(!std::integral); return result; } enum ClassicEnum { a, b, c }; enum class ScopedEnum { x, y, z }; struct EmptyStruct {}; constexpr void CheckIntegral() { // standard signed and unsigned integers static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); // extended integers #ifndef _LIBCPP_HAS_NO_INT128 static_assert(CheckIntegralQualifiers<__int128_t>()); static_assert(CheckIntegralQualifiers<__uint128_t>()); #endif // bool and char types are also integral static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); static_assert(CheckIntegralQualifiers()); // types that aren't integral static_assert(!std::integral); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); static_assert(!CheckIntegralQualifiers()); } template constexpr bool CheckSignedIntegralQualifiers() { constexpr bool result = std::signed_integral; static_assert(std::signed_integral == result); static_assert(std::signed_integral == result); static_assert(std::signed_integral == result); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); static_assert(!std::signed_integral); return result; } constexpr void CheckSignedIntegral() { // standard signed integers static_assert(CheckSignedIntegralQualifiers()); static_assert(CheckSignedIntegralQualifiers()); static_assert(CheckSignedIntegralQualifiers()); static_assert(CheckSignedIntegralQualifiers()); static_assert(CheckSignedIntegralQualifiers()); // bool and character *may* be signed static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); // integers that aren't signed integrals static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); // extended integers #ifndef _LIBCPP_HAS_NO_INT128 static_assert(CheckSignedIntegralQualifiers<__int128_t>()); static_assert(!CheckSignedIntegralQualifiers<__uint128_t>()); #endif // types that aren't even integers shouldn't be signed integers! static_assert(!std::signed_integral); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); static_assert(!CheckSignedIntegralQualifiers()); } template constexpr bool CheckUnsignedIntegralQualifiers() { constexpr bool result = std::unsigned_integral; static_assert(std::unsigned_integral == result); static_assert(std::unsigned_integral == result); static_assert(std::unsigned_integral == result); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); return result; } constexpr void CheckUnsignedIntegral() { // standard unsigned types static_assert(CheckUnsignedIntegralQualifiers()); static_assert(CheckUnsignedIntegralQualifiers()); static_assert(CheckUnsignedIntegralQualifiers()); static_assert(CheckUnsignedIntegralQualifiers()); static_assert(CheckUnsignedIntegralQualifiers()); // Whether bool and character types are signed or unsigned is impl-defined static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); // extended integers #ifndef _LIBCPP_HAS_NO_INT128 static_assert(CheckUnsignedIntegralQualifiers<__uint128_t>()); static_assert(!CheckUnsignedIntegralQualifiers<__int128_t>()); #endif // integer types that aren't unsigned integrals static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!std::unsigned_integral); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(!CheckUnsignedIntegralQualifiers()); } // This overload should never be called. It exists solely to force subsumption. template [[nodiscard]] constexpr bool CheckSubsumption(I) { return false; } // clang-format off template requires std::signed_integral && (!std::unsigned_integral) [[nodiscard]] constexpr bool CheckSubsumption(I) { return std::is_signed_v; } template requires std::unsigned_integral && (!std::signed_integral) [[nodiscard]] constexpr bool CheckSubsumption(I) { return std::is_unsigned_v; } // clang-format on template constexpr bool CheckFloatingPointQualifiers() { constexpr bool result = std::floating_point; static_assert(std::floating_point == result); static_assert(std::floating_point == result); static_assert(std::floating_point == result); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); static_assert(!std::floating_point); return result; } constexpr void CheckFloatingPoint() { // floating-point types static_assert(CheckFloatingPointQualifiers()); static_assert(CheckFloatingPointQualifiers()); static_assert(CheckFloatingPointQualifiers()); // types that aren't floating-point static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!std::floating_point); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); } } // namespace int main(int, char**) { CheckIntegral(); CheckSignedIntegral(); CheckUnsignedIntegral(); static_assert(CheckSubsumption(0)); static_assert(CheckSubsumption(0U)); CheckFloatingPoint(); return 0; }