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// <set>
12
13// void swap(set& 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 <set>
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 {
91 typedef std::set<MoveOnly> C;
92 static_assert(noexcept(swap(a&: std::declval<C&>(), b&: std::declval<C&>())), "");
93 }
94#if defined(_LIBCPP_VERSION)
95 {
96 typedef std::set<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
97 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
98 }
99 {
100 typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
101 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
102 }
103#endif // _LIBCPP_VERSION
104 {
105 typedef std::set<MoveOnly, some_comp<MoveOnly>> C;
106 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
107 }
108
109#if TEST_STD_VER >= 14
110 { // POCS allocator, throwable swap for comp
111 typedef std::set<MoveOnly, some_comp<MoveOnly>, some_alloc<MoveOnly>> C;
112 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
113 }
114 { // always equal allocator, throwable swap for comp
115 typedef std::set<MoveOnly, some_comp<MoveOnly>, some_alloc2<MoveOnly>> C;
116 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
117 }
118 { // POCS allocator, nothrow swap for comp
119 typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc<MoveOnly>> C;
120 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
121 }
122 { // always equal allocator, nothrow swap for comp
123 typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
124 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
125 }
126# if defined(_LIBCPP_VERSION)
127 { // NOT always equal allocator, nothrow swap for comp
128 typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
129 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
130 }
131# endif // _LIBCPP_VERSION
132#endif
133
134 return 0;
135}
136

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