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
15 // template <class ...Types> class variant;
17 // template <class T, class ...Args> void emplace(Args&&... args);
21 #include <type_traits>
24 #include "archetypes.hpp"
25 #include "test_convertible.hpp"
26 #include "test_macros.h"
27 #include "variant_test_helpers.hpp"
29 template <class Var, class T, class... Args>
30 constexpr auto test_emplace_exists_imp(int) -> decltype(
31 std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
35 template <class, class, class...>
36 constexpr auto test_emplace_exists_imp(long) -> bool {
40 template <class... Args> constexpr bool emplace_exists() {
41 return test_emplace_exists_imp<Args...>(0);
44 void test_emplace_sfinae() {
46 using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
47 static_assert(emplace_exists<V, int>(), "");
48 static_assert(emplace_exists<V, int, int>(), "");
49 static_assert(!emplace_exists<V, int, decltype(nullptr)>(),
51 static_assert(emplace_exists<V, void *, decltype(nullptr)>(), "");
52 static_assert(!emplace_exists<V, void *, int>(), "cannot construct");
53 static_assert(emplace_exists<V, void *, int *>(), "");
54 static_assert(!emplace_exists<V, void *, const int *>(), "");
55 static_assert(emplace_exists<V, const void *, const int *>(), "");
56 static_assert(emplace_exists<V, const void *, int *>(), "");
57 static_assert(!emplace_exists<V, TestTypes::NoCtors>(), "cannot construct");
59 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
60 using V = std::variant<int, int &, const int &, int &&, long, long,
62 static_assert(emplace_exists<V, int>(), "");
63 static_assert(emplace_exists<V, int, int>(), "");
64 static_assert(emplace_exists<V, int, long long>(), "");
65 static_assert(!emplace_exists<V, int, int, int>(), "too many args");
66 static_assert(emplace_exists<V, int &, int &>(), "");
67 static_assert(!emplace_exists<V, int &>(), "cannot default construct ref");
68 static_assert(!emplace_exists<V, int &, const int &>(), "cannot bind ref");
69 static_assert(!emplace_exists<V, int &, int &&>(), "cannot bind ref");
70 static_assert(emplace_exists<V, const int &, int &>(), "");
71 static_assert(emplace_exists<V, const int &, const int &>(), "");
72 static_assert(emplace_exists<V, const int &, int &&>(), "");
73 static_assert(!emplace_exists<V, const int &, void *>(),
74 "not constructible from void*");
75 static_assert(emplace_exists<V, int &&, int>(), "");
76 static_assert(!emplace_exists<V, int &&, int &>(), "cannot bind ref");
77 static_assert(!emplace_exists<V, int &&, const int &>(), "cannot bind ref");
78 static_assert(!emplace_exists<V, int &&, const int &&>(), "cannot bind ref");
79 static_assert(!emplace_exists<V, long, long>(), "ambiguous");
80 static_assert(!emplace_exists<V, TestTypes::NoCtors>(),
81 "cannot construct void");
87 using V = std::variant<int>;
90 assert(std::get<0>(v) == 0);
92 assert(std::get<0>(v) == 42);
96 std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
98 V v(std::in_place_type<int>, -1);
99 // default emplace a value
101 assert(std::get<1>(v) == 0);
102 v.emplace<const void *>(&x);
103 assert(std::get<2>(v) == &x);
104 // emplace with multiple args
105 v.emplace<std::string>(3, 'a');
106 assert(std::get<4>(v) == "aaa");
108 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
110 using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
115 V v(std::in_place_index<0>, -1);
116 // default emplace a value
118 assert(std::get<long>(v) == 0);
119 // emplace a reference
120 v.emplace<const int &>(x);
121 assert(&std::get<const int &>(v) == &x);
122 // emplace an rvalue reference
123 v.emplace<int &&>(std::move(y));
124 assert(&std::get<int &&>(v) == &y);
125 // re-emplace a new reference over the active member
126 v.emplace<int &&>(std::move(z));
127 assert(&std::get<int &&>(v) == &z);
128 // emplace with multiple args
129 v.emplace<std::string>(3, 'a');
130 assert(std::get<std::string>(v) == "aaa");
137 test_emplace_sfinae();