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