1e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//===----------------------------------------------------------------------===//
2e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//
3e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//                     The LLVM Compiler Infrastructure
4e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//
5e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
6e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// Source Licenses. See LICENSE.TXT for details.
7e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//
8e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//===----------------------------------------------------------------------===//
9e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
10e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14
11e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
12e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// <any>
13e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
14e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// template <class ValueType>
15e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// ValueType const any_cast(any const&);
16e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//
17e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// template <class ValueType>
18e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// ValueType any_cast(any &);
19e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier//
20e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// template <class ValueType>
21e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// ValueType any_cast(any &&);
22e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
23e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include <any>
24e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include <type_traits>
25e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include <cassert>
26e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
27e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include "any_helpers.h"
28e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include "count_new.hpp"
29e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include "test_macros.h"
30e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
31e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselierusing std::any;
32e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselierusing std::any_cast;
33e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselierusing std::bad_any_cast;
34e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
35e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
36e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// Test that the operators are NOT marked noexcept.
37e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid test_cast_is_not_noexcept() {
38e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    any a;
39e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
40e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
41e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
42e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
43e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
44e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier// Test that the return type of any_cast is correct.
45e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid test_cast_return_type() {
46e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    any a;
47e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
48e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
49e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
50e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
51e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
52e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
53e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
54e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
55e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
56e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
57e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
58e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
59e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
60e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
61e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
62e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
63e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    any const& ca = a;
64e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
65e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
66e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
67e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
68e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
69e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
70e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
71e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliertemplate <class Type, class ConstT = Type>
72e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid checkThrows(any& a)
73e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier{
74e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#if !defined(TEST_HAS_NO_EXCEPTIONS)
75e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    try {
76e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        any_cast<Type>(a);
77e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
78e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (bad_any_cast const &) {
79e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            // do nothing
80e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (...) {
81e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
82e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    }
83e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
84e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    try {
85e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        any_cast<ConstT>(static_cast<any const&>(a));
86e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
87e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (bad_any_cast const &) {
88e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            // do nothing
89e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (...) {
90e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
91e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    }
92e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
93e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    try {
942c429bee79204b77cff067695798dfac5605820dEric Fiselier        using RefType = typename std::conditional<
952c429bee79204b77cff067695798dfac5605820dEric Fiselier            std::is_lvalue_reference<Type>::value,
962c429bee79204b77cff067695798dfac5605820dEric Fiselier            typename std::remove_reference<Type>::type&&,
972c429bee79204b77cff067695798dfac5605820dEric Fiselier            Type
982c429bee79204b77cff067695798dfac5605820dEric Fiselier        >::type;
992c429bee79204b77cff067695798dfac5605820dEric Fiselier        any_cast<RefType>(static_cast<any&&>(a));
100e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
101e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (bad_any_cast const &) {
102e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            // do nothing
103e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    } catch (...) {
104e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(false);
105e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    }
1060e5ebbc77c3c2cfd7d835fcfe40fcb65df0c5598Eric Fiselier#else
1070e5ebbc77c3c2cfd7d835fcfe40fcb65df0c5598Eric Fiselier    ((void)a);
108e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#endif
109e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
110e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
111e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid test_cast_empty() {
112e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    // None of these operations should allocate.
113e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    DisableAllocationGuard g; ((void)g);
114e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    any a;
115e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    checkThrows<int>(a);
116e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
117e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
118e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliertemplate <class Type>
119e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid test_cast_to_reference() {
120e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    assert(Type::count == 0);
121e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    Type::reset();
122e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    {
123e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        any a((Type(42)));
124e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        any const& ca = a;
125e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
126e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::copied == 0);
127e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::moved == 1);
128e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
129e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Try a cast to a bad type.
130e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // NOTE: Type cannot be an int.
131e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<int>(a);
132e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<int&, int const&>(a);
133e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<Type*, Type const*>(a);
134e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<Type const*>(a);
135e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
136e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting a type by reference from a non-const lvalue any.
137e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
138e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type& v = any_cast<Type&>(a);
139e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(v.value == 42);
140e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
141e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const &cv = any_cast<Type const&>(a);
142e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(&cv == &v);
143e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
144e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting a type by reference from a const lvalue any.
145e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
146e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const& v = any_cast<Type const&>(ca);
147e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(v.value == 42);
148e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
149e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const &cv = any_cast<Type const&>(ca);
150e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(&cv == &v);
151e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
152e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting a type by reference from a const rvalue any.
153e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
154e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const& v = any_cast<Type const&>(std::move(ca));
155e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(v.value == 42);
156e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
157e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const &cv = any_cast<Type const&>(std::move(ca));
158e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(&cv == &v);
159e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
160e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting a type by reference from a const rvalue any.
161e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
162e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type&& v = any_cast<Type&&>(std::move(a));
163e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(v.value == 42);
164e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 42);
165e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
166e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type&& cv = any_cast<Type&&>(std::move(a));
167e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(&cv == &v);
168e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 42);
169e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
170e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting a type by reference from a const rvalue any.
171e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
172e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const&& v = any_cast<Type const&&>(std::move(a));
173e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(v.value == 42);
174e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 42);
175e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
176e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type const&& cv = any_cast<Type const&&>(std::move(a));
177e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(&cv == &v);
178e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 42);
179e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
180e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check that the original object hasn't been changed.
181e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assertContains<Type>(a, 42);
182e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
183e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check that no objects have been created/copied/moved.
184e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
185e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::copied == 0);
186e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::moved == 1);
187e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    }
188e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    assert(Type::count == 0);
189e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
190e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
191e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliertemplate <class Type>
192e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiseliervoid test_cast_to_value() {
193e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    assert(Type::count == 0);
194e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    Type::reset();
195e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    {
196e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        any a((Type(42)));
197e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
198e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::copied == 0);
199e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::moved == 1);
200e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
201e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Try a cast to a bad type.
202e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // NOTE: Type cannot be an int.
203e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<int>(a);
204e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<int&, int const&>(a);
205e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<Type*, Type const*>(a);
206e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        checkThrows<Type const*>(a);
207e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
208e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset(); // NOTE: reset does not modify Type::count
209e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting Type by value from a non-const lvalue any.
210e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the non-const copy constructor to be called.
211e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
212e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type>(a);
213e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
214e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
215e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::copied == 1);
216e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::const_copied == 0);
217e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::non_const_copied == 1);
218e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::moved == 0);
219e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
220e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
221e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
222e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset();
223e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting const Type by value from a non-const lvalue any.
224e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the const copy constructor to be called.
225e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
226e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type const>(a);
227e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
228e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
229e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::copied == 1);
2302c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(Type::const_copied == 0);
2312c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(Type::non_const_copied == 1);
232e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::moved == 0);
233e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
234e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
235e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
236e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset();
237e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting Type by value from a non-const lvalue any.
238e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the const copy constructor to be called.
239e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
240e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type>(static_cast<any const&>(a));
241e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
242e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
243e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::copied == 1);
244e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::const_copied == 1);
245e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::non_const_copied == 0);
246e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::moved == 0);
247e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
248e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
249e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
250e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset();
251e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting Type by value from a non-const rvalue any.
252e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the non-const copy constructor to be called.
253e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
254e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type>(static_cast<any &&>(a));
255e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
256e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
257e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::moved == 1);
258e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::copied == 0);
259e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::const_copied == 0);
260e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::non_const_copied == 0);
261e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
262e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 0);
263e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            any_cast<Type&>(a).value = 42; // reset the value
264e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
265e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
266e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset();
267e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting const Type by value from a non-const rvalue any.
268e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the const copy constructor to be called.
269e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
270e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type const>(static_cast<any &&>(a));
271e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
272e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
2732c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(Type::copied == 0);
2742c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(Type::const_copied == 0);
275e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::non_const_copied == 0);
2762c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(Type::moved == 1);
277e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
2782c429bee79204b77cff067695798dfac5605820dEric Fiselier            assert(any_cast<Type&>(a).value == 0);
2792c429bee79204b77cff067695798dfac5605820dEric Fiselier            any_cast<Type&>(a).value = 42; // reset the value
280e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
281e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
282e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        Type::reset();
283e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check getting Type by value from a const rvalue any.
284e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // This should cause the const copy constructor to be called.
285e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        {
286e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            Type t = any_cast<Type>(static_cast<any const&&>(a));
287e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
288e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::count == 2);
289e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::copied == 1);
290e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::const_copied == 1);
291e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::non_const_copied == 0);
292e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(Type::moved == 0);
293e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(t.value == 42);
294e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier            assert(any_cast<Type&>(a).value == 42);
295e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        }
296e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Ensure we still only have 1 Type object alive.
297e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assert(Type::count == 1);
298e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
299e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        // Check that the original object hasn't been changed.
300e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier        assertContains<Type>(a, 42);
301e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    }
302e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    assert(Type::count == 0);
303e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
304e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier
305e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselierint main() {
306e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_is_not_noexcept();
307e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_return_type();
308e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_empty();
309e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_to_reference<small>();
310e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_to_reference<large>();
311e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_to_value<small>();
312e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier    test_cast_to_value<large>();
313e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier}
314