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