• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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