]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / utilities / any / any.class / any.cons / in_place_type.pass.cpp
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11
12 // <any>
13
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&&...);
17
18 // Test construction from a value.
19 // Concerns:
20 // ---------
21 // 1. The value is properly move/copied depending on the value category.
22 // 2. Both small and large values are properly handled.
23
24
25 #include <any>
26 #include <cassert>
27
28 #include "any_helpers.h"
29 #include "count_new.hpp"
30 #include "test_macros.h"
31 #include "test_convertible.hpp"
32
33 using std::any;
34 using std::any_cast;
35
36 template <class Type>
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);
41     Type::reset();
42     {
43         any a(std::in_place_type<Type>);
44
45         assert(Type::count == 1);
46         assert(Type::copied == 0);
47         assert(Type::moved == 0);
48         assertContains<Type>(a, 0);
49     }
50     assert(Type::count == 0);
51     Type::reset();
52     { // Test that the in_place argument is properly decayed
53         any a(std::in_place_type<Type&>);
54
55         assert(Type::count == 1);
56         assert(Type::copied == 0);
57         assert(Type::moved == 0);
58         assertContains<Type>(a, 0);
59     }
60     assert(Type::count == 0);
61     Type::reset();
62     {
63         any a(std::in_place_type<Type>, 101);
64
65         assert(Type::count == 1);
66         assert(Type::copied == 0);
67         assert(Type::moved == 0);
68         assertContains<Type>(a, 101);
69     }
70     assert(Type::count == 0);
71     Type::reset();
72     {
73         any a(std::in_place_type<Type>, -1, 42, -1);
74
75         assert(Type::count == 1);
76         assert(Type::copied == 0);
77         assert(Type::moved == 0);
78         assertContains<Type>(a, 42);
79     }
80     assert(Type::count == 0);
81     Type::reset();
82 }
83
84 template <class Type>
85 void test_in_place_type_tracked() {
86     // constructing from a small type should perform no allocations.
87     DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
88     {
89         any a(std::in_place_type<Type>);
90         assertArgsMatch<Type>(a);
91     }
92     {
93         any a(std::in_place_type<Type>, -1, 42, -1);
94         assertArgsMatch<Type, int, int, int>(a);
95     }
96     // initializer_list constructor tests
97     {
98         any a(std::in_place_type<Type>, {-1, 42, -1});
99         assertArgsMatch<Type, std::initializer_list<int>>(a);
100     }
101     {
102         int x = 42;
103         any a(std::in_place_type<Type&>, {-1, 42, -1}, x);
104         assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
105     }
106 }
107
108 void test_func() {}
109
110 void test_in_place_type_decayed() {
111     {
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);
117     }
118     {
119         int my_arr[5];
120         using Type = int(&)[5];
121         using DecayT = int*;
122         any a(std::in_place_type<Type>, my_arr);
123         assert(containsType<DecayT>(a));
124         assert(any_cast<DecayT>(a) == my_arr);
125     }
126     {
127         using Type = int[5];
128         using DecayT = int*;
129         any a(std::in_place_type<Type>);
130         assert(containsType<DecayT>(a));
131         assert(any_cast<DecayT>(a) == nullptr);
132     }
133 }
134
135 void test_ctor_sfinae() {
136     {
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, "");
144     }
145     {
146         // Test that the tagged dispatch constructor SFINAE's away when the
147         // argument is non-copyable
148         struct NoCopy {
149           NoCopy() = default;
150           NoCopy(NoCopy const&) = delete;
151           NoCopy(int) {}
152           NoCopy(std::initializer_list<int>, int) {}
153         };
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, "");
163     }
164 }
165
166 struct Implicit {
167   Implicit(int) {}
168   Implicit(int, int, int) {}
169   Implicit(std::initializer_list<int>, int) {}
170 };
171
172 void test_constructor_explicit() {
173     using I = Implicit;
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, "");
181 }
182
183 int main() {
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();
192     test_ctor_sfinae();
193     test_constructor_explicit();
194 }