libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

is_constructible.pass.cpp (10004B)


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