//===----------------------------------------------------------------------===// // // 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++03, c++11, c++14, c++17 // template // concept convertible_to; #include #include namespace { enum ClassicEnum { a, b }; enum class ScopedEnum { x, y }; struct Empty {}; using nullptr_t = decltype(nullptr); template void CheckConvertibleTo() { static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); } template void CheckNotConvertibleTo() { static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); } template void CheckIsConvertibleButNotConvertibleTo() { // Sanity check T is either implicitly xor explicitly convertible to U. static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); CheckNotConvertibleTo(); } // Tests that should objectively return false (except for bool and nullptr_t) template constexpr void CommonlyNotConvertibleTo() { CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); } template > constexpr void CommonlyNotConvertibleTo() { CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); } template > constexpr void CommonlyNotConvertibleTo() { CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); } } // namespace using Function = void(); using NoexceptFunction = void() noexcept; using ConstFunction = void() const; using Array = char[1]; struct StringType { StringType(const char*) {} }; class NonCopyable { NonCopyable(NonCopyable&); }; template class CannotInstantiate { enum { X = T::ThisExpressionWillBlowUp }; }; struct abstract { virtual int f() = 0; }; struct ExplicitlyConvertible; struct ImplicitlyConvertible; struct ExplicitlyConstructible { explicit ExplicitlyConstructible(int); explicit ExplicitlyConstructible(ExplicitlyConvertible); explicit ExplicitlyConstructible(ImplicitlyConvertible) = delete; }; struct ExplicitlyConvertible { explicit operator ExplicitlyConstructible() const { return ExplicitlyConstructible(0); } }; struct ImplicitlyConstructible; struct ImplicitlyConvertible { operator ExplicitlyConstructible() const; operator ImplicitlyConstructible() const = delete; }; struct ImplicitlyConstructible { ImplicitlyConstructible(ImplicitlyConvertible); }; int main(int, char**) { // void CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // Function CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); static_assert(std::convertible_to); static_assert(!std::convertible_to); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // Function& CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // Function* CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // Non-referencable function type static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); // NoexceptFunction CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // NoexceptFunction& CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // NoexceptFunction* CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); CheckConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); // Array CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); CheckNotConvertibleTo(); CheckNotConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(!std::convertible_to); // Array& CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); CheckNotConvertibleTo(); CheckNotConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); // char CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); static_assert(!std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); CheckNotConvertibleTo(); // char& CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); CheckNotConvertibleTo(); // char* CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); static_assert(std::convertible_to); // NonCopyable static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert(std::convertible_to); static_assert( std::convertible_to); static_assert( std::convertible_to); static_assert(std::convertible_to); static_assert(!std::convertible_to); // This test requires Access control SFINAE which we only have in C++11 or when // we are using the compiler builtin for convertible_to. CheckNotConvertibleTo(); // Ensure that CannotInstantiate is not instantiated by convertible_to when it is not needed. // For example CannotInstantiate is instantiated as a part of ADL lookup for arguments of type CannotInstantiate*. static_assert( std::convertible_to*, CannotInstantiate*>); // Test for PR13592 static_assert(!std::convertible_to); CommonlyNotConvertibleTo(); CommonlyNotConvertibleTo(); CommonlyNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckNotConvertibleTo(); CheckIsConvertibleButNotConvertibleTo(); CheckNotConvertibleTo(); return 0; }