1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
12
13 // <variant>
14
15 // template <class ...Types> class variant;
16
17 // template <size_t I, class ...Args> void emplace(Args&&... args);
18
19 #include <cassert>
20 #include <string>
21 #include <type_traits>
22 #include <variant>
23
24 #include "archetypes.hpp"
25 #include "test_convertible.hpp"
26 #include "test_macros.h"
27 #include "variant_test_helpers.hpp"
28
29 template <class Var, size_t I, class... Args>
test_emplace_exists_imp(int)30 constexpr auto test_emplace_exists_imp(int) -> decltype(
31 std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
32 return true;
33 }
34
35 template <class, size_t, class...>
test_emplace_exists_imp(long)36 constexpr auto test_emplace_exists_imp(long) -> bool {
37 return false;
38 }
39
emplace_exists()40 template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
41 return test_emplace_exists_imp<Var, I, Args...>(0);
42 }
43
test_emplace_sfinae()44 void test_emplace_sfinae() {
45 {
46 using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
47 static_assert(emplace_exists<V, 0>(), "");
48 static_assert(emplace_exists<V, 0, int>(), "");
49 static_assert(!emplace_exists<V, 0, decltype(nullptr)>(),
50 "cannot construct");
51 static_assert(emplace_exists<V, 1, decltype(nullptr)>(), "");
52 static_assert(emplace_exists<V, 1, int *>(), "");
53 static_assert(!emplace_exists<V, 1, const int *>(), "");
54 static_assert(!emplace_exists<V, 1, int>(), "cannot construct");
55 static_assert(emplace_exists<V, 2, const int *>(), "");
56 static_assert(emplace_exists<V, 2, int *>(), "");
57 static_assert(!emplace_exists<V, 3>(), "cannot construct");
58 }
59 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
60 {
61 using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
62 static_assert(emplace_exists<V, 0>(), "");
63 static_assert(emplace_exists<V, 0, int>(), "");
64 static_assert(emplace_exists<V, 0, long long>(), "");
65 static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
66 static_assert(emplace_exists<V, 1, int &>(), "");
67 static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
68 static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
69 static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
70 static_assert(emplace_exists<V, 2, int &>(), "");
71 static_assert(emplace_exists<V, 2, const int &>(), "");
72 static_assert(emplace_exists<V, 2, int &&>(), "");
73 static_assert(!emplace_exists<V, 2, void *>(),
74 "not constructible from void*");
75 static_assert(emplace_exists<V, 3, int>(), "");
76 static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
77 static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
78 static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
79 static_assert(!emplace_exists<V, 4>(), "no ctors");
80 }
81 #endif
82 }
83
test_basic()84 void test_basic() {
85 {
86 using V = std::variant<int>;
87 V v(42);
88 v.emplace<0>();
89 assert(std::get<0>(v) == 0);
90 v.emplace<0>(42);
91 assert(std::get<0>(v) == 42);
92 }
93 {
94 using V =
95 std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
96 const int x = 100;
97 V v(std::in_place_index<0>, -1);
98 // default emplace a value
99 v.emplace<1>();
100 assert(std::get<1>(v) == 0);
101 v.emplace<2>(&x);
102 assert(std::get<2>(v) == &x);
103 // emplace with multiple args
104 v.emplace<4>(3, 'a');
105 assert(std::get<4>(v) == "aaa");
106 }
107 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
108 {
109 using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
110 std::string>;
111 const int x = 100;
112 int y = 42;
113 int z = 43;
114 V v(std::in_place_index<0>, -1);
115 // default emplace a value
116 v.emplace<1>();
117 assert(std::get<1>(v) == 0);
118 // emplace a reference
119 v.emplace<2>(x);
120 assert(&std::get<2>(v) == &x);
121 // emplace an rvalue reference
122 v.emplace<3>(std::move(y));
123 assert(&std::get<3>(v) == &y);
124 // re-emplace a new reference over the active member
125 v.emplace<3>(std::move(z));
126 assert(&std::get<3>(v) == &z);
127 // emplace with multiple args
128 v.emplace<5>(3, 'a');
129 assert(std::get<5>(v) == "aaa");
130 }
131 #endif
132 }
133
main()134 int main() {
135 test_basic();
136 test_emplace_sfinae();
137 }
138