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
10
11// <map>
12
13// void swap(map& c)
14// noexcept(!allocator_type::propagate_on_container_swap::value ||
15// __is_nothrow_swappable<allocator_type>::value);
16//
17// In C++17, the standard says that swap shall have:
18// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
19// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
20
21// This tests a conforming extension
22
23#include <map>
24#include <utility>
25#include <cassert>
26
27#include "test_macros.h"
28#include "MoveOnly.h"
29#include "test_allocator.h"
30
31template <class T>
32struct some_comp {
33 typedef T value_type;
34
35 some_comp() {}
36 some_comp(const some_comp&) {}
37 bool operator()(const T&, const T&) const { return false; }
38};
39
40template <class T>
41struct some_comp2 {
42 typedef T value_type;
43
44 some_comp2() {}
45 some_comp2(const some_comp2&) {}
46 bool operator()(const T&, const T&) const { return false; }
47};
48
49#if TEST_STD_VER >= 14
50template <typename T>
51void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
52#endif
53
54template <class T>
55struct some_alloc {
56 typedef T value_type;
57
58 some_alloc() {}
59 some_alloc(const some_alloc&);
60 void deallocate(void*, unsigned) {}
61
62 typedef std::true_type propagate_on_container_swap;
63};
64
65template <class T>
66struct some_alloc2 {
67 typedef T value_type;
68
69 some_alloc2() {}
70 some_alloc2(const some_alloc2&);
71 void deallocate(void*, unsigned) {}
72
73 typedef std::false_type propagate_on_container_swap;
74 typedef std::true_type is_always_equal;
75};
76
77template <class T>
78struct some_alloc3 {
79 typedef T value_type;
80
81 some_alloc3() {}
82 some_alloc3(const some_alloc3&);
83 void deallocate(void*, unsigned) {}
84
85 typedef std::false_type propagate_on_container_swap;
86 typedef std::false_type is_always_equal;
87};
88
89int main(int, char**) {
90 typedef std::pair<const MoveOnly, MoveOnly> V;
91 {
92 typedef std::map<MoveOnly, MoveOnly> C;
93 static_assert(noexcept(swap(a&: std::declval<C&>(), b&: std::declval<C&>())), "");
94 }
95#if defined(_LIBCPP_VERSION)
96 {
97 typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
98 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
99 }
100 {
101 typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
102 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
103 }
104#endif // _LIBCPP_VERSION
105 {
106 typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
107 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
108 }
109
110#if TEST_STD_VER >= 14
111 { // POCS allocator, throwable swap for comp
112 typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>, some_alloc<V>> C;
113 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
114 }
115 { // always equal allocator, throwable swap for comp
116 typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>, some_alloc2<V>> C;
117 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
118 }
119 { // POCS allocator, nothrow swap for comp
120 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc<V>> C;
121 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
122 }
123 { // always equal allocator, nothrow swap for comp
124 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<V>> C;
125 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
126 }
127# if defined(_LIBCPP_VERSION)
128 { // NOT always equal allocator, nothrow swap for comp
129 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<V>> C;
130 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
131 }
132# endif // _LIBCPP_VERSION
133#endif
134
135 return 0;
136}
137

source code of libcxx/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp