1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
14 // template <class T, class ...Args> any(in_place_type_t<T>, Args&&...);
15 // template <class T, class U, class ...Args>
16 // any(in_place_type_t<T>, initializer_list<U>, Args&&...);
18 // Test construction from a value.
21 // 1. The value is properly move/copied depending on the value category.
22 // 2. Both small and large values are properly handled.
28 #include "any_helpers.h"
29 #include "count_new.hpp"
30 #include "test_macros.h"
31 #include "test_convertible.hpp"
37 void test_in_place_type() {
38 // constructing from a small type should perform no allocations.
39 DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
40 assert(Type::count == 0);
43 any a(std::in_place_type<Type>);
45 assert(Type::count == 1);
46 assert(Type::copied == 0);
47 assert(Type::moved == 0);
48 assertContains<Type>(a, 0);
50 assert(Type::count == 0);
52 { // Test that the in_place argument is properly decayed
53 any a(std::in_place_type<Type&>);
55 assert(Type::count == 1);
56 assert(Type::copied == 0);
57 assert(Type::moved == 0);
58 assertContains<Type>(a, 0);
60 assert(Type::count == 0);
63 any a(std::in_place_type<Type>, 101);
65 assert(Type::count == 1);
66 assert(Type::copied == 0);
67 assert(Type::moved == 0);
68 assertContains<Type>(a, 101);
70 assert(Type::count == 0);
73 any a(std::in_place_type<Type>, -1, 42, -1);
75 assert(Type::count == 1);
76 assert(Type::copied == 0);
77 assert(Type::moved == 0);
78 assertContains<Type>(a, 42);
80 assert(Type::count == 0);
85 void test_in_place_type_tracked() {
86 // constructing from a small type should perform no allocations.
87 DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
89 any a(std::in_place_type<Type>);
90 assertArgsMatch<Type>(a);
93 any a(std::in_place_type<Type>, -1, 42, -1);
94 assertArgsMatch<Type, int, int, int>(a);
96 // initializer_list constructor tests
98 any a(std::in_place_type<Type>, {-1, 42, -1});
99 assertArgsMatch<Type, std::initializer_list<int>>(a);
103 any a(std::in_place_type<Type&>, {-1, 42, -1}, x);
104 assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
110 void test_in_place_type_decayed() {
112 using Type = decltype(test_func);
113 using DecayT = void(*)();
114 any a(std::in_place_type<Type>, test_func);
115 assert(containsType<DecayT>(a));
116 assert(any_cast<DecayT>(a) == test_func);
120 using Type = int(&)[5];
122 any a(std::in_place_type<Type>, my_arr);
123 assert(containsType<DecayT>(a));
124 assert(any_cast<DecayT>(a) == my_arr);
129 any a(std::in_place_type<Type>);
130 assert(containsType<DecayT>(a));
131 assert(any_cast<DecayT>(a) == nullptr);
135 void test_ctor_sfinae() {
137 // Test that the init-list ctor SFINAE's away properly when
138 // construction would be ill-formed.
139 using IL = std::initializer_list<int>;
140 static_assert(!std::is_constructible<std::any,
141 std::in_place_type_t<int>, IL>::value, "");
142 static_assert(std::is_constructible<std::any,
143 std::in_place_type_t<small_tracked_t>, IL>::value, "");
146 // Test that the tagged dispatch constructor SFINAE's away when the
147 // argument is non-copyable
150 NoCopy(NoCopy const&) = delete;
152 NoCopy(std::initializer_list<int>, int) {}
154 using Tag = std::in_place_type_t<NoCopy>;
155 using RefTag = std::in_place_type_t<NoCopy&>;
156 using IL = std::initializer_list<int>;
157 static_assert(!std::is_constructible<std::any, Tag>::value, "");
158 static_assert(!std::is_constructible<std::any, Tag, int>::value, "");
159 static_assert(!std::is_constructible<std::any, Tag, IL, int>::value, "");
160 static_assert(!std::is_constructible<std::any, RefTag>::value, "");
161 static_assert(!std::is_constructible<std::any, RefTag, int>::value, "");
162 static_assert(!std::is_constructible<std::any, RefTag, IL, int>::value, "");
168 Implicit(int, int, int) {}
169 Implicit(std::initializer_list<int>, int) {}
172 void test_constructor_explicit() {
174 using IT = std::in_place_type_t<I>;
175 static_assert(!test_convertible<std::any, IT, int>(), "");
176 static_assert(std::is_constructible<std::any, IT, int>::value, "");
177 static_assert(!test_convertible<std::any, IT, int, int, int>(), "");
178 static_assert(std::is_constructible<std::any, IT, int, int, int>::value, "");
179 static_assert(!test_convertible<std::any, IT, std::initializer_list<int>&, int>(), "");
180 static_assert(std::is_constructible<std::any, IT, std::initializer_list<int>&, int>::value, "");
184 test_in_place_type<small>();
185 test_in_place_type<large>();
186 test_in_place_type<small_throws_on_copy>();
187 test_in_place_type<large_throws_on_copy>();
188 test_in_place_type<throws_on_move>();
189 test_in_place_type_tracked<small_tracked_t>();
190 test_in_place_type_tracked<large_tracked_t>();
191 test_in_place_type_decayed();
193 test_constructor_explicit();