Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / utilities / variant / variant.variant / variant.mod / emplace_index_args.pass.cpp
blob21a02c24f7db47730bcedc536cb4a82eae45568d
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
11 // XFAIL: availability-bad_variant_access-missing && !no-exceptions
13 // <variant>
15 // template <class ...Types> class variant;
17 // template <size_t I, class ...Args>
18 // variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
20 #include <cassert>
21 #include <string>
22 #include <type_traits>
23 #include <variant>
25 #include "archetypes.h"
26 #include "test_convertible.h"
27 #include "test_macros.h"
28 #include "variant_test_helpers.h"
30 template <class Var, std::size_t I, class... Args>
31 constexpr auto test_emplace_exists_imp(int) -> decltype(
32 std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
33 return true;
36 template <class, std::size_t, class...>
37 constexpr auto test_emplace_exists_imp(long) -> bool {
38 return false;
41 template <class Var, std::size_t I, class... Args> constexpr bool emplace_exists() {
42 return test_emplace_exists_imp<Var, I, Args...>(0);
45 void test_emplace_sfinae() {
47 using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
48 static_assert(emplace_exists<V, 0>(), "");
49 static_assert(emplace_exists<V, 0, int>(), "");
50 static_assert(!emplace_exists<V, 0, decltype(nullptr)>(),
51 "cannot construct");
52 static_assert(emplace_exists<V, 1, decltype(nullptr)>(), "");
53 static_assert(emplace_exists<V, 1, int *>(), "");
54 static_assert(!emplace_exists<V, 1, const int *>(), "");
55 static_assert(!emplace_exists<V, 1, int>(), "cannot construct");
56 static_assert(emplace_exists<V, 2, const int *>(), "");
57 static_assert(emplace_exists<V, 2, int *>(), "");
58 static_assert(!emplace_exists<V, 3>(), "cannot construct");
60 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
62 using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
63 static_assert(emplace_exists<V, 0>(), "");
64 static_assert(emplace_exists<V, 0, int>(), "");
65 static_assert(emplace_exists<V, 0, long long>(), "");
66 static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
67 static_assert(emplace_exists<V, 1, int &>(), "");
68 static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
69 static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
70 static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
71 static_assert(emplace_exists<V, 2, int &>(), "");
72 static_assert(emplace_exists<V, 2, const int &>(), "");
73 static_assert(emplace_exists<V, 2, int &&>(), "");
74 static_assert(!emplace_exists<V, 2, void *>(),
75 "not constructible from void*");
76 static_assert(emplace_exists<V, 3, int>(), "");
77 static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
78 static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
79 static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
80 static_assert(!emplace_exists<V, 4>(), "no ctors");
82 #endif
85 void test_basic() {
87 using V = std::variant<int>;
88 V v(42);
89 auto& ref1 = v.emplace<0>();
90 static_assert(std::is_same_v<int&, decltype(ref1)>, "");
91 assert(std::get<0>(v) == 0);
92 assert(&ref1 == &std::get<0>(v));
93 auto& ref2 = v.emplace<0>(42);
94 static_assert(std::is_same_v<int&, decltype(ref2)>, "");
95 assert(std::get<0>(v) == 42);
96 assert(&ref2 == &std::get<0>(v));
99 using V =
100 std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
101 const int x = 100;
102 V v(std::in_place_index<0>, -1);
103 // default emplace a value
104 auto& ref1 = v.emplace<1>();
105 static_assert(std::is_same_v<long&, decltype(ref1)>, "");
106 assert(std::get<1>(v) == 0);
107 assert(&ref1 == &std::get<1>(v));
108 auto& ref2 = v.emplace<2>(&x);
109 static_assert(std::is_same_v<const void*&, decltype(ref2)>, "");
110 assert(std::get<2>(v) == &x);
111 assert(&ref2 == &std::get<2>(v));
112 // emplace with multiple args
113 auto& ref3 = v.emplace<4>(3u, 'a');
114 static_assert(std::is_same_v<std::string&, decltype(ref3)>, "");
115 assert(std::get<4>(v) == "aaa");
116 assert(&ref3 == &std::get<4>(v));
118 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
120 using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
121 std::string>;
122 const int x = 100;
123 int y = 42;
124 int z = 43;
125 V v(std::in_place_index<0>, -1);
126 // default emplace a value
127 auto& ref1 = v.emplace<1>();
128 static_assert(std::is_same_v<long&, decltype(ref1)>, "");
129 assert(std::get<1>(v) == 0);
130 assert(&ref1 == &std::get<1>(v));
131 // emplace a reference
132 auto& ref2 = v.emplace<2>(x);
133 static_assert(std::is_same_v<&, decltype(ref)>, "");
134 assert(&std::get<2>(v) == &x);
135 assert(&ref2 == &std::get<2>(v));
136 // emplace an rvalue reference
137 auto& ref3 = v.emplace<3>(std::move(y));
138 static_assert(std::is_same_v<&, decltype(ref)>, "");
139 assert(&std::get<3>(v) == &y);
140 assert(&ref3 == &std::get<3>(v));
141 // re-emplace a new reference over the active member
142 auto& ref4 = v.emplace<3>(std::move(z));
143 static_assert(std::is_same_v<&, decltype(ref)>, "");
144 assert(&std::get<3>(v) == &z);
145 assert(&ref4 == &std::get<3>(v));
146 // emplace with multiple args
147 auto& ref5 = v.emplace<5>(3u, 'a');
148 static_assert(std::is_same_v<std::string&, decltype(ref5)>, "");
149 assert(std::get<5>(v) == "aaa");
150 assert(&ref5 == &std::get<5>(v));
152 #endif
155 int main(int, char**) {
156 test_basic();
157 test_emplace_sfinae();
159 return 0;