Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,156 +25,157 @@

// Test that the operators are properly noexcept.
void test_cast_is_noexcept() {
std::any a;
ASSERT_NOEXCEPT(std::any_cast<int>(&a));
std::any a;
ASSERT_NOEXCEPT(std::any_cast<int>(&a));

const std::any& ca = a;
ASSERT_NOEXCEPT(std::any_cast<int>(&ca));
const std::any& ca = a;
ASSERT_NOEXCEPT(std::any_cast<int>(&ca));
}

// Test that the return type of any_cast is correct.
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*);
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*);
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*);
}

// Test that any_cast handles null pointers.
void test_cast_nullptr() {
std::any *a = nullptr;
assert(nullptr == std::any_cast<int>(a));
assert(nullptr == std::any_cast<int const>(a));
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));
const std::any* ca = nullptr;
assert(nullptr == std::any_cast<int>(ca));
assert(nullptr == std::any_cast<int const>(ca));
}

// Test casting an empty object.
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));
}
// Create as non-empty, then make empty and run test.
{
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));
}
{
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));
}
// Create as non-empty, then make empty and run test.
{
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);

// Try a cast to a bad type.
// NOTE: Type cannot be an int.
assert(std::any_cast<int>(&a) == nullptr);
assert(std::any_cast<int const>(&a) == nullptr);
assert(std::any_cast<int const volatile>(&a) == nullptr);

// Try a cast to the right type, but as a pointer.
assert(std::any_cast<Type*>(&a) == nullptr);
assert(std::any_cast<Type const*>(&a) == nullptr);

// Check getting a unqualified type from a non-const any.
Type* v = std::any_cast<Type>(&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 = std::any_cast<Type const>(&a);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);

// Check getting a unqualified type from a const any.
cv = std::any_cast<Type>(&ca);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);

// Check getting a const-qualified type from a const any.
cv = std::any_cast<Type const>(&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);
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);

// Try a cast to a bad type.
// NOTE: Type cannot be an int.
assert(std::any_cast<int>(&a) == nullptr);
assert(std::any_cast<int const>(&a) == nullptr);
assert(std::any_cast<int const volatile>(&a) == nullptr);

// Try a cast to the right type, but as a pointer.
assert(std::any_cast<Type*>(&a) == nullptr);
assert(std::any_cast<Type const*>(&a) == nullptr);

// Check getting a unqualified type from a non-const any.
Type* v = std::any_cast<Type>(&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 = std::any_cast<Type const>(&a);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);

// Check getting a unqualified type from a const any.
cv = std::any_cast<Type>(&ca);
assert(cv != nullptr);
assert(cv == v);
assert(cv->value == 999);

// Check getting a const-qualified type from a const any.
cv = std::any_cast<Type const>(&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<NoCopy>(ptr)
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_non_copyable_type() {
// Even though 'any' never stores non-copyable types
// we still need to support any_cast<NoCopy>(ptr)
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*)); // contained value is decayed
// We can't get an array out
int (*p)[3] = std::any_cast<int[3]>(&a);
assert(p == nullptr);
int arr[3];
std::any a(arr);
RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed
// We can't get an array out
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);
// An any can never store a function type, but we should at least be able
// to ask.
assert(std::any_cast<void()>(&a) == nullptr);
T fn_ptr = std::any_cast<T>(a);
assert(fn_ptr == test_fn);
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<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();
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;
}
Loading
Loading