1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14 10 11 // Throwing bad_any_cast is supported starting in macosx10.13 12 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12}} && !no-exceptions 13 14 // <any> 15 16 // any(any &&) noexcept; 17 18 #include <any> 19 #include <utility> 20 #include <type_traits> 21 #include <cassert> 22 23 #include "any_helpers.h" 24 #include "count_new.h" 25 #include "test_macros.h" 26 27 // Moves are always noexcept. The throws_on_move object 28 // must be stored dynamically so the pointer is moved and 29 // not the stored object. test_move_does_not_throw()30void test_move_does_not_throw() 31 { 32 #if !defined(TEST_HAS_NO_EXCEPTIONS) 33 assert(throws_on_move::count == 0); 34 { 35 throws_on_move v(42); 36 std::any a = v; 37 assert(throws_on_move::count == 2); 38 // No allocations should be performed after this point. 39 DisableAllocationGuard g; ((void)g); 40 try { 41 const std::any a2 = std::move(a); 42 assertEmpty(a); 43 assertContains<throws_on_move>(a2, 42); 44 } catch (...) { 45 assert(false); 46 } 47 assert(throws_on_move::count == 1); 48 assertEmpty(a); 49 } 50 assert(throws_on_move::count == 0); 51 #endif 52 } 53 test_move_empty()54void test_move_empty() { 55 DisableAllocationGuard g; ((void)g); // no allocations should be performed. 56 57 std::any a1; 58 std::any a2 = std::move(a1); 59 60 assertEmpty(a1); 61 assertEmpty(a2); 62 } 63 64 template <class Type> test_move()65void test_move() { 66 assert(Type::count == 0); 67 Type::reset(); 68 { 69 std::any a = Type(42); 70 assert(Type::count == 1); 71 assert(Type::copied == 0); 72 assert(Type::moved == 1); 73 74 // Moving should not perform allocations since it must be noexcept. 75 DisableAllocationGuard g; ((void)g); 76 77 std::any a2 = std::move(a); 78 79 assert(Type::moved == 1 || Type::moved == 2); // zero or more move operations can be performed. 80 assert(Type::copied == 0); // no copies can be performed. 81 assert(Type::count == 1 + a.has_value()); 82 assertContains<Type>(a2, 42); 83 LIBCPP_ASSERT(!a.has_value()); // Moves are always destructive. 84 if (a.has_value()) 85 assertContains<Type>(a, 0); 86 } 87 assert(Type::count == 0); 88 } 89 main(int,char **)90int main(int, char**) 91 { 92 // noexcept test 93 static_assert(std::is_nothrow_move_constructible<std::any>::value); 94 95 test_move<small>(); 96 test_move<large>(); 97 test_move_empty(); 98 test_move_does_not_throw(); 99 100 return 0; 101 } 102