2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
13 // XFAIL: with_system_cxx_lib=macosx10.12
14 // XFAIL: with_system_cxx_lib=macosx10.11
15 // XFAIL: with_system_cxx_lib=macosx10.10
16 // XFAIL: with_system_cxx_lib=macosx10.9
17 // XFAIL: with_system_cxx_lib=macosx10.7
18 // XFAIL: with_system_cxx_lib=macosx10.8
22 // template <class ...Types> class variant;
24 // template <size_t I, class ...Args>
25 // variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
29 #include <type_traits>
32 #include "archetypes.hpp"
33 #include "test_convertible.hpp"
34 #include "test_macros.h"
35 #include "variant_test_helpers.hpp"
37 template <class Var, size_t I, class... Args>
38 constexpr auto test_emplace_exists_imp(int) -> decltype(
39 std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
43 template <class, size_t, class...>
44 constexpr auto test_emplace_exists_imp(long) -> bool {
48 template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
49 return test_emplace_exists_imp<Var, I, Args...>(0);
52 void test_emplace_sfinae() {
54 using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
55 static_assert(emplace_exists<V, 0>(), "");
56 static_assert(emplace_exists<V, 0, int>(), "");
57 static_assert(!emplace_exists<V, 0, decltype(nullptr)>(),
59 static_assert(emplace_exists<V, 1, decltype(nullptr)>(), "");
60 static_assert(emplace_exists<V, 1, int *>(), "");
61 static_assert(!emplace_exists<V, 1, const int *>(), "");
62 static_assert(!emplace_exists<V, 1, int>(), "cannot construct");
63 static_assert(emplace_exists<V, 2, const int *>(), "");
64 static_assert(emplace_exists<V, 2, int *>(), "");
65 static_assert(!emplace_exists<V, 3>(), "cannot construct");
67 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
69 using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
70 static_assert(emplace_exists<V, 0>(), "");
71 static_assert(emplace_exists<V, 0, int>(), "");
72 static_assert(emplace_exists<V, 0, long long>(), "");
73 static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
74 static_assert(emplace_exists<V, 1, int &>(), "");
75 static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
76 static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
77 static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
78 static_assert(emplace_exists<V, 2, int &>(), "");
79 static_assert(emplace_exists<V, 2, const int &>(), "");
80 static_assert(emplace_exists<V, 2, int &&>(), "");
81 static_assert(!emplace_exists<V, 2, void *>(),
82 "not constructible from void*");
83 static_assert(emplace_exists<V, 3, int>(), "");
84 static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
85 static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
86 static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
87 static_assert(!emplace_exists<V, 4>(), "no ctors");
94 using V = std::variant<int>;
96 auto& ref1 = v.emplace<0>();
97 static_assert(std::is_same_v<int&, decltype(ref1)>, "");
98 assert(std::get<0>(v) == 0);
99 assert(&ref1 == &std::get<0>(v));
100 auto& ref2 = v.emplace<0>(42);
101 static_assert(std::is_same_v<int&, decltype(ref2)>, "");
102 assert(std::get<0>(v) == 42);
103 assert(&ref2 == &std::get<0>(v));
107 std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
109 V v(std::in_place_index<0>, -1);
110 // default emplace a value
111 auto& ref1 = v.emplace<1>();
112 static_assert(std::is_same_v<long&, decltype(ref1)>, "");
113 assert(std::get<1>(v) == 0);
114 assert(&ref1 == &std::get<1>(v));
115 auto& ref2 = v.emplace<2>(&x);
116 static_assert(std::is_same_v<const void*&, decltype(ref2)>, "");
117 assert(std::get<2>(v) == &x);
118 assert(&ref2 == &std::get<2>(v));
119 // emplace with multiple args
120 auto& ref3 = v.emplace<4>(3, 'a');
121 static_assert(std::is_same_v<std::string&, decltype(ref3)>, "");
122 assert(std::get<4>(v) == "aaa");
123 assert(&ref3 == &std::get<4>(v));
125 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
127 using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
132 V v(std::in_place_index<0>, -1);
133 // default emplace a value
134 auto& ref1 = v.emplace<1>();
135 static_assert(std::is_same_v<long&, decltype(ref1)>, "");
136 assert(std::get<1>(v) == 0);
137 assert(&ref1 == &std::get<1>(v));
138 // emplace a reference
139 auto& ref2 = v.emplace<2>(x);
140 static_assert(std::is_same_v<&, decltype(ref)>, "");
141 assert(&std::get<2>(v) == &x);
142 assert(&ref2 == &std::get<2>(v));
143 // emplace an rvalue reference
144 auto& ref3 = v.emplace<3>(std::move(y));
145 static_assert(std::is_same_v<&, decltype(ref)>, "");
146 assert(&std::get<3>(v) == &y);
147 assert(&ref3 == &std::get<3>(v));
148 // re-emplace a new reference over the active member
149 auto& ref4 = v.emplace<3>(std::move(z));
150 static_assert(std::is_same_v<&, decltype(ref)>, "");
151 assert(&std::get<3>(v) == &z);
152 assert(&ref4 == &std::get<3>(v));
153 // emplace with multiple args
154 auto& ref5 = v.emplace<5>(3, 'a');
155 static_assert(std::is_same_v<std::string&, decltype(ref5)>, "");
156 assert(std::get<5>(v) == "aaa");
157 assert(&ref5 == &std::get<5>(v));
164 test_emplace_sfinae();