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