]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / variant / variant.variant / variant.mod / emplace_type_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 // <variant>
14
15 // template <class ...Types> class variant;
16
17 // template <class T, 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, class T, class... Args>
30 constexpr auto test_emplace_exists_imp(int) -> decltype(
31     std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
32   return true;
33 }
34
35 template <class, class, class...>
36 constexpr auto test_emplace_exists_imp(long) -> bool {
37   return false;
38 }
39
40 template <class... Args> constexpr bool emplace_exists() {
41   return test_emplace_exists_imp<Args...>(0);
42 }
43
44 void test_emplace_sfinae() {
45   {
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)>(),
50                   "cannot construct");
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");
58   }
59 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
60   using V = std::variant<int, int &, const int &, int &&, long, long,
61                          TestTypes::NoCtors>;
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");
82 #endif
83 }
84
85 void test_basic() {
86   {
87     using V = std::variant<int>;
88     V v(42);
89     v.emplace<int>();
90     assert(std::get<0>(v) == 0);
91     v.emplace<int>(42);
92     assert(std::get<0>(v) == 42);
93   }
94   {
95     using V =
96         std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
97     const int x = 100;
98     V v(std::in_place_type<int>, -1);
99     // default emplace a value
100     v.emplace<long>();
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");
107   }
108 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
109   {
110     using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
111                            std::string>;
112     const int x = 100;
113     int y = 42;
114     int z = 43;
115     V v(std::in_place_index<0>, -1);
116     // default emplace a value
117     v.emplace<long>();
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");
131   }
132 #endif
133 }
134
135 int main() {
136   test_basic();
137   test_emplace_sfinae();
138 }