libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

any_cast_reference.pass.cpp (10808B)


      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 // XFAIL: availability=macosx10.13
     13 // XFAIL: availability=macosx10.12
     14 // XFAIL: availability=macosx10.11
     15 // XFAIL: availability=macosx10.10
     16 // XFAIL: availability=macosx10.9
     17 // XFAIL: availability=macosx10.8
     18 // XFAIL: availability=macosx10.7
     19 
     20 // <any>
     21 
     22 // template <class ValueType>
     23 // ValueType const any_cast(any const&);
     24 //
     25 // template <class ValueType>
     26 // ValueType any_cast(any &);
     27 //
     28 // template <class ValueType>
     29 // ValueType any_cast(any &&);
     30 
     31 #include <any>
     32 #include <type_traits>
     33 #include <cassert>
     34 
     35 #include "any_helpers.h"
     36 #include "count_new.hpp"
     37 #include "test_macros.h"
     38 
     39 using std::any;
     40 using std::any_cast;
     41 using std::bad_any_cast;
     42 
     43 
     44 // Test that the operators are NOT marked noexcept.
     45 void test_cast_is_not_noexcept() {
     46     any a;
     47     static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
     48     static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
     49     static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
     50 }
     51 
     52 // Test that the return type of any_cast is correct.
     53 void test_cast_return_type() {
     54     any a;
     55     static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
     56     static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
     57     static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
     58     static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
     59 
     60     static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
     61     static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
     62 
     63     static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
     64     static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
     65     static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
     66     static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
     67 
     68     static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
     69     static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
     70 
     71     any const& ca = a;
     72     static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
     73     static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
     74     static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
     75 
     76     static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
     77 }
     78 
     79 template <class Type, class ConstT = Type>
     80 void checkThrows(any& a)
     81 {
     82 #if !defined(TEST_HAS_NO_EXCEPTIONS)
     83     try {
     84         TEST_IGNORE_NODISCARD any_cast<Type>(a);
     85         assert(false);
     86     } catch (bad_any_cast const &) {
     87             // do nothing
     88     } catch (...) {
     89         assert(false);
     90     }
     91 
     92     try {
     93         TEST_IGNORE_NODISCARD any_cast<ConstT>(static_cast<any const&>(a));
     94         assert(false);
     95     } catch (bad_any_cast const &) {
     96             // do nothing
     97     } catch (...) {
     98         assert(false);
     99     }
    100 
    101     try {
    102         using RefType = typename std::conditional<
    103             std::is_lvalue_reference<Type>::value,
    104             typename std::remove_reference<Type>::type&&,
    105             Type
    106         >::type;
    107         TEST_IGNORE_NODISCARD any_cast<RefType>(static_cast<any&&>(a));
    108         assert(false);
    109     } catch (bad_any_cast const &) {
    110             // do nothing
    111     } catch (...) {
    112         assert(false);
    113     }
    114 #else
    115     (TEST_IGNORE_NODISCARD a);
    116 #endif
    117 }
    118 
    119 void test_cast_empty() {
    120     // None of these operations should allocate.
    121     DisableAllocationGuard g; (TEST_IGNORE_NODISCARD g);
    122     any a;
    123     checkThrows<int>(a);
    124 }
    125 
    126 template <class Type>
    127 void test_cast_to_reference() {
    128     assert(Type::count == 0);
    129     Type::reset();
    130     {
    131         any a((Type(42)));
    132         any const& ca = a;
    133         assert(Type::count == 1);
    134         assert(Type::copied == 0);
    135         assert(Type::moved == 1);
    136 
    137         // Try a cast to a bad type.
    138         // NOTE: Type cannot be an int.
    139         checkThrows<int>(a);
    140         checkThrows<int&, int const&>(a);
    141         checkThrows<Type*, Type const*>(a);
    142         checkThrows<Type const*>(a);
    143 
    144         // Check getting a type by reference from a non-const lvalue any.
    145         {
    146             Type& v = any_cast<Type&>(a);
    147             assert(v.value == 42);
    148 
    149             Type const &cv = any_cast<Type const&>(a);
    150             assert(&cv == &v);
    151         }
    152         // Check getting a type by reference from a const lvalue any.
    153         {
    154             Type const& v = any_cast<Type const&>(ca);
    155             assert(v.value == 42);
    156 
    157             Type const &cv = any_cast<Type const&>(ca);
    158             assert(&cv == &v);
    159         }
    160         // Check getting a type by reference from a const rvalue any.
    161         {
    162             Type const& v = any_cast<Type const&>(std::move(ca));
    163             assert(v.value == 42);
    164 
    165             Type const &cv = any_cast<Type const&>(std::move(ca));
    166             assert(&cv == &v);
    167         }
    168         // Check getting a type by reference from a const rvalue any.
    169         {
    170             Type&& v = any_cast<Type&&>(std::move(a));
    171             assert(v.value == 42);
    172             assert(any_cast<Type&>(a).value == 42);
    173 
    174             Type&& cv = any_cast<Type&&>(std::move(a));
    175             assert(&cv == &v);
    176             assert(any_cast<Type&>(a).value == 42);
    177         }
    178         // Check getting a type by reference from a const rvalue any.
    179         {
    180             Type const&& v = any_cast<Type const&&>(std::move(a));
    181             assert(v.value == 42);
    182             assert(any_cast<Type&>(a).value == 42);
    183 
    184             Type const&& cv = any_cast<Type const&&>(std::move(a));
    185             assert(&cv == &v);
    186             assert(any_cast<Type&>(a).value == 42);
    187         }
    188         // Check that the original object hasn't been changed.
    189         assertContains<Type>(a, 42);
    190 
    191         // Check that no objects have been created/copied/moved.
    192         assert(Type::count == 1);
    193         assert(Type::copied == 0);
    194         assert(Type::moved == 1);
    195     }
    196     assert(Type::count == 0);
    197 }
    198 
    199 template <class Type>
    200 void test_cast_to_value() {
    201     assert(Type::count == 0);
    202     Type::reset();
    203     {
    204         any a((Type(42)));
    205         assert(Type::count == 1);
    206         assert(Type::copied == 0);
    207         assert(Type::moved == 1);
    208 
    209         // Try a cast to a bad type.
    210         // NOTE: Type cannot be an int.
    211         checkThrows<int>(a);
    212         checkThrows<int&, int const&>(a);
    213         checkThrows<Type*, Type const*>(a);
    214         checkThrows<Type const*>(a);
    215 
    216         Type::reset(); // NOTE: reset does not modify Type::count
    217         // Check getting Type by value from a non-const lvalue any.
    218         // This should cause the non-const copy constructor to be called.
    219         {
    220             Type t = any_cast<Type>(a);
    221 
    222             assert(Type::count == 2);
    223             assert(Type::copied == 1);
    224             assert(Type::const_copied == 0);
    225             assert(Type::non_const_copied == 1);
    226             assert(Type::moved == 0);
    227             assert(t.value == 42);
    228         }
    229         assert(Type::count == 1);
    230         Type::reset();
    231         // Check getting const Type by value from a non-const lvalue any.
    232         // This should cause the const copy constructor to be called.
    233         {
    234             Type t = any_cast<Type const>(a);
    235 
    236             assert(Type::count == 2);
    237             assert(Type::copied == 1);
    238             assert(Type::const_copied == 0);
    239             assert(Type::non_const_copied == 1);
    240             assert(Type::moved == 0);
    241             assert(t.value == 42);
    242         }
    243         assert(Type::count == 1);
    244         Type::reset();
    245         // Check getting Type by value from a non-const lvalue any.
    246         // This should cause the const copy constructor to be called.
    247         {
    248             Type t = any_cast<Type>(static_cast<any const&>(a));
    249 
    250             assert(Type::count == 2);
    251             assert(Type::copied == 1);
    252             assert(Type::const_copied == 1);
    253             assert(Type::non_const_copied == 0);
    254             assert(Type::moved == 0);
    255             assert(t.value == 42);
    256         }
    257         assert(Type::count == 1);
    258         Type::reset();
    259         // Check getting Type by value from a non-const rvalue any.
    260         // This should cause the non-const copy constructor to be called.
    261         {
    262             Type t = any_cast<Type>(static_cast<any &&>(a));
    263 
    264             assert(Type::count == 2);
    265             assert(Type::moved == 1);
    266             assert(Type::copied == 0);
    267             assert(Type::const_copied == 0);
    268             assert(Type::non_const_copied == 0);
    269             assert(t.value == 42);
    270             assert(any_cast<Type&>(a).value == 0);
    271             any_cast<Type&>(a).value = 42; // reset the value
    272         }
    273         assert(Type::count == 1);
    274         Type::reset();
    275         // Check getting const Type by value from a non-const rvalue any.
    276         // This should cause the const copy constructor to be called.
    277         {
    278             Type t = any_cast<Type const>(static_cast<any &&>(a));
    279 
    280             assert(Type::count == 2);
    281             assert(Type::copied == 0);
    282             assert(Type::const_copied == 0);
    283             assert(Type::non_const_copied == 0);
    284             assert(Type::moved == 1);
    285             assert(t.value == 42);
    286             assert(any_cast<Type&>(a).value == 0);
    287             any_cast<Type&>(a).value = 42; // reset the value
    288         }
    289         assert(Type::count == 1);
    290         Type::reset();
    291         // Check getting Type by value from a const rvalue any.
    292         // This should cause the const copy constructor to be called.
    293         {
    294             Type t = any_cast<Type>(static_cast<any const&&>(a));
    295 
    296             assert(Type::count == 2);
    297             assert(Type::copied == 1);
    298             assert(Type::const_copied == 1);
    299             assert(Type::non_const_copied == 0);
    300             assert(Type::moved == 0);
    301             assert(t.value == 42);
    302             assert(any_cast<Type&>(a).value == 42);
    303         }
    304         // Ensure we still only have 1 Type object alive.
    305         assert(Type::count == 1);
    306 
    307         // Check that the original object hasn't been changed.
    308         assertContains<Type>(a, 42);
    309     }
    310     assert(Type::count == 0);
    311 }
    312 
    313 int main() {
    314     test_cast_is_not_noexcept();
    315     test_cast_return_type();
    316     test_cast_empty();
    317     test_cast_to_reference<small>();
    318     test_cast_to_reference<large>();
    319     test_cast_to_value<small>();
    320     test_cast_to_value<large>();
    321 }