]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
Vendor import of libc++ trunk r302418:
[FreeBSD/FreeBSD.git] / test / std / utilities / variant / variant.variant / variant.mod / emplace_index_args.pass.cpp
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 // 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
19
20 // <variant>
21
22 // template <class ...Types> class variant;
23
24 // template <size_t I, class ...Args>
25 //   variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
26
27 #include <cassert>
28 #include <string>
29 #include <type_traits>
30 #include <variant>
31
32 #include "archetypes.hpp"
33 #include "test_convertible.hpp"
34 #include "test_macros.h"
35 #include "variant_test_helpers.hpp"
36
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) {
40   return true;
41 }
42
43 template <class, size_t, class...>
44 constexpr auto test_emplace_exists_imp(long) -> bool {
45   return false;
46 }
47
48 template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
49   return test_emplace_exists_imp<Var, I, Args...>(0);
50 }
51
52 void test_emplace_sfinae() {
53   {
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)>(),
58                   "cannot construct");
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");
66   }
67 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
68   {
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");
88   }
89 #endif
90 }
91
92 void test_basic() {
93   {
94     using V = std::variant<int>;
95     V v(42);
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));
104   }
105   {
106     using V =
107         std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
108     const int x = 100;
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));
124   }
125 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
126   {
127     using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
128                            std::string>;
129     const int x = 100;
130     int y = 42;
131     int z = 43;
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));
158   }
159 #endif
160 }
161
162 int main() {
163   test_basic();
164   test_emplace_sfinae();
165 }