//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 // XFAIL: availability=macosx10.13 // XFAIL: availability=macosx10.12 // XFAIL: availability=macosx10.11 // XFAIL: availability=macosx10.10 // XFAIL: availability=macosx10.9 // XFAIL: availability=macosx10.8 // XFAIL: availability=macosx10.7 // // template // ValueType const* any_cast(any const *) noexcept; // // template // ValueType * any_cast(any *) noexcept; #include #include #include #include "any_helpers.h" using std::any; using std::any_cast; // Test that the operators are properly noexcept. void test_cast_is_noexcept() { any a; static_assert(noexcept(any_cast(&a)), ""); any const& ca = a; static_assert(noexcept(any_cast(&ca)), ""); } // Test that the return type of any_cast is correct. void test_cast_return_type() { any a; static_assert(std::is_same(&a)), int*>::value, ""); static_assert(std::is_same(&a)), int const*>::value, ""); any const& ca = a; static_assert(std::is_same(&ca)), int const*>::value, ""); static_assert(std::is_same(&ca)), int const*>::value, ""); } // Test that any_cast handles null pointers. void test_cast_nullptr() { any* a = nullptr; assert(nullptr == any_cast(a)); assert(nullptr == any_cast(a)); any const* ca = nullptr; assert(nullptr == any_cast(ca)); assert(nullptr == any_cast(ca)); } // Test casting an empty object. void test_cast_empty() { { any a; assert(nullptr == any_cast(&a)); assert(nullptr == any_cast(&a)); any const& ca = a; assert(nullptr == any_cast(&ca)); assert(nullptr == any_cast(&ca)); } // Create as non-empty, then make empty and run test. { any a(42); a.reset(); assert(nullptr == any_cast(&a)); assert(nullptr == any_cast(&a)); any const& ca = a; assert(nullptr == any_cast(&ca)); assert(nullptr == any_cast(&ca)); } } template void test_cast() { assert(Type::count == 0); Type::reset(); { any a((Type(42))); any const& ca = a; assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 1); // Try a cast to a bad type. // NOTE: Type cannot be an int. assert(any_cast(&a) == nullptr); assert(any_cast(&a) == nullptr); assert(any_cast(&a) == nullptr); // Try a cast to the right type, but as a pointer. assert(any_cast(&a) == nullptr); assert(any_cast(&a) == nullptr); // Check getting a unqualified type from a non-const any. Type* v = any_cast(&a); assert(v != nullptr); assert(v->value == 42); // change the stored value and later check for the new value. v->value = 999; // Check getting a const qualified type from a non-const any. Type const* cv = any_cast(&a); assert(cv != nullptr); assert(cv == v); assert(cv->value == 999); // Check getting a unqualified type from a const any. cv = any_cast(&ca); assert(cv != nullptr); assert(cv == v); assert(cv->value == 999); // Check getting a const-qualified type from a const any. cv = any_cast(&ca); assert(cv != nullptr); assert(cv == v); assert(cv->value == 999); // Check that no more objects were created, copied or moved. assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 1); } assert(Type::count == 0); } void test_cast_non_copyable_type() { // Even though 'any' never stores non-copyable types // we still need to support any_cast(ptr) struct NoCopy { NoCopy(NoCopy const&) = delete; }; std::any a(42); std::any const& ca = a; assert(std::any_cast(&a) == nullptr); assert(std::any_cast(&ca) == nullptr); } void test_fn() {} void test_cast_function_pointer() { using T = void(*)(); std::any a(test_fn); // An any can never store a function type, but we should at least be able // to ask. assert(std::any_cast(&a) == nullptr); T fn_ptr = std::any_cast(a); assert(fn_ptr == test_fn); } int main() { test_cast_is_noexcept(); test_cast_return_type(); test_cast_nullptr(); test_cast_empty(); test_cast(); test_cast(); test_cast_non_copyable_type(); test_cast_function_pointer(); }