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