1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14
10 
11 // Throwing bad_any_cast is supported starting in macosx10.13
12 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12}} && !no-exceptions
13 
14 // <any>
15 
16 // template <class T, class ...Args> any make_any(Args&&...);
17 // template <class T, class U, class ...Args>
18 // any make_any(initializer_list<U>, Args&&...);
19 
20 #include <any>
21 #include <cassert>
22 
23 #include "any_helpers.h"
24 #include "count_new.h"
25 #include "test_macros.h"
26 
27 template <class Type>
test_make_any_type()28 void test_make_any_type() {
29     // constructing from a small type should perform no allocations.
30     DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
31     assert(Type::count == 0);
32     Type::reset();
33     {
34         std::any a = std::make_any<Type>();
35 
36         assert(Type::count == 1);
37         assert(Type::copied == 0);
38         assert(Type::moved == 0);
39         assertContains<Type>(a, 0);
40     }
41     assert(Type::count == 0);
42     Type::reset();
43     {
44         std::any a = std::make_any<Type>(101);
45 
46         assert(Type::count == 1);
47         assert(Type::copied == 0);
48         assert(Type::moved == 0);
49         assertContains<Type>(a, 101);
50     }
51     assert(Type::count == 0);
52     Type::reset();
53     {
54         std::any a = std::make_any<Type>(-1, 42, -1);
55 
56         assert(Type::count == 1);
57         assert(Type::copied == 0);
58         assert(Type::moved == 0);
59         assertContains<Type>(a, 42);
60     }
61     assert(Type::count == 0);
62     Type::reset();
63 }
64 
65 template <class Type>
test_make_any_type_tracked()66 void test_make_any_type_tracked() {
67     // constructing from a small type should perform no allocations.
68     DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
69     {
70         std::any a = std::make_any<Type>();
71         assertArgsMatch<Type>(a);
72     }
73     {
74         std::any a = std::make_any<Type>(-1, 42, -1);
75         assertArgsMatch<Type, int, int, int>(a);
76     }
77     // initializer_list constructor tests
78     {
79         std::any a = std::make_any<Type>({-1, 42, -1});
80         assertArgsMatch<Type, std::initializer_list<int>>(a);
81     }
82     {
83         int x = 42;
84         std::any a  = std::make_any<Type>({-1, 42, -1}, x);
85         assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
86     }
87 }
88 
89 #ifndef TEST_HAS_NO_EXCEPTIONS
90 
91 struct SmallThrows {
SmallThrowsSmallThrows92   SmallThrows(int) { throw 42; }
SmallThrowsSmallThrows93   SmallThrows(std::initializer_list<int>, int) { throw 42; }
94 };
95 static_assert(IsSmallObject<SmallThrows>::value, "");
96 
97 struct LargeThrows {
LargeThrowsLargeThrows98   LargeThrows(int) { throw 42; }
LargeThrowsLargeThrows99   LargeThrows(std::initializer_list<int>, int) { throw 42; }
100   int data[sizeof(std::any)];
101 };
102 static_assert(!IsSmallObject<LargeThrows>::value, "");
103 
104 template <class Type>
test_make_any_throws()105 void test_make_any_throws()
106 {
107     {
108         try {
109             TEST_IGNORE_NODISCARD std::make_any<Type>(101);
110             assert(false);
111         } catch (int const&) {
112         }
113     }
114     {
115         try {
116             TEST_IGNORE_NODISCARD std::make_any<Type>({1, 2, 3}, 101);
117             assert(false);
118         } catch (int const&) {
119         }
120     }
121 }
122 
123 #endif
124 
main(int,char **)125 int main(int, char**) {
126     test_make_any_type<small>();
127     test_make_any_type<large>();
128     test_make_any_type<small_throws_on_copy>();
129     test_make_any_type<large_throws_on_copy>();
130     test_make_any_type<throws_on_move>();
131     test_make_any_type_tracked<small_tracked_t>();
132     test_make_any_type_tracked<large_tracked_t>();
133 #ifndef TEST_HAS_NO_EXCEPTIONS
134     test_make_any_throws<SmallThrows>();
135     test_make_any_throws<LargeThrows>();
136 
137 #endif
138 
139   return 0;
140 }
141