182 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 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>(&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.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 // Even though 'any' never stores non-copyable types138 // we still need to support any_cast<NoCopy>(ptr)139 struct NoCopy {140 NoCopy(NoCopy const&) = delete;141 };142 std::any a(42);143 std::any const& ca = a;144 assert(std::any_cast<NoCopy>(&a) == nullptr);145 assert(std::any_cast<NoCopy>(&ca) == nullptr);146}147 148void test_cast_array() {149 int arr[3];150 std::any a(arr);151 RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed152 // We can't get an array out153 int (*p)[3] = std::any_cast<int[3]>(&a);154 assert(p == 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 able163 // 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(int, char**) {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_array();178 test_cast_function_pointer();179 180 return 0;181}182