Home | History | Annotate | Download | only in any.cons
      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(any &&) noexcept;
     15 
     16 #include <experimental/any>
     17 #include <utility>
     18 #include <type_traits>
     19 #include <cassert>
     20 
     21 #include "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 // Moves are always noexcept. The throws_on_move object
     29 // must be stored dynamically so the pointer is moved and
     30 // not the stored object.
     31 void test_move_does_not_throw()
     32 {
     33 #if !defined(TEST_HAS_NO_EXCEPTIONS)
     34     assert(throws_on_move::count == 0);
     35     {
     36         throws_on_move v(42);
     37         any a(v);
     38         assert(throws_on_move::count == 2);
     39         // No allocations should be performed after this point.
     40         DisableAllocationGuard g; ((void)g);
     41         try {
     42             any const a2(std::move(a));
     43             assertEmpty(a);
     44             assertContains<throws_on_move>(a2, 42);
     45         } catch (...) {
     46             assert(false);
     47         }
     48         assert(throws_on_move::count == 1);
     49         assertEmpty(a);
     50     }
     51     assert(throws_on_move::count == 0);
     52 #endif
     53 }
     54 
     55 void test_move_empty() {
     56     DisableAllocationGuard g; ((void)g); // no allocations should be performed.
     57 
     58     any a1;
     59     any a2(std::move(a1));
     60 
     61     assertEmpty(a1);
     62     assertEmpty(a2);
     63 }
     64 
     65 template <class Type>
     66 void test_move() {
     67     assert(Type::count == 0);
     68     Type::reset();
     69     {
     70         any a((Type(42)));
     71         assert(Type::count == 1);
     72         assert(Type::copied == 0);
     73         assert(Type::moved == 1);
     74 
     75         // Moving should not perform allocations since it must be noexcept.
     76         DisableAllocationGuard g; ((void)g);
     77 
     78         any a2(std::move(a));
     79 
     80         assert(Type::moved >= 1); // zero or more move operations can be performed.
     81         assert(Type::copied == 0); // no copies can be performed.
     82         assert(Type::count == 1);
     83         assertEmpty(a); // Moves are always destructive.
     84         assertContains<Type>(a2, 42);
     85     }
     86     assert(Type::count == 0);
     87 }
     88 
     89 int main()
     90 {
     91     // noexcept test
     92     {
     93         static_assert(
     94             std::is_nothrow_move_constructible<any>::value
     95           , "any must be nothrow move constructible"
     96           );
     97     }
     98     test_move<small>();
     99     test_move<large>();
    100     test_move_empty();
    101     test_move_does_not_throw();
    102 }
    103