//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // // flat_map(flat_map&&) // noexcept(is_nothrow_move_constructible::value && // is_nothrow_move_constructible::value && // is_nothrow_copy_constructible::value); // This tests a conforming extension #include #include #include #include #include #include #include #include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" template struct ThrowingMoveAllocator { using value_type = T; explicit ThrowingMoveAllocator() = default; ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default; ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {} T* allocate(std::ptrdiff_t n) { return std::allocator().allocate(n); } void deallocate(T* p, std::ptrdiff_t n) { return std::allocator().deallocate(p, n); } friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default; }; struct ThrowingMoveComp { ThrowingMoveComp() = default; ThrowingMoveComp(const ThrowingMoveComp&) noexcept(true) {} ThrowingMoveComp(ThrowingMoveComp&&) noexcept(false) {} bool operator()(const auto&, const auto&) const { return false; } }; struct MoveSensitiveComp { MoveSensitiveComp() noexcept(false) = default; MoveSensitiveComp(const MoveSensitiveComp&) noexcept = default; MoveSensitiveComp(MoveSensitiveComp&& rhs) { rhs.is_moved_from_ = true; } MoveSensitiveComp& operator=(const MoveSensitiveComp&) noexcept(false) = default; MoveSensitiveComp& operator=(MoveSensitiveComp&& rhs) { rhs.is_moved_from_ = true; return *this; } bool operator()(const auto&, const auto&) const { return false; } bool is_moved_from_ = false; }; int main(int, char**) { { using C = std::flat_map; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_constructible_v); C c; C d = std::move(c); } { using C = std::flat_map, std::deque>>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_constructible_v); C c; C d = std::move(c); } #if _LIBCPP_VERSION { // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators using C = std::flat_map, std::deque>, std::vector>; static_assert(!std::is_nothrow_move_constructible_v>>); static_assert(!std::is_nothrow_move_constructible_v); C c; C d = std::move(c); } { // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators using C = std::flat_map, std::vector, std::deque>>; static_assert(!std::is_nothrow_move_constructible_v>>); static_assert(!std::is_nothrow_move_constructible_v); C c; C d = std::move(c); } #endif // _LIBCPP_VERSION { // Comparator fails to be nothrow-move-constructible using C = std::flat_map; static_assert(!std::is_nothrow_move_constructible_v); C c; C d = std::move(c); } return 0; }