Home | History | Annotate | Download | only in meta.unary.prop
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // type_traits
     11 // XFAIL: apple-clang-6.0
     12 //	The Apple-6 compiler gets is_constructible<void ()> wrong.
     13 
     14 // template <class T, class... Args>
     15 //   struct is_constructible;
     16 
     17 // MODULES_DEFINES: _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
     18 #define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
     19 #include <type_traits>
     20 #include "test_macros.h"
     21 
     22 #if TEST_STD_VER >= 11 && defined(_LIBCPP_VERSION)
     23 #define LIBCPP11_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
     24 #else
     25 #define LIBCPP11_STATIC_ASSERT(...) ((void)0)
     26 #endif
     27 
     28 
     29 struct A
     30 {
     31     explicit A(int);
     32     A(int, double);
     33 #if TEST_STD_VER >= 11
     34 private:
     35 #endif
     36     A(char);
     37 };
     38 
     39 struct Base {};
     40 struct Derived : public Base {};
     41 
     42 class Abstract
     43 {
     44     virtual void foo() = 0;
     45 };
     46 
     47 class AbstractDestructor
     48 {
     49     virtual ~AbstractDestructor() = 0;
     50 };
     51 
     52 struct PrivateDtor {
     53   PrivateDtor(int) {}
     54 private:
     55   ~PrivateDtor() {}
     56 };
     57 
     58 struct S {
     59    template <class T>
     60 #if TEST_STD_VER >= 11
     61    explicit
     62 #endif
     63    operator T () const;
     64 };
     65 
     66 template <class To>
     67 struct ImplicitTo {
     68   operator To();
     69 };
     70 
     71 #if TEST_STD_VER >= 11
     72 template <class To>
     73 struct ExplicitTo {
     74    explicit operator To ();
     75 };
     76 #endif
     77 
     78 
     79 template <class T>
     80 void test_is_constructible()
     81 {
     82     static_assert( (std::is_constructible<T>::value), "");
     83     LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T>::type::value), "");
     84 #if TEST_STD_VER > 14
     85     static_assert( std::is_constructible_v<T>, "");
     86 #endif
     87 }
     88 
     89 template <class T, class A0>
     90 void test_is_constructible()
     91 {
     92     static_assert(( std::is_constructible<T, A0>::value), "");
     93     LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0>::type::value), "");
     94 #if TEST_STD_VER > 14
     95     static_assert(( std::is_constructible_v<T, A0>), "");
     96 #endif
     97 }
     98 
     99 template <class T, class A0, class A1>
    100 void test_is_constructible()
    101 {
    102     static_assert(( std::is_constructible<T, A0, A1>::value), "");
    103     LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0, A1>::type::value), "");
    104 #if TEST_STD_VER > 14
    105     static_assert(( std::is_constructible_v<T, A0, A1>), "");
    106 #endif
    107 }
    108 
    109 template <class T>
    110 void test_is_not_constructible()
    111 {
    112     static_assert((!std::is_constructible<T>::value), "");
    113     LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T>::type::value), "");
    114 #if TEST_STD_VER > 14
    115     static_assert((!std::is_constructible_v<T>), "");
    116 #endif
    117 }
    118 
    119 template <class T, class A0>
    120 void test_is_not_constructible()
    121 {
    122     static_assert((!std::is_constructible<T, A0>::value), "");
    123     LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T, A0>::type::value), "");
    124 #if TEST_STD_VER > 14
    125     static_assert((!std::is_constructible_v<T, A0>), "");
    126 #endif
    127 }
    128 
    129 #if TEST_STD_VER >= 11
    130 template <class T = int, class = decltype(static_cast<T&&>(std::declval<double&>()))>
    131 constexpr bool  clang_disallows_valid_static_cast_test(int) { return false; };
    132 
    133 constexpr bool clang_disallows_valid_static_cast_test(long) { return true; }
    134 
    135 static constexpr bool clang_disallows_valid_static_cast_bug =
    136     clang_disallows_valid_static_cast_test(0);
    137 #endif
    138 
    139 
    140 int main()
    141 {
    142     typedef Base B;
    143     typedef Derived D;
    144 
    145     test_is_constructible<int> ();
    146     test_is_constructible<int, const int> ();
    147     test_is_constructible<A, int> ();
    148     test_is_constructible<A, int, double> ();
    149     test_is_constructible<int&, int&> ();
    150 
    151     test_is_not_constructible<A> ();
    152 #if TEST_STD_VER >= 11
    153     test_is_not_constructible<A, char> ();
    154 #else
    155     test_is_constructible<A, char> ();
    156 #endif
    157     test_is_not_constructible<A, void> ();
    158     test_is_not_constructible<int, void()>();
    159     test_is_not_constructible<int, void(&)()>();
    160     test_is_not_constructible<int, void() const>();
    161     test_is_not_constructible<int&, void>();
    162     test_is_not_constructible<int&, void()>();
    163     test_is_not_constructible<int&, void() const>();
    164     test_is_not_constructible<int&, void(&)()>();
    165 
    166     test_is_not_constructible<void> ();
    167     test_is_not_constructible<const void> ();  // LWG 2738
    168     test_is_not_constructible<volatile void> ();
    169     test_is_not_constructible<const volatile void> ();
    170     test_is_not_constructible<int&> ();
    171     test_is_not_constructible<Abstract> ();
    172     test_is_not_constructible<AbstractDestructor> ();
    173     test_is_constructible<int, S>();
    174     test_is_not_constructible<int&, S>();
    175 
    176     test_is_constructible<void(&)(), void(&)()>();
    177     test_is_constructible<void(&)(), void()>();
    178 #if TEST_STD_VER >= 11
    179     test_is_constructible<void(&&)(), void(&&)()>();
    180     test_is_constructible<void(&&)(), void()>();
    181     test_is_constructible<void(&&)(), void(&)()>();
    182 #endif
    183 
    184 #if TEST_STD_VER >= 11
    185     test_is_constructible<int const&, int>();
    186     test_is_constructible<int const&, int&&>();
    187 
    188     test_is_constructible<int&&, double&>();
    189     test_is_constructible<void(&)(), void(&&)()>();
    190 
    191     test_is_not_constructible<int&, int>();
    192     test_is_not_constructible<int&, int const&>();
    193     test_is_not_constructible<int&, int&&>();
    194 
    195     test_is_constructible<int&&, int>();
    196     test_is_constructible<int&&, int&&>();
    197     test_is_not_constructible<int&&, int&>();
    198     test_is_not_constructible<int&&, int const&&>();
    199 
    200     test_is_constructible<Base, Derived>();
    201     test_is_constructible<Base&, Derived&>();
    202     test_is_not_constructible<Derived&, Base&>();
    203     test_is_constructible<Base const&, Derived const&>();
    204     test_is_not_constructible<Derived const&, Base const&>();
    205     test_is_not_constructible<Derived const&, Base>();
    206 
    207     test_is_constructible<Base&&, Derived>();
    208     test_is_constructible<Base&&, Derived&&>();
    209     test_is_not_constructible<Derived&&, Base&&>();
    210     test_is_not_constructible<Derived&&, Base>();
    211 
    212     // test that T must also be destructible
    213     test_is_constructible<PrivateDtor&, PrivateDtor&>();
    214     test_is_not_constructible<PrivateDtor, int>();
    215 
    216     test_is_not_constructible<void() const, void() const>();
    217     test_is_not_constructible<void() const, void*>();
    218 
    219     test_is_constructible<int&, ImplicitTo<int&>>();
    220     test_is_constructible<const int&, ImplicitTo<int&&>>();
    221     test_is_constructible<int&&, ImplicitTo<int&&>>();
    222     test_is_constructible<const int&, ImplicitTo<int>>();
    223 
    224     test_is_not_constructible<B&&, B&>();
    225     test_is_not_constructible<B&&, D&>();
    226     test_is_constructible<B&&, ImplicitTo<D&&>>();
    227     test_is_constructible<B&&, ImplicitTo<D&&>&>();
    228     test_is_constructible<int&&, double&>();
    229     test_is_constructible<const int&, ImplicitTo<int&>&>();
    230     test_is_constructible<const int&, ImplicitTo<int&>>();
    231     test_is_constructible<const int&, ExplicitTo<int&>&>();
    232     test_is_constructible<const int&, ExplicitTo<int&>>();
    233 
    234     test_is_constructible<const int&, ExplicitTo<int&>&>();
    235     test_is_constructible<const int&, ExplicitTo<int&>>();
    236     test_is_constructible<int&, ExplicitTo<int&>>();
    237     test_is_constructible<const int&, ExplicitTo<int&&>>();
    238 
    239     // Binding through reference-compatible type is required to perform
    240     // direct-initialization as described in [over.match.ref] p. 1 b. 1:
    241     test_is_constructible<int&, ExplicitTo<int&>>();
    242     test_is_constructible<const int&, ExplicitTo<int&&>>();
    243 
    244     static_assert(std::is_constructible<int&&, ExplicitTo<int&&>>::value, "");
    245 #ifdef __clang__
    246 #if defined(CLANG_TEST_VER) && CLANG_TEST_VER < 400
    247     static_assert(clang_disallows_valid_static_cast_bug, "bug still exists");
    248 #endif
    249     // FIXME Clang disallows this construction because it thinks that
    250     // 'static_cast<int&&>(declval<ExplicitTo<int&&>>())' is ill-formed.
    251     LIBCPP_STATIC_ASSERT(
    252         clang_disallows_valid_static_cast_bug !=
    253         std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
    254 #else
    255     static_assert(clang_disallows_valid_static_cast_bug == false, "");
    256     LIBCPP_STATIC_ASSERT(std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
    257 #endif
    258 
    259 #ifdef __clang__
    260     // FIXME Clang and GCC disagree on the validity of this expression.
    261     test_is_constructible<const int&, ExplicitTo<int>>();
    262     static_assert(std::is_constructible<int&&, ExplicitTo<int>>::value, "");
    263     LIBCPP_STATIC_ASSERT(
    264         clang_disallows_valid_static_cast_bug !=
    265         std::__libcpp_is_constructible<int&&, ExplicitTo<int>>::value, "");
    266 #else
    267     test_is_not_constructible<const int&, ExplicitTo<int>>();
    268     test_is_not_constructible<int&&, ExplicitTo<int>>();
    269 #endif
    270 
    271     // Binding through temporary behaves like copy-initialization,
    272     // see [dcl.init.ref] p. 5, very last sub-bullet:
    273     test_is_not_constructible<const int&, ExplicitTo<double&&>>();
    274     test_is_not_constructible<int&&, ExplicitTo<double&&>>();
    275 
    276 
    277 // TODO: Remove this workaround once Clang <= 3.7 are no longer used regularly.
    278 // In those compiler versions the __is_constructible builtin gives the wrong
    279 // results for abominable function types.
    280 #if (defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER < 703) \
    281  || (defined(TEST_CLANG_VER) && TEST_CLANG_VER < 308)
    282 #define WORKAROUND_CLANG_BUG
    283 #endif
    284 #if !defined(WORKAROUND_CLANG_BUG)
    285     test_is_not_constructible<void()>();
    286     test_is_not_constructible<void() const> ();
    287     test_is_not_constructible<void() volatile> ();
    288     test_is_not_constructible<void() &> ();
    289     test_is_not_constructible<void() &&> ();
    290 #endif
    291 #endif // TEST_STD_VER >= 11
    292 }
    293