libcxx

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

default-sfinae.pass.cpp (5173B)


      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 // <utility>
     11 
     12 // template <class T1, class T2> struct pair
     13 
     14 // Test the SFINAE required by LWG Issue #2367.
     15 // is_default_constructible<pair>
     16 
     17 // UNSUPPORTED: c++98, c++03
     18 
     19 #include <utility>
     20 #include <type_traits>
     21 #include <cassert>
     22 
     23 #include "test_macros.h"
     24 
     25 #if TEST_STD_VER > 11
     26 #define CONSTEXPR_CXX14 constexpr
     27 #define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "")
     28 #else
     29 #define CONSTEXPR_CXX14
     30 #define STATIC_ASSERT_CXX14(Pred) assert(Pred)
     31 #endif
     32 
     33 struct DeletedDefault {
     34     // A class with a deleted default constructor. Used to test the SFINAE
     35     // on std::pair's default constructor.
     36     constexpr explicit DeletedDefault(int x) : value(x) {}
     37     constexpr DeletedDefault() = delete;
     38     int value;
     39 };
     40 
     41 template <class Tp, bool>
     42 struct DependantType: public Tp {};
     43 
     44 template <class T, bool Val>
     45 using DependantIsDefault = DependantType<std::is_default_constructible<T>, Val>;
     46 
     47 template <class T>
     48 struct DefaultSFINAES {
     49     template <bool Dummy = false, class = typename std::enable_if<
     50              DependantIsDefault<T, Dummy>::value
     51                 >::type
     52             >
     53     constexpr DefaultSFINAES() : value() {}
     54     constexpr explicit DefaultSFINAES(T const& x) : value(x) {}
     55     T value;
     56 };
     57 
     58 struct NoDefault {
     59     constexpr NoDefault(int v) : value(v) {}
     60     int value;
     61 };
     62 
     63 template <class Tp>
     64 void test_not_is_default_constructible()
     65 {
     66     {
     67         typedef std::pair<int, Tp> P;
     68         static_assert(!std::is_default_constructible<P>::value, "");
     69         static_assert(std::is_constructible<P, int, Tp>::value, "");
     70     }
     71     {
     72         typedef std::pair<Tp, int> P;
     73         static_assert(!std::is_default_constructible<P>::value, "");
     74         static_assert(std::is_constructible<P, Tp, int>::value, "");
     75     }
     76     {
     77         typedef std::pair<Tp, Tp> P;
     78         static_assert(!std::is_default_constructible<P>::value, "");
     79         static_assert(std::is_constructible<P, Tp, Tp>::value, "");
     80     }
     81 }
     82 
     83 template <class Tp>
     84 void test_is_default_constructible()
     85 {
     86     {
     87         typedef std::pair<int, Tp> P;
     88         static_assert(std::is_default_constructible<P>::value, "");
     89     }
     90     {
     91         typedef std::pair<Tp, int> P;
     92         static_assert(std::is_default_constructible<P>::value, "");
     93     }
     94     {
     95         typedef std::pair<Tp, Tp> P;
     96         static_assert(std::is_default_constructible<P>::value, "");
     97     }
     98 }
     99 
    100 template <class T>
    101 struct IllFormedDefaultImp {
    102   constexpr explicit IllFormedDefaultImp(int v) : value(v) {}
    103   constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {}
    104   int value;
    105 };
    106 
    107 typedef IllFormedDefaultImp<int> IllFormedDefault;
    108     // A class which provides a constexpr default constructor with a valid
    109     // signature but an ill-formed body. The A compile error will be emitted if
    110     // the default constructor is instantiated.
    111 
    112 
    113 // Check that the SFINAE on the default constructor is not evaluated when
    114 // it isn't needed. If the default constructor of 'IllFormedDefault' is evaluated
    115 // in C++11, even with is_default_constructible, then this test should fail to
    116 // compile. In C++14 and greater evaluate each test is evaluated as a constant
    117 // expression.
    118 // See LWG issue #2367
    119 void test_illformed_default()
    120 {
    121     {
    122     typedef std::pair<IllFormedDefault, int> P;
    123     static_assert((std::is_constructible<P, IllFormedDefault, int>::value), "");
    124     CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5);
    125     STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5);
    126     }
    127     {
    128     typedef std::pair<int, IllFormedDefault> P;
    129     static_assert((std::is_constructible<P, int, IllFormedDefault>::value), "");
    130     CONSTEXPR_CXX14 IllFormedDefault dd(-5);
    131     CONSTEXPR_CXX14 P p(42, dd);
    132     STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5);
    133     }
    134     {
    135     typedef std::pair<IllFormedDefault, IllFormedDefault> P;
    136     static_assert((std::is_constructible<P, IllFormedDefault, IllFormedDefault>::value), "");
    137     CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5));
    138     STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5);
    139     }
    140 }
    141 
    142 
    143 int main()
    144 {
    145     {
    146         // Check that pair<T, U> can still be used even if
    147         // is_default_constructible<T> or is_default_constructible<U> cause
    148         // a compilation error.
    149         test_illformed_default();
    150     }
    151     {
    152         // pair::pair() is only disable in C++11 and beyond.
    153         test_not_is_default_constructible<NoDefault>();
    154         test_not_is_default_constructible<DeletedDefault>();
    155         test_not_is_default_constructible<DefaultSFINAES<int&>>();
    156         test_not_is_default_constructible<DefaultSFINAES<int&&>>();
    157         test_not_is_default_constructible<int&>();
    158         test_not_is_default_constructible<int&&>();
    159     }
    160     {
    161         test_is_default_constructible<int>();
    162         test_is_default_constructible<DefaultSFINAES<int>>();
    163     }
    164 }