libcxx

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

value.pass.cpp (4250B)


      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 Value> any(Value &&)
     23 
     24 // Test construction from a value.
     25 // Concerns:
     26 // ---------
     27 // 1. The value is properly move/copied depending on the value category.
     28 // 2. Both small and large values are properly handled.
     29 
     30 
     31 #include <any>
     32 #include <cassert>
     33 
     34 #include "any_helpers.h"
     35 #include "count_new.hpp"
     36 #include "test_macros.h"
     37 
     38 using std::any;
     39 using std::any_cast;
     40 
     41 template <class Type>
     42 void test_copy_value_throws()
     43 {
     44 #if !defined(TEST_HAS_NO_EXCEPTIONS)
     45     assert(Type::count == 0);
     46     {
     47         Type const t(42);
     48         assert(Type::count == 1);
     49         try {
     50             any const a2(t);
     51             assert(false);
     52         } catch (my_any_exception const &) {
     53             // do nothing
     54         } catch (...) {
     55             assert(false);
     56         }
     57         assert(Type::count == 1);
     58         assert(t.value == 42);
     59     }
     60     assert(Type::count == 0);
     61 #endif
     62 }
     63 
     64 void test_move_value_throws()
     65 {
     66 #if !defined(TEST_HAS_NO_EXCEPTIONS)
     67     assert(throws_on_move::count == 0);
     68     {
     69         throws_on_move v;
     70         assert(throws_on_move::count == 1);
     71         try {
     72             any const a(std::move(v));
     73             assert(false);
     74         } catch (my_any_exception const &) {
     75             // do nothing
     76         } catch (...) {
     77             assert(false);
     78         }
     79         assert(throws_on_move::count == 1);
     80     }
     81     assert(throws_on_move::count == 0);
     82 #endif
     83 }
     84 
     85 template <class Type>
     86 void test_copy_move_value() {
     87     // constructing from a small type should perform no allocations.
     88     DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
     89     assert(Type::count == 0);
     90     Type::reset();
     91     {
     92         Type t(42);
     93         assert(Type::count == 1);
     94 
     95         any a(t);
     96 
     97         assert(Type::count == 2);
     98         assert(Type::copied == 1);
     99         assert(Type::moved == 0);
    100         assertContains<Type>(a, 42);
    101     }
    102     assert(Type::count == 0);
    103     Type::reset();
    104     {
    105         Type t(42);
    106         assert(Type::count == 1);
    107 
    108         any a(std::move(t));
    109 
    110         assert(Type::count == 2);
    111         assert(Type::copied == 0);
    112         assert(Type::moved == 1);
    113         assertContains<Type>(a, 42);
    114     }
    115 }
    116 
    117 // Test that any(ValueType&&) is *never* selected for a std::in_place_type_t specialization.
    118 void test_sfinae_constraints() {
    119     using BadTag = std::in_place_type_t<int>;
    120     using OKTag = std::in_place_t;
    121     // Test that the tag type is properly handled in SFINAE
    122     BadTag t = std::in_place_type<int>;
    123     OKTag ot = std::in_place;
    124     {
    125         std::any a(t);
    126         assertContains<int>(a, 0);
    127     }
    128     {
    129         std::any a(std::move(t));
    130         assertContains<int>(a, 0);
    131     }
    132     {
    133         std::any a(ot);
    134         assert(containsType<OKTag>(a));
    135     }
    136     {
    137         struct Dummy { Dummy() = delete; };
    138         using T = std::in_place_type_t<Dummy>;
    139         static_assert(!std::is_constructible<std::any, T>::value, "");
    140     }
    141     {
    142         // Test that the ValueType&& constructor SFINAE's away when the
    143         // argument is non-copyable
    144         struct NoCopy {
    145           NoCopy() = default;
    146           NoCopy(NoCopy const&) = delete;
    147           NoCopy(int) {}
    148         };
    149         static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
    150         static_assert(!std::is_constructible<std::any, NoCopy&>::value, "");
    151         static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
    152     }
    153 }
    154 
    155 int main() {
    156     test_copy_move_value<small>();
    157     test_copy_move_value<large>();
    158     test_copy_value_throws<small_throws_on_copy>();
    159     test_copy_value_throws<large_throws_on_copy>();
    160     test_move_value_throws();
    161     test_sfinae_constraints();
    162 }