1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 // TODO: Revisit this test once we have more information
12 // with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102247
17 // template <class T1, class T2> struct pair
19 // pair(const T1&, const T2&);
20 // template<class U = T1, class V = T2> pair(U&&, V&&);
22 // This test checks support for brace-initialization of pairs.
27 #include "test_macros.h"
30 constexpr explicit ExplicitT(int x
) : value(x
) {}
31 constexpr explicit ExplicitT(ExplicitT
const& o
) : value(o
.value
) {}
36 constexpr ImplicitT(int x
) : value(x
) {}
37 constexpr ImplicitT(ImplicitT
const& o
) : value(o
.value
) {}
41 template <class T
, class = decltype(std::pair
<T
, T
>({}, {}))>
42 constexpr bool can_construct_with_brace_init(int) { return true; }
44 constexpr bool can_construct_with_brace_init(...) { return false; }
46 #if TEST_STD_VER >= 17 // CTAD isn't supported before C++17
47 template <class T
, class = decltype(std::pair(T
{}, {}))>
48 constexpr bool can_construct_with_ctad_brace_init(int) { return true; }
50 constexpr bool can_construct_with_ctad_brace_init(...) { return false; }
53 struct BraceInit
{ BraceInit() = default; };
54 struct NoBraceInit
{ NoBraceInit(int); };
55 struct ExplicitBraceInit
{ explicit ExplicitBraceInit() = default; };
57 constexpr int explicit_vs_implicit_brace_init(std::pair
<ExplicitBraceInit
, ExplicitBraceInit
>) { return 1; }
58 constexpr int explicit_vs_implicit_brace_init(std::pair
<BraceInit
, BraceInit
>) { return 2; }
60 TEST_CONSTEXPR_CXX14
bool test() {
61 // Explicit constructor
63 std::pair
<ExplicitT
, BraceInit
> p1(ExplicitT
{42}, {});
64 assert(p1
.first
.value
== 42);
66 std::pair
<ExplicitT
, BraceInit
> p2
{ExplicitT
{42}, {}};
67 assert(p2
.first
.value
== 42);
70 std::pair
<BraceInit
, ExplicitT
> p1({}, ExplicitT
{42});
71 assert(p1
.second
.value
== 42);
73 std::pair
<BraceInit
, ExplicitT
> p2
{{}, ExplicitT
{42}};
74 assert(p2
.second
.value
== 42);
77 std::pair
<BraceInit
, BraceInit
> p
{{}, {}};
81 // Implicit constructor
83 std::pair
<ImplicitT
, BraceInit
> p
= {42, {}};
84 assert(p
.first
.value
== 42);
87 std::pair
<BraceInit
, ImplicitT
> p
= {{}, 42};
88 assert(p
.second
.value
== 42);
91 std::pair
<BraceInit
, BraceInit
> p
= {{}, {}};
95 // SFINAE-friendliness of some invalid cases
97 static_assert( can_construct_with_brace_init
<BraceInit
>(0), "");
98 static_assert(!can_construct_with_brace_init
<NoBraceInit
>(0), "");
100 #if TEST_STD_VER >= 17
101 // CTAD with {} should never work, since we can't possibly deduce the types
102 static_assert(!can_construct_with_ctad_brace_init
<BraceInit
>(0), "");
103 static_assert(!can_construct_with_ctad_brace_init
<int>(0), "");
107 // Make sure there is no ambiguity between the explicit and the non-explicit constructors
109 assert(explicit_vs_implicit_brace_init({{}, {}}) == 2);
115 int main(int, char**) {
117 #if TEST_STD_VER > 11
118 static_assert(test(), "");