15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
9*31cbe0f2SLouis Dionne // UNSUPPORTED: c++03
10d513ad88SEric Fiselier
115a83710eSEric Fiselier // <set>
125a83710eSEric Fiselier
135a83710eSEric Fiselier // void swap(set& c)
145a83710eSEric Fiselier // noexcept(!allocator_type::propagate_on_container_swap::value ||
155a83710eSEric Fiselier // __is_nothrow_swappable<allocator_type>::value);
16e3fbe143SMarshall Clow //
17e3fbe143SMarshall Clow // In C++17, the standard says that swap shall have:
18e3fbe143SMarshall Clow // noexcept(allocator_traits<Allocator>::is_always_equal::value &&
19e3fbe143SMarshall Clow // noexcept(swap(declval<Compare&>(), declval<Compare&>())));
205a83710eSEric Fiselier
215a83710eSEric Fiselier // This tests a conforming extension
225a83710eSEric Fiselier
235a83710eSEric Fiselier #include <set>
242cd516e0SEric Fiselier #include <utility>
255a83710eSEric Fiselier #include <cassert>
265a83710eSEric Fiselier
27d513ad88SEric Fiselier #include "test_macros.h"
28949389c3SMarshall Clow #include "MoveOnly.h"
295a83710eSEric Fiselier #include "test_allocator.h"
305a83710eSEric Fiselier
315a83710eSEric Fiselier template <class T>
325a83710eSEric Fiselier struct some_comp
335a83710eSEric Fiselier {
345a83710eSEric Fiselier typedef T value_type;
355a83710eSEric Fiselier
some_compsome_comp365a83710eSEric Fiselier some_comp() {}
some_compsome_comp375a83710eSEric Fiselier some_comp(const some_comp&) {}
operator ()some_comp3854238fd3SMarshall Clow bool operator()(const T&, const T&) const { return false; }
395a83710eSEric Fiselier };
405a83710eSEric Fiselier
41e3fbe143SMarshall Clow template <class T>
42e3fbe143SMarshall Clow struct some_comp2
43e3fbe143SMarshall Clow {
44e3fbe143SMarshall Clow typedef T value_type;
45e3fbe143SMarshall Clow
some_comp2some_comp246e3fbe143SMarshall Clow some_comp2() {}
some_comp2some_comp247e3fbe143SMarshall Clow some_comp2(const some_comp2&) {}
operator ()some_comp24854238fd3SMarshall Clow bool operator()(const T&, const T&) const { return false; }
49e3fbe143SMarshall Clow };
50e3fbe143SMarshall Clow
51e3fbe143SMarshall Clow #if TEST_STD_VER >= 14
52e3fbe143SMarshall Clow template <typename T>
swap(some_comp2<T> &,some_comp2<T> &)53e3fbe143SMarshall Clow void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
54e3fbe143SMarshall Clow #endif
55e3fbe143SMarshall Clow
56e3fbe143SMarshall Clow template <class T>
57e3fbe143SMarshall Clow struct some_alloc
58e3fbe143SMarshall Clow {
59e3fbe143SMarshall Clow typedef T value_type;
60e3fbe143SMarshall Clow
some_allocsome_alloc61e3fbe143SMarshall Clow some_alloc() {}
62e3fbe143SMarshall Clow some_alloc(const some_alloc&);
deallocatesome_alloc63e3fbe143SMarshall Clow void deallocate(void*, unsigned) {}
64e3fbe143SMarshall Clow
65e3fbe143SMarshall Clow typedef std::true_type propagate_on_container_swap;
66e3fbe143SMarshall Clow };
67e3fbe143SMarshall Clow
68e3fbe143SMarshall Clow template <class T>
69e3fbe143SMarshall Clow struct some_alloc2
70e3fbe143SMarshall Clow {
71e3fbe143SMarshall Clow typedef T value_type;
72e3fbe143SMarshall Clow
some_alloc2some_alloc273e3fbe143SMarshall Clow some_alloc2() {}
74e3fbe143SMarshall Clow some_alloc2(const some_alloc2&);
deallocatesome_alloc275e3fbe143SMarshall Clow void deallocate(void*, unsigned) {}
76e3fbe143SMarshall Clow
77e3fbe143SMarshall Clow typedef std::false_type propagate_on_container_swap;
78e3fbe143SMarshall Clow typedef std::true_type is_always_equal;
79e3fbe143SMarshall Clow };
80e3fbe143SMarshall Clow
81e3fbe143SMarshall Clow template <class T>
82e3fbe143SMarshall Clow struct some_alloc3
83e3fbe143SMarshall Clow {
84e3fbe143SMarshall Clow typedef T value_type;
85e3fbe143SMarshall Clow
some_alloc3some_alloc386e3fbe143SMarshall Clow some_alloc3() {}
87e3fbe143SMarshall Clow some_alloc3(const some_alloc3&);
deallocatesome_alloc388e3fbe143SMarshall Clow void deallocate(void*, unsigned) {}
89e3fbe143SMarshall Clow
90e3fbe143SMarshall Clow typedef std::false_type propagate_on_container_swap;
91e3fbe143SMarshall Clow typedef std::false_type is_always_equal;
92e3fbe143SMarshall Clow };
93e3fbe143SMarshall Clow
main(int,char **)942df59c50SJF Bastien int main(int, char**)
955a83710eSEric Fiselier {
965a83710eSEric Fiselier {
975a83710eSEric Fiselier typedef std::set<MoveOnly> C;
982cd516e0SEric Fiselier static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
995a83710eSEric Fiselier }
10003fe6e2dSStephan T. Lavavej #if defined(_LIBCPP_VERSION)
1015a83710eSEric Fiselier {
1025a83710eSEric Fiselier typedef std::set<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
10303fe6e2dSStephan T. Lavavej static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
1045a83710eSEric Fiselier }
1055a83710eSEric Fiselier {
1065a83710eSEric Fiselier typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
10703fe6e2dSStephan T. Lavavej static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
1085a83710eSEric Fiselier }
10903fe6e2dSStephan T. Lavavej #endif // _LIBCPP_VERSION
1105a83710eSEric Fiselier {
1115a83710eSEric Fiselier typedef std::set<MoveOnly, some_comp<MoveOnly>> C;
1122cd516e0SEric Fiselier static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
1135a83710eSEric Fiselier }
114e3fbe143SMarshall Clow
115e3fbe143SMarshall Clow #if TEST_STD_VER >= 14
116e3fbe143SMarshall Clow { // POCS allocator, throwable swap for comp
117e3fbe143SMarshall Clow typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
1182cd516e0SEric Fiselier static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
119e3fbe143SMarshall Clow }
120e3fbe143SMarshall Clow { // always equal allocator, throwable swap for comp
121e3fbe143SMarshall Clow typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
1222cd516e0SEric Fiselier static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
123e3fbe143SMarshall Clow }
124e3fbe143SMarshall Clow { // POCS allocator, nothrow swap for comp
125e3fbe143SMarshall Clow typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
1262cd516e0SEric Fiselier static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
127e3fbe143SMarshall Clow }
128e3fbe143SMarshall Clow { // always equal allocator, nothrow swap for comp
129e3fbe143SMarshall Clow typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
1302cd516e0SEric Fiselier static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
131e3fbe143SMarshall Clow }
13203fe6e2dSStephan T. Lavavej #if defined(_LIBCPP_VERSION)
133e3fbe143SMarshall Clow { // NOT always equal allocator, nothrow swap for comp
134e3fbe143SMarshall Clow typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
13503fe6e2dSStephan T. Lavavej static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
136e3fbe143SMarshall Clow }
13703fe6e2dSStephan T. Lavavej #endif // _LIBCPP_VERSION
138e3fbe143SMarshall Clow #endif
139e3fbe143SMarshall Clow
1402df59c50SJF Bastien
1412df59c50SJF Bastien return 0;
1425a83710eSEric Fiselier }
143