blob: 1056c231f0db36c9529fd1a8e94440fa98a6a6cb [file] [log] [blame]
Howard Hinnant5f2f14c2011-06-04 18:54:24 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <unordered_map>
11
12// void swap(unordered_map& c)
Marshall Clow7d914d12015-07-13 20:04:56 +000013// noexcept(
14// (!allocator_type::propagate_on_container_swap::value ||
15// __is_nothrow_swappable<allocator_type>::value) &&
16// __is_nothrow_swappable<hasher>::value &&
17// __is_nothrow_swappable<key_equal>::value);
18//
19// In C++17, the standard says that swap shall have:
20// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
21// noexcept(swap(declval<Hash&>(), declval<Hash&>())) &&
22// noexcept(swap(declval<Pred&>(), declval<Pred&>())));
Howard Hinnant5f2f14c2011-06-04 18:54:24 +000023
24// This tests a conforming extension
25
26#include <unordered_map>
27#include <cassert>
28
Marshall Clowdf00d5e2015-01-28 21:22:53 +000029#include "MoveOnly.h"
Marshall Clow1b921882013-12-03 00:18:10 +000030#include "test_allocator.h"
Howard Hinnant5f2f14c2011-06-04 18:54:24 +000031
32template <class T>
33struct some_comp
34{
35 typedef T value_type;
36
37 some_comp() {}
38 some_comp(const some_comp&) {}
39};
40
41template <class T>
Marshall Clow7d914d12015-07-13 20:04:56 +000042struct some_comp2
43{
44 typedef T value_type;
45
46 some_comp2() {}
47 some_comp2(const some_comp2&) {}
48 void deallocate(void*, unsigned) {}
49 typedef std::true_type propagate_on_container_swap;
50};
51
52#if TEST_STD_VER >= 14
53template <typename T>
54void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
55#endif
56
57template <class T>
Howard Hinnant5f2f14c2011-06-04 18:54:24 +000058struct some_hash
59{
60 typedef T value_type;
61 some_hash() {}
62 some_hash(const some_hash&);
63};
64
Marshall Clow7d914d12015-07-13 20:04:56 +000065template <class T>
66struct some_hash2
67{
68 typedef T value_type;
69 some_hash2() {}
70 some_hash2(const some_hash2&);
71};
72
73#if TEST_STD_VER >= 14
74template <typename T>
75void swap(some_hash2<T>&, some_hash2<T>&) noexcept {}
76#endif
77
78template <class T>
79struct some_alloc
80{
81 typedef T value_type;
82
83 some_alloc() {}
84 some_alloc(const some_alloc&);
85 void deallocate(void*, unsigned) {}
86
87 typedef std::true_type propagate_on_container_swap;
88};
89
90template <class T>
91struct some_alloc2
92{
93 typedef T value_type;
94
95 some_alloc2() {}
96 some_alloc2(const some_alloc2&);
97 void deallocate(void*, unsigned) {}
98
99 typedef std::false_type propagate_on_container_swap;
100 typedef std::true_type is_always_equal;
101};
102
103template <class T>
104struct some_alloc3
105{
106 typedef T value_type;
107
108 some_alloc3() {}
109 some_alloc3(const some_alloc3&);
110 void deallocate(void*, unsigned) {}
111
112 typedef std::false_type propagate_on_container_swap;
113 typedef std::false_type is_always_equal;
114};
115
116
Howard Hinnant5f2f14c2011-06-04 18:54:24 +0000117int main()
118{
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700119#if __has_feature(cxx_noexcept)
Marshall Clow7d914d12015-07-13 20:04:56 +0000120 typedef std::pair<const MoveOnly, MoveOnly> MapType;
Howard Hinnant5f2f14c2011-06-04 18:54:24 +0000121 {
122 typedef std::unordered_map<MoveOnly, MoveOnly> C;
123 C c1, c2;
124 static_assert(noexcept(swap(c1, c2)), "");
125 }
126 {
127 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
Marshall Clow7d914d12015-07-13 20:04:56 +0000128 std::equal_to<MoveOnly>, test_allocator<MapType>> C;
Howard Hinnant5f2f14c2011-06-04 18:54:24 +0000129 C c1, c2;
130 static_assert(noexcept(swap(c1, c2)), "");
131 }
132 {
133 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
Marshall Clow7d914d12015-07-13 20:04:56 +0000134 std::equal_to<MoveOnly>, other_allocator<MapType>> C;
Howard Hinnant5f2f14c2011-06-04 18:54:24 +0000135 C c1, c2;
136 static_assert(noexcept(swap(c1, c2)), "");
137 }
138 {
139 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>> C;
140 C c1, c2;
141 static_assert(!noexcept(swap(c1, c2)), "");
142 }
143 {
144 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
145 some_comp<MoveOnly>> C;
146 C c1, c2;
147 static_assert(!noexcept(swap(c1, c2)), "");
148 }
Marshall Clow7d914d12015-07-13 20:04:56 +0000149
150#if TEST_STD_VER >= 14
151 { // POCS allocator, throwable swap for hash, throwable swap for comp
152 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
153 C c1, c2;
154 static_assert(!noexcept(swap(c1, c2)), "");
155 }
156 { // always equal allocator, throwable swap for hash, throwable swap for comp
157 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
158 C c1, c2;
159 static_assert(!noexcept(swap(c1, c2)), "");
160 }
161 { // POCS allocator, throwable swap for hash, nothrow swap for comp
162 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
163 C c1, c2;
164 static_assert(!noexcept(swap(c1, c2)), "");
165 }
166 { // always equal allocator, throwable swap for hash, nothrow swap for comp
167 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
168 C c1, c2;
169 static_assert(!noexcept(swap(c1, c2)), "");
170 }
171 { // POCS allocator, nothrow swap for hash, throwable swap for comp
172 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
173 C c1, c2;
174 static_assert(!noexcept(swap(c1, c2)), "");
175 }
176 { // always equal allocator, nothrow swap for hash, throwable swap for comp
177 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
178 C c1, c2;
179 static_assert(!noexcept(swap(c1, c2)), "");
180 }
181 { // POCS allocator, nothrow swap for hash, nothrow swap for comp
182 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
183 C c1, c2;
184 static_assert( noexcept(swap(c1, c2)), "");
185 }
186 { // always equal allocator, nothrow swap for hash, nothrow swap for comp
187 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
188 C c1, c2;
189 static_assert( noexcept(swap(c1, c2)), "");
190 }
191
192 { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
193 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C;
194 C c1, c2;
195 static_assert( noexcept(swap(c1, c2)), "");
196 }
197#endif
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700198#endif
Howard Hinnant5f2f14c2011-06-04 18:54:24 +0000199}