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
32struct 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
40template <class Tp, bool>
41struct DependantType: public Tp {};
42
43template <class T, bool Val>
44using DependantIsDefault = DependantType<std::is_default_constructible<T>, Val>;
45
46template <class T>
47struct 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
57struct NoDefault {
58 constexpr NoDefault(int v) : value(v) {}
59 int value;
60};
61
62template <class Tp>
63void 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
82template <class Tp>
83void 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
99template <class T>
100struct IllFormedDefaultImp {
101 constexpr explicit IllFormedDefaultImp(int v) : value(v) {}
102 constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {}
103 int value;
104};
105
106typedef 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
118void 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
142int 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

source code of libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.default.sfinae_LWG2367.pass.cpp