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