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
10// XFAIL: FROZEN-CXX03-HEADERS-FIXME
11
12// <memory>
13
14// template <typename _Alloc>
15// void __swap_allocator(_Alloc& __a1, _Alloc& __a2);
16
17#include <__memory/swap_allocator.h>
18#include <cassert>
19#include <memory>
20#include <utility>
21
22#include "test_macros.h"
23
24template <bool Propagate, bool Noexcept>
25struct Alloc {
26 int i = 0;
27 Alloc() = default;
28 Alloc(int set_i) : i(set_i) {}
29
30 using value_type = int;
31 using propagate_on_container_swap = std::integral_constant<bool, Propagate>;
32
33 friend void swap(Alloc& a1, Alloc& a2) TEST_NOEXCEPT_COND(Noexcept) {
34 std::swap(a1.i, a2.i);
35 }
36
37};
38
39using PropagatingAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>;
40static_assert(std::allocator_traits<PropagatingAlloc>::propagate_on_container_swap::value, "");
41
42using NonPropagatingAlloc = Alloc</*Propagate=*/false, /*Noexcept=*/true>;
43static_assert(!std::allocator_traits<NonPropagatingAlloc>::propagate_on_container_swap::value, "");
44
45using NoexceptSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>;
46using ThrowingSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/false>;
47
48int main(int, char**) {
49 {
50 PropagatingAlloc a1(1), a2(42);
51 std::__swap_allocator(a1, a2);
52 assert(a1.i == 42);
53 assert(a2.i == 1);
54 }
55
56 {
57 NonPropagatingAlloc a1(1), a2(42);
58 std::__swap_allocator(a1, a2);
59 assert(a1.i == 1);
60 assert(a2.i == 42);
61 }
62
63#if TEST_STD_VER >= 11
64 {
65 NoexceptSwapAlloc noexcept_alloc;
66 static_assert(noexcept(std::__swap_allocator(noexcept_alloc, noexcept_alloc)), "");
67 }
68
69#if TEST_STD_VER > 11
70 { // From C++14, `__swap_allocator` is unconditionally noexcept.
71 ThrowingSwapAlloc throwing_alloc;
72 static_assert(noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
73 }
74#else
75 { // Until C++14, `__swap_allocator` is only noexcept if the underlying `swap` function is `noexcept`.
76 ThrowingSwapAlloc throwing_alloc;
77 static_assert(!noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
78 }
79#endif // TEST_STD_VER > 11
80#endif // TEST_STD_VER >= 11
81
82 return 0;
83}
84

source code of libcxx/test/libcxx/memory/swap_allocator.pass.cpp