#include <any>
#include <type_traits>
#include <cassert>
#include "test_macros.h"
#include "any_helpers.h"
void test_cast_is_noexcept() {
std::any a;
ASSERT_NOEXCEPT(std::any_cast<int>(&a));
const std::any& ca = a;
ASSERT_NOEXCEPT(std::any_cast<int>(&ca));
}
void test_cast_return_type() {
std::any a;
ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&a)), int*);
ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&a)), int const*);
const std::any& ca = a;
ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&ca)), int const*);
ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&ca)), int const*);
}
void test_cast_nullptr() {
std::any *a = nullptr;
assert(nullptr == std::any_cast<int>(a));
assert(nullptr == std::any_cast<int const>(a));
const std::any *ca = nullptr;
assert(nullptr == std::any_cast<int>(ca));
assert(nullptr == std::any_cast<int const>(ca));
}
void test_cast_empty() {
{
std::any a;
assert(nullptr == std::any_cast<int>(&a));
assert(nullptr == std::any_cast<int const>(&a));
const std::any& ca = a;
assert(nullptr == std::any_cast<int>(&ca));
assert(nullptr == std::any_cast<int const>(&ca));
}
{
std::any a(42);
a.reset();
assert(nullptr == std::any_cast<int>(&a));
assert(nullptr == std::any_cast<int const>(&a));
const std::any& ca = a;
assert(nullptr == std::any_cast<int>(&ca));
assert(nullptr == std::any_cast<int const>(&ca));
}
}
template <class Type>
void test_cast() {
assert(Type::count == 0);
Type::reset();
{
std::any a = Type(42);
const std::any& ca = a;
assert(Type::count == 1);
assert(Type::copied == 0);
assert(Type::moved == 1);
assert(std::any_cast<int>(&a) == nullptr);
assert(std::any_cast<int const>(&a) == nullptr);
assert(std::any_cast<int const volatile>(&a) == nullptr);
assert(std::any_cast<Type*>(&a) == nullptr);
assert(std::any_cast<Type const*>(&a) == nullptr);
Type* v = std::any_cast<Type>(&a);
assert(v != nullptr);
assert(v->value == 42);
v->value = 999;
Type const* cv = std::any_cast<Type const>(&a);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);
cv = std::any_cast<Type>(&ca);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);
cv = std::any_cast<Type const>(&ca);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);
assert(Type::count == 1);
assert(Type::copied == 0);
assert(Type::moved == 1);
}
assert(Type::count == 0);
}
void test_cast_non_copyable_type()
{
struct NoCopy { NoCopy(NoCopy const&) = delete; };
std::any a(42);
std::any const& ca = a;
assert(std::any_cast<NoCopy>(&a) == nullptr);
assert(std::any_cast<NoCopy>(&ca) == nullptr);
}
void test_cast_array() {
int arr[3];
std::any a(arr);
RTTI_ASSERT(a.type() == typeid(int*));
int (*p)[3] = std::any_cast<int[3]>(&a);
assert(p == nullptr);
}
void test_fn() {}
void test_cast_function_pointer() {
using T = void(*)();
std::any a(test_fn);
assert(std::any_cast<void()>(&a) == nullptr);
T fn_ptr = std::any_cast<T>(a);
assert(fn_ptr == test_fn);
}
int main(int, char**) {
test_cast_is_noexcept();
test_cast_return_type();
test_cast_nullptr();
test_cast_empty();
test_cast<small>();
test_cast<large>();
test_cast_non_copyable_type();
test_cast_array();
test_cast_function_pointer();
return 0;
}