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, libcpp-no-rtti
10
11 // Throwing bad_any_cast is supported starting in macosx10.13
12 // XFAIL: with_system_cxx_lib=macosx10.12 && !no-exceptions
13 // XFAIL: with_system_cxx_lib=macosx10.11 && !no-exceptions
14 // XFAIL: with_system_cxx_lib=macosx10.10 && !no-exceptions
15 // XFAIL: with_system_cxx_lib=macosx10.9 && !no-exceptions
16
17 // <any>
18
19 // template <class ValueType>
20 // ValueType const* any_cast(any const *) noexcept;
21 //
22 // template <class ValueType>
23 // ValueType * any_cast(any *) noexcept;
24
25 #include <any>
26 #include <type_traits>
27 #include <cassert>
28
29 #include "test_macros.h"
30 #include "any_helpers.h"
31
32 using std::any;
33 using std::any_cast;
34
35 // Test that the operators are properly noexcept.
test_cast_is_noexcept()36 void test_cast_is_noexcept() {
37 any a;
38 ASSERT_NOEXCEPT(any_cast<int>(&a));
39
40 any const& ca = a;
41 ASSERT_NOEXCEPT(any_cast<int>(&ca));
42 }
43
44 // Test that the return type of any_cast is correct.
test_cast_return_type()45 void test_cast_return_type() {
46 any a;
47 ASSERT_SAME_TYPE(decltype(any_cast<int>(&a)), int*);
48 ASSERT_SAME_TYPE(decltype(any_cast<int const>(&a)), int const*);
49
50 any const& ca = a;
51 ASSERT_SAME_TYPE(decltype(any_cast<int>(&ca)), int const*);
52 ASSERT_SAME_TYPE(decltype(any_cast<int const>(&ca)), int const*);
53 }
54
55 // Test that any_cast handles null pointers.
test_cast_nullptr()56 void test_cast_nullptr() {
57 any* a = nullptr;
58 assert(nullptr == any_cast<int>(a));
59 assert(nullptr == any_cast<int const>(a));
60
61 any const* ca = nullptr;
62 assert(nullptr == any_cast<int>(ca));
63 assert(nullptr == any_cast<int const>(ca));
64 }
65
66 // Test casting an empty object.
test_cast_empty()67 void test_cast_empty() {
68 {
69 any a;
70 assert(nullptr == any_cast<int>(&a));
71 assert(nullptr == any_cast<int const>(&a));
72
73 any const& ca = a;
74 assert(nullptr == any_cast<int>(&ca));
75 assert(nullptr == any_cast<int const>(&ca));
76 }
77 // Create as non-empty, then make empty and run test.
78 {
79 any a(42);
80 a.reset();
81 assert(nullptr == any_cast<int>(&a));
82 assert(nullptr == any_cast<int const>(&a));
83
84 any const& ca = a;
85 assert(nullptr == any_cast<int>(&ca));
86 assert(nullptr == any_cast<int const>(&ca));
87 }
88 }
89
90 template <class Type>
test_cast()91 void test_cast() {
92 assert(Type::count == 0);
93 Type::reset();
94 {
95 any a((Type(42)));
96 any const& ca = a;
97 assert(Type::count == 1);
98 assert(Type::copied == 0);
99 assert(Type::moved == 1);
100
101 // Try a cast to a bad type.
102 // NOTE: Type cannot be an int.
103 assert(any_cast<int>(&a) == nullptr);
104 assert(any_cast<int const>(&a) == nullptr);
105 assert(any_cast<int const volatile>(&a) == nullptr);
106
107 // Try a cast to the right type, but as a pointer.
108 assert(any_cast<Type*>(&a) == nullptr);
109 assert(any_cast<Type const*>(&a) == nullptr);
110
111 // Check getting a unqualified type from a non-const any.
112 Type* v = any_cast<Type>(&a);
113 assert(v != nullptr);
114 assert(v->value == 42);
115
116 // change the stored value and later check for the new value.
117 v->value = 999;
118
119 // Check getting a const qualified type from a non-const any.
120 Type const* cv = any_cast<Type const>(&a);
121 assert(cv != nullptr);
122 assert(cv == v);
123 assert(cv->value == 999);
124
125 // Check getting a unqualified type from a const any.
126 cv = any_cast<Type>(&ca);
127 assert(cv != nullptr);
128 assert(cv == v);
129 assert(cv->value == 999);
130
131 // Check getting a const-qualified type from a const any.
132 cv = any_cast<Type const>(&ca);
133 assert(cv != nullptr);
134 assert(cv == v);
135 assert(cv->value == 999);
136
137 // Check that no more objects were created, copied or moved.
138 assert(Type::count == 1);
139 assert(Type::copied == 0);
140 assert(Type::moved == 1);
141 }
142 assert(Type::count == 0);
143 }
144
test_cast_non_copyable_type()145 void test_cast_non_copyable_type()
146 {
147 // Even though 'any' never stores non-copyable types
148 // we still need to support any_cast<NoCopy>(ptr)
149 struct NoCopy { NoCopy(NoCopy const&) = delete; };
150 std::any a(42);
151 std::any const& ca = a;
152 assert(std::any_cast<NoCopy>(&a) == nullptr);
153 assert(std::any_cast<NoCopy>(&ca) == nullptr);
154 }
155
test_cast_array()156 void test_cast_array() {
157 int arr[3];
158 std::any a(arr);
159 assert(a.type() == typeid(int*)); // contained value is decayed
160 // We can't get an array out
161 int (*p)[3] = std::any_cast<int[3]>(&a);
162 assert(p == nullptr);
163 }
164
test_fn()165 void test_fn() {}
166
test_cast_function_pointer()167 void test_cast_function_pointer() {
168 using T = void(*)();
169 std::any a(test_fn);
170 // An any can never store a function type, but we should at least be able
171 // to ask.
172 assert(std::any_cast<void()>(&a) == nullptr);
173 T fn_ptr = std::any_cast<T>(a);
174 assert(fn_ptr == test_fn);
175 }
176
main(int,char **)177 int main(int, char**) {
178 test_cast_is_noexcept();
179 test_cast_return_type();
180 test_cast_nullptr();
181 test_cast_empty();
182 test_cast<small>();
183 test_cast<large>();
184 test_cast_non_copyable_type();
185 test_cast_array();
186 test_cast_function_pointer();
187
188 return 0;
189 }
190