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, c++17, c++20
10
11// <flat_map>
12
13// flat_multimap(flat_multimap&&)
14// noexcept(is_nothrow_move_constructible<key_container_type>::value &&
15// is_nothrow_move_constructible<mapped_container_type>::value &&
16// is_nothrow_copy_constructible<key_compare>::value);
17
18// This tests a conforming extension
19
20#include <cassert>
21#include <deque>
22#include <flat_map>
23#include <functional>
24#include <memory>
25#include <type_traits>
26#include <vector>
27
28#include "test_macros.h"
29#include "MoveOnly.h"
30#include "test_allocator.h"
31
32template <class T>
33struct ThrowingMoveAllocator {
34 using value_type = T;
35 explicit ThrowingMoveAllocator() = default;
36 ThrowingMoveAllocator(const ThrowingMoveAllocator&) = default;
37 ThrowingMoveAllocator(ThrowingMoveAllocator&&) noexcept(false) {}
38 T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
39 void deallocate(T* p, std::ptrdiff_t n) { return std::allocator<T>().deallocate(p, n); }
40 friend bool operator==(ThrowingMoveAllocator, ThrowingMoveAllocator) = default;
41};
42
43struct ThrowingMoveComp {
44 ThrowingMoveComp() = default;
45 ThrowingMoveComp(const ThrowingMoveComp&) noexcept(true) {}
46 ThrowingMoveComp(ThrowingMoveComp&&) noexcept(false) {}
47 bool operator()(const auto&, const auto&) const { return false; }
48};
49
50struct MoveSensitiveComp {
51 MoveSensitiveComp() noexcept(false) = default;
52 MoveSensitiveComp(const MoveSensitiveComp&) noexcept = default;
53 MoveSensitiveComp(MoveSensitiveComp&& rhs) { rhs.is_moved_from_ = true; }
54 MoveSensitiveComp& operator=(const MoveSensitiveComp&) noexcept(false) = default;
55 MoveSensitiveComp& operator=(MoveSensitiveComp&& rhs) {
56 rhs.is_moved_from_ = true;
57 return *this;
58 }
59 bool operator()(const auto&, const auto&) const { return false; }
60 bool is_moved_from_ = false;
61};
62
63int main(int, char**) {
64 {
65 using C = std::flat_multimap<int, int>;
66 LIBCPP_STATIC_ASSERT(std::is_nothrow_move_constructible_v<C>);
67 C c;
68 C d = std::move(c);
69 }
70 {
71 using C = std::flat_multimap<int, int, std::less<int>, std::deque<int, test_allocator<int>>>;
72 LIBCPP_STATIC_ASSERT(std::is_nothrow_move_constructible_v<C>);
73 C c;
74 C d = std::move(c);
75 }
76#if _LIBCPP_VERSION
77 {
78 // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
79 using C =
80 std::flat_multimap<int, int, std::less<int>, std::deque<int, ThrowingMoveAllocator<int>>, std::vector<int>>;
81 static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
82 static_assert(!std::is_nothrow_move_constructible_v<C>);
83 C c;
84 C d = std::move(c);
85 }
86 {
87 // Container fails to be nothrow-move-constructible; this relies on libc++'s support for non-nothrow-copyable allocators
88 using C =
89 std::flat_multimap<int, int, std::less<int>, std::vector<int>, std::deque<int, ThrowingMoveAllocator<int>>>;
90 static_assert(!std::is_nothrow_move_constructible_v<std::deque<int, ThrowingMoveAllocator<int>>>);
91 static_assert(!std::is_nothrow_move_constructible_v<C>);
92 C c;
93 C d = std::move(c);
94 }
95#endif // _LIBCPP_VERSION
96 {
97 // Comparator fails to be nothrow-move-constructible
98 using C = std::flat_multimap<int, int, ThrowingMoveComp>;
99 static_assert(!std::is_nothrow_move_constructible_v<C>);
100 C c;
101 C d = std::move(c);
102 }
103 return 0;
104}
105

source code of libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp