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// UNSUPPORTED: c++03
10
11// TODO: Revisit this test once we have more information
12// with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102247
13// XFAIL: gcc
14
15// <utility>
16
17// template <class T1, class T2> struct pair
18//
19// pair(const T1&, const T2&);
20// template<class U = T1, class V = T2> pair(U&&, V&&);
21
22// This test checks support for brace-initialization of pairs.
23
24#include <utility>
25#include <cassert>
26
27#include "test_macros.h"
28
29struct ExplicitT {
30 constexpr explicit ExplicitT(int x) : value(x) {}
31 constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
32 int value;
33};
34
35struct ImplicitT {
36 constexpr ImplicitT(int x) : value(x) {}
37 constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
38 int value;
39};
40
41template <class T, class = decltype(std::pair<T, T>({}, {}))>
42constexpr bool can_construct_with_brace_init(int) { return true; }
43template <class T>
44constexpr bool can_construct_with_brace_init(...) { return false; }
45
46#if TEST_STD_VER >= 17 // CTAD isn't supported before C++17
47template <class T, class = decltype(std::pair(T{}, {}))>
48constexpr bool can_construct_with_ctad_brace_init(int) { return true; }
49template <class T>
50constexpr bool can_construct_with_ctad_brace_init(...) { return false; }
51#endif
52
53struct BraceInit { BraceInit() = default; };
54struct NoBraceInit { NoBraceInit(int); };
55struct ExplicitBraceInit { explicit ExplicitBraceInit() = default; };
56
57constexpr int explicit_vs_implicit_brace_init(std::pair<ExplicitBraceInit, ExplicitBraceInit>) { return 1; }
58constexpr int explicit_vs_implicit_brace_init(std::pair<BraceInit, BraceInit>) { return 2; }
59
60TEST_CONSTEXPR_CXX14 bool test() {
61 // Explicit constructor
62 {
63 std::pair<ExplicitT, BraceInit> p1(ExplicitT{42}, {});
64 assert(p1.first.value == 42);
65
66 std::pair<ExplicitT, BraceInit> p2{ExplicitT{42}, {}};
67 assert(p2.first.value == 42);
68 }
69 {
70 std::pair<BraceInit, ExplicitT> p1({}, ExplicitT{42});
71 assert(p1.second.value == 42);
72
73 std::pair<BraceInit, ExplicitT> p2{{}, ExplicitT{42}};
74 assert(p2.second.value == 42);
75 }
76 {
77 std::pair<BraceInit, BraceInit> p{{}, {}};
78 (void)p;
79 }
80
81 // Implicit constructor
82 {
83 std::pair<ImplicitT, BraceInit> p = {42, {}};
84 assert(p.first.value == 42);
85 }
86 {
87 std::pair<BraceInit, ImplicitT> p = {{}, 42};
88 assert(p.second.value == 42);
89 }
90 {
91 std::pair<BraceInit, BraceInit> p = {{}, {}};
92 (void)p;
93 }
94
95 // SFINAE-friendliness of some invalid cases
96 {
97 static_assert( can_construct_with_brace_init<BraceInit>(0), "");
98 static_assert(!can_construct_with_brace_init<NoBraceInit>(0), "");
99
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), "");
104#endif
105 }
106
107 // Make sure there is no ambiguity between the explicit and the non-explicit constructors
108 {
109 assert(explicit_vs_implicit_brace_init({{}, {}}) == 2);
110 }
111
112 return true;
113}
114
115int main(int, char**) {
116 test();
117#if TEST_STD_VER > 11
118 static_assert(test(), "");
119#endif
120
121 return 0;
122}
123

source code of libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.brace-init.pass.cpp