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