Home | History | Annotate | Download | only in any.assign
      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
     11 
     12 // <experimental/any>
     13 
     14 // any& operator=(any const &);
     15 
     16 // Test value copy and move assignment.
     17 
     18 #include <experimental/any>
     19 #include <cassert>
     20 
     21 #include "experimental_any_helpers.h"
     22 #include "count_new.hpp"
     23 #include "test_macros.h"
     24 
     25 using std::experimental::any;
     26 using std::experimental::any_cast;
     27 
     28 template <class LHS, class RHS>
     29 void test_assign_value() {
     30     assert(LHS::count == 0);
     31     assert(RHS::count == 0);
     32     LHS::reset();
     33     RHS::reset();
     34     {
     35         any lhs(LHS(1));
     36         any const rhs(RHS(2));
     37 
     38         assert(LHS::count == 1);
     39         assert(RHS::count == 1);
     40         assert(RHS::copied == 0);
     41 
     42         lhs = rhs;
     43 
     44         assert(RHS::copied == 1);
     45         assert(LHS::count == 0);
     46         assert(RHS::count == 2);
     47 
     48         assertContains<RHS>(lhs, 2);
     49         assertContains<RHS>(rhs, 2);
     50     }
     51     assert(LHS::count == 0);
     52     assert(RHS::count == 0);
     53     LHS::reset();
     54     RHS::reset();
     55     {
     56         any lhs(LHS(1));
     57         any rhs(RHS(2));
     58 
     59         assert(LHS::count == 1);
     60         assert(RHS::count == 1);
     61         assert(RHS::moved == 1);
     62 
     63         lhs = std::move(rhs);
     64 
     65         assert(RHS::moved >= 1);
     66         assert(RHS::copied == 0);
     67         assert(LHS::count == 0);
     68         assert(RHS::count == 1);
     69 
     70         assertContains<RHS>(lhs, 2);
     71         assertEmpty<RHS>(rhs);
     72     }
     73     assert(LHS::count == 0);
     74     assert(RHS::count == 0);
     75 }
     76 
     77 template <class RHS>
     78 void test_assign_value_empty() {
     79     assert(RHS::count == 0);
     80     RHS::reset();
     81     {
     82         any lhs;
     83         RHS rhs(42);
     84         assert(RHS::count == 1);
     85         assert(RHS::copied == 0);
     86 
     87         lhs = rhs;
     88 
     89         assert(RHS::count == 2);
     90         assert(RHS::copied == 1);
     91         assert(RHS::moved >= 0);
     92         assertContains<RHS>(lhs, 42);
     93     }
     94     assert(RHS::count == 0);
     95     RHS::reset();
     96     {
     97         any lhs;
     98         RHS rhs(42);
     99         assert(RHS::count == 1);
    100         assert(RHS::moved == 0);
    101 
    102         lhs = std::move(rhs);
    103 
    104         assert(RHS::count == 2);
    105         assert(RHS::copied == 0);
    106         assert(RHS::moved >= 1);
    107         assertContains<RHS>(lhs, 42);
    108     }
    109     assert(RHS::count == 0);
    110     RHS::reset();
    111 }
    112 
    113 
    114 template <class Tp, bool Move = false>
    115 void test_assign_throws() {
    116 #if !defined(TEST_HAS_NO_EXCEPTIONS)
    117     auto try_throw=
    118     [](any& lhs, auto&& rhs) {
    119         try {
    120             Move ? lhs = std::move(rhs)
    121                  : lhs = rhs;
    122             assert(false);
    123         } catch (my_any_exception const &) {
    124             // do nothing
    125         } catch (...) {
    126             assert(false);
    127         }
    128     };
    129     // const lvalue to empty
    130     {
    131         any lhs;
    132         Tp rhs(1);
    133         assert(Tp::count == 1);
    134 
    135         try_throw(lhs, rhs);
    136 
    137         assert(Tp::count == 1);
    138         assertEmpty<Tp>(lhs);
    139     }
    140     {
    141         any lhs((small(2)));
    142         Tp  rhs(1);
    143         assert(small::count == 1);
    144         assert(Tp::count == 1);
    145 
    146         try_throw(lhs, rhs);
    147 
    148         assert(small::count == 1);
    149         assert(Tp::count == 1);
    150         assertContains<small>(lhs, 2);
    151     }
    152     {
    153         any lhs((large(2)));
    154         Tp rhs(1);
    155         assert(large::count == 1);
    156         assert(Tp::count == 1);
    157 
    158         try_throw(lhs, rhs);
    159 
    160         assert(large::count == 1);
    161         assert(Tp::count == 1);
    162         assertContains<large>(lhs, 2);
    163     }
    164 #endif
    165 }
    166 
    167 int main() {
    168     test_assign_value<small1, small2>();
    169     test_assign_value<large1, large2>();
    170     test_assign_value<small, large>();
    171     test_assign_value<large, small>();
    172     test_assign_value_empty<small>();
    173     test_assign_value_empty<large>();
    174     test_assign_throws<small_throws_on_copy>();
    175     test_assign_throws<large_throws_on_copy>();
    176     test_assign_throws<throws_on_move, /* Move = */ true>();
    177 }