libcxx

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

move.pass.cpp (2954B)


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