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.
27void test_cast_is_noexcept() {
28 std::any a;
29 ASSERT_NOEXCEPT(std::any_cast<int>(any: &a));
30
31 const std::any& ca = a;
32 ASSERT_NOEXCEPT(std::any_cast<int>(any: &ca));
33}
34
35// Test that the return type of any_cast is correct.
36void 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.
47void 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.
58void 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
81template <class Type>
82void 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
136void 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
147void 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]>(any: &a);
153 assert(p == nullptr);
154}
155
156void test_fn() {}
157
158void 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>(any&: a);
165 assert(fn_ptr == test_fn);
166}
167
168int 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

source code of libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp