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. |
35 | 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 | > |
52 | constexpr DefaultSFINAES() : value() {} |
53 | constexpr explicit DefaultSFINAES(T const& x) : value(x) {} |
54 | T value; |
55 | }; |
56 | |
57 | struct NoDefault { |
58 | constexpr NoDefault(int v) : value(v) {} |
59 | int value; |
60 | }; |
61 | |
62 | template <class Tp> |
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> |
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 { |
101 | constexpr explicit IllFormedDefaultImp(int v) : value(v) {} |
102 | 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 |
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 | |
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 | |