libcxx

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

value.pass.cpp (5400B)


      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 // any& operator=(ValueType&&);
     24 
     25 // Test value copy and move assignment.
     26 
     27 #include <any>
     28 #include <cassert>
     29 
     30 #include "any_helpers.h"
     31 #include "count_new.hpp"
     32 #include "test_macros.h"
     33 
     34 using std::any;
     35 using std::any_cast;
     36 
     37 template <class LHS, class RHS>
     38 void test_assign_value() {
     39     assert(LHS::count == 0);
     40     assert(RHS::count == 0);
     41     LHS::reset();
     42     RHS::reset();
     43     {
     44         any lhs(LHS(1));
     45         any const rhs(RHS(2));
     46 
     47         assert(LHS::count == 1);
     48         assert(RHS::count == 1);
     49         assert(RHS::copied == 0);
     50 
     51         lhs = rhs;
     52 
     53         assert(RHS::copied == 1);
     54         assert(LHS::count == 0);
     55         assert(RHS::count == 2);
     56 
     57         assertContains<RHS>(lhs, 2);
     58         assertContains<RHS>(rhs, 2);
     59     }
     60     assert(LHS::count == 0);
     61     assert(RHS::count == 0);
     62     LHS::reset();
     63     RHS::reset();
     64     {
     65         any lhs(LHS(1));
     66         any rhs(RHS(2));
     67 
     68         assert(LHS::count == 1);
     69         assert(RHS::count == 1);
     70         assert(RHS::moved == 1);
     71 
     72         lhs = std::move(rhs);
     73 
     74         assert(RHS::moved >= 1);
     75         assert(RHS::copied == 0);
     76         assert(LHS::count == 0);
     77         assert(RHS::count == 1 + rhs.has_value());
     78         LIBCPP_ASSERT(!rhs.has_value());
     79 
     80         assertContains<RHS>(lhs, 2);
     81         if (rhs.has_value())
     82             assertContains<RHS>(rhs, 0);
     83     }
     84     assert(LHS::count == 0);
     85     assert(RHS::count == 0);
     86 }
     87 
     88 template <class RHS>
     89 void test_assign_value_empty() {
     90     assert(RHS::count == 0);
     91     RHS::reset();
     92     {
     93         any lhs;
     94         RHS rhs(42);
     95         assert(RHS::count == 1);
     96         assert(RHS::copied == 0);
     97 
     98         lhs = rhs;
     99 
    100         assert(RHS::count == 2);
    101         assert(RHS::copied == 1);
    102         assert(RHS::moved >= 0);
    103         assertContains<RHS>(lhs, 42);
    104     }
    105     assert(RHS::count == 0);
    106     RHS::reset();
    107     {
    108         any lhs;
    109         RHS rhs(42);
    110         assert(RHS::count == 1);
    111         assert(RHS::moved == 0);
    112 
    113         lhs = std::move(rhs);
    114 
    115         assert(RHS::count == 2);
    116         assert(RHS::copied == 0);
    117         assert(RHS::moved >= 1);
    118         assertContains<RHS>(lhs, 42);
    119     }
    120     assert(RHS::count == 0);
    121     RHS::reset();
    122 }
    123 
    124 
    125 template <class Tp, bool Move = false>
    126 void test_assign_throws() {
    127 #if !defined(TEST_HAS_NO_EXCEPTIONS)
    128     auto try_throw =
    129     [](any& lhs, Tp& rhs) {
    130         try {
    131             Move ? lhs = std::move(rhs)
    132                  : lhs = rhs;
    133             assert(false);
    134         } catch (my_any_exception const &) {
    135             // do nothing
    136         } catch (...) {
    137             assert(false);
    138         }
    139     };
    140     // const lvalue to empty
    141     {
    142         any lhs;
    143         Tp rhs(1);
    144         assert(Tp::count == 1);
    145 
    146         try_throw(lhs, rhs);
    147 
    148         assert(Tp::count == 1);
    149         assertEmpty<Tp>(lhs);
    150     }
    151     {
    152         any lhs((small(2)));
    153         Tp  rhs(1);
    154         assert(small::count == 1);
    155         assert(Tp::count == 1);
    156 
    157         try_throw(lhs, rhs);
    158 
    159         assert(small::count == 1);
    160         assert(Tp::count == 1);
    161         assertContains<small>(lhs, 2);
    162     }
    163     {
    164         any lhs((large(2)));
    165         Tp rhs(1);
    166         assert(large::count == 1);
    167         assert(Tp::count == 1);
    168 
    169         try_throw(lhs, rhs);
    170 
    171         assert(large::count == 1);
    172         assert(Tp::count == 1);
    173         assertContains<large>(lhs, 2);
    174     }
    175 #endif
    176 }
    177 
    178 
    179 // Test that any& operator=(ValueType&&) is *never* selected for:
    180 // * std::in_place type.
    181 // * Non-copyable types
    182 void test_sfinae_constraints() {
    183     { // Only the constructors are required to SFINAE on in_place_t
    184         using Tag = std::in_place_type_t<int>;
    185         using RawTag = std::remove_reference_t<Tag>;
    186         static_assert(std::is_assignable<std::any, RawTag&&>::value, "");
    187     }
    188     {
    189         struct Dummy { Dummy() = delete; };
    190         using T = std::in_place_type_t<Dummy>;
    191         static_assert(std::is_assignable<std::any, T>::value, "");
    192     }
    193     {
    194         // Test that the ValueType&& constructor SFINAE's away when the
    195         // argument is non-copyable
    196         struct NoCopy {
    197           NoCopy() = default;
    198           NoCopy(NoCopy const&) = delete;
    199           NoCopy(NoCopy&&) = default;
    200         };
    201         static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
    202         static_assert(!std::is_assignable<std::any, NoCopy&>::value, "");
    203     }
    204 }
    205 
    206 int main() {
    207     test_assign_value<small1, small2>();
    208     test_assign_value<large1, large2>();
    209     test_assign_value<small, large>();
    210     test_assign_value<large, small>();
    211     test_assign_value_empty<small>();
    212     test_assign_value_empty<large>();
    213     test_assign_throws<small_throws_on_copy>();
    214     test_assign_throws<large_throws_on_copy>();
    215     test_assign_throws<throws_on_move, /* Move = */ true>();
    216     test_sfinae_constraints();
    217 }