Home | History | Annotate | Download | only in any.cast
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14
     11 
     12 // <any>
     13 
     14 // template <class ValueType>
     15 // ValueType const* any_cast(any const *) noexcept;
     16 //
     17 // template <class ValueType>
     18 // ValueType * any_cast(any *) noexcept;
     19 
     20 #include <any>
     21 #include <type_traits>
     22 #include <cassert>
     23 
     24 #include "any_helpers.h"
     25 
     26 using std::any;
     27 using std::any_cast;
     28 
     29 // Test that the operators are properly noexcept.
     30 void test_cast_is_noexcept() {
     31     any a;
     32     static_assert(noexcept(any_cast<int>(&a)), "");
     33 
     34     any const& ca = a;
     35     static_assert(noexcept(any_cast<int>(&ca)), "");
     36 }
     37 
     38 // Test that the return type of any_cast is correct.
     39 void test_cast_return_type() {
     40     any a;
     41     static_assert(std::is_same<decltype(any_cast<int>(&a)), int*>::value, "");
     42     static_assert(std::is_same<decltype(any_cast<int const>(&a)), int const*>::value, "");
     43 
     44     any const& ca = a;
     45     static_assert(std::is_same<decltype(any_cast<int>(&ca)), int const*>::value, "");
     46     static_assert(std::is_same<decltype(any_cast<int const>(&ca)), int const*>::value, "");
     47 }
     48 
     49 // Test that any_cast handles null pointers.
     50 void test_cast_nullptr() {
     51     any* a = nullptr;
     52     assert(nullptr == any_cast<int>(a));
     53     assert(nullptr == any_cast<int const>(a));
     54 
     55     any const* ca = nullptr;
     56     assert(nullptr == any_cast<int>(ca));
     57     assert(nullptr == any_cast<int const>(ca));
     58 }
     59 
     60 // Test casting an empty object.
     61 void test_cast_empty() {
     62     {
     63         any a;
     64         assert(nullptr == any_cast<int>(&a));
     65         assert(nullptr == any_cast<int const>(&a));
     66 
     67         any const& ca = a;
     68         assert(nullptr == any_cast<int>(&ca));
     69         assert(nullptr == any_cast<int const>(&ca));
     70     }
     71     // Create as non-empty, then make empty and run test.
     72     {
     73         any a(42);
     74         a.reset();
     75         assert(nullptr == any_cast<int>(&a));
     76         assert(nullptr == any_cast<int const>(&a));
     77 
     78         any const& ca = a;
     79         assert(nullptr == any_cast<int>(&ca));
     80         assert(nullptr == any_cast<int const>(&ca));
     81     }
     82 }
     83 
     84 template <class Type>
     85 void test_cast() {
     86     assert(Type::count == 0);
     87     Type::reset();
     88     {
     89         any a((Type(42)));
     90         any const& ca = a;
     91         assert(Type::count == 1);
     92         assert(Type::copied == 0);
     93         assert(Type::moved == 1);
     94 
     95         // Try a cast to a bad type.
     96         // NOTE: Type cannot be an int.
     97         assert(any_cast<int>(&a) == nullptr);
     98         assert(any_cast<int const>(&a) == nullptr);
     99         assert(any_cast<int const volatile>(&a) == nullptr);
    100 
    101         // Try a cast to the right type, but as a pointer.
    102         assert(any_cast<Type*>(&a) == nullptr);
    103         assert(any_cast<Type const*>(&a) == nullptr);
    104 
    105         // Check getting a unqualified type from a non-const any.
    106         Type* v = any_cast<Type>(&a);
    107         assert(v != nullptr);
    108         assert(v->value == 42);
    109 
    110         // change the stored value and later check for the new value.
    111         v->value = 999;
    112 
    113         // Check getting a const qualified type from a non-const any.
    114         Type const* cv = any_cast<Type const>(&a);
    115         assert(cv != nullptr);
    116         assert(cv == v);
    117         assert(cv->value == 999);
    118 
    119         // Check getting a unqualified type from a const any.
    120         cv = any_cast<Type>(&ca);
    121         assert(cv != nullptr);
    122         assert(cv == v);
    123         assert(cv->value == 999);
    124 
    125         // Check getting a const-qualified type from a const any.
    126         cv = any_cast<Type const>(&ca);
    127         assert(cv != nullptr);
    128         assert(cv == v);
    129         assert(cv->value == 999);
    130 
    131         // Check that no more objects were created, copied or moved.
    132         assert(Type::count == 1);
    133         assert(Type::copied == 0);
    134         assert(Type::moved == 1);
    135     }
    136     assert(Type::count == 0);
    137 }
    138 
    139 void test_cast_non_copyable_type()
    140 {
    141     // Even though 'any' never stores non-copyable types
    142     // we still need to support any_cast<NoCopy>(ptr)
    143     struct NoCopy { NoCopy(NoCopy const&) = delete; };
    144     std::any a(42);
    145     std::any const& ca = a;
    146     assert(std::any_cast<NoCopy>(&a) == nullptr);
    147     assert(std::any_cast<NoCopy>(&ca) == nullptr);
    148 }
    149 
    150 void test_fn() {}
    151 
    152 void test_cast_function_pointer() {
    153     using T = void(*)();
    154     std::any a(test_fn);
    155     // An any can never store a function type, but we should at least be able
    156     // to ask.
    157     assert(std::any_cast<void()>(&a) == nullptr);
    158     T fn_ptr = std::any_cast<T>(a);
    159     assert(fn_ptr == test_fn);
    160 }
    161 
    162 int main() {
    163     test_cast_is_noexcept();
    164     test_cast_return_type();
    165     test_cast_nullptr();
    166     test_cast_empty();
    167     test_cast<small>();
    168     test_cast<large>();
    169     test_cast_non_copyable_type();
    170     test_cast_function_pointer();
    171 }
    172