| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| |
| // <memory> |
| |
| // template <typename _Alloc> |
| // void __swap_allocator(_Alloc& __a1, _Alloc& __a2); |
| |
| #include <cassert> |
| #include <memory> |
| // Transitively includes `swap_allocator.h` (directly including it breaks the modules build). |
| #include <vector> |
| #include <utility> |
| |
| #include "test_macros.h" |
| |
| template <bool Propagate, bool Noexcept> |
| struct Alloc { |
| int i = 0; |
| Alloc() = default; |
| Alloc(int set_i) : i(set_i) {} |
| |
| using value_type = int; |
| using propagate_on_container_swap = std::integral_constant<bool, Propagate>; |
| |
| friend void swap(Alloc& a1, Alloc& a2) TEST_NOEXCEPT_COND(Noexcept) { |
| std::swap(a1.i, a2.i); |
| } |
| |
| }; |
| |
| using PropagatingAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>; |
| static_assert(std::allocator_traits<PropagatingAlloc>::propagate_on_container_swap::value, ""); |
| |
| using NonPropagatingAlloc = Alloc</*Propagate=*/false, /*Noexcept=*/true>; |
| static_assert(!std::allocator_traits<NonPropagatingAlloc>::propagate_on_container_swap::value, ""); |
| |
| using NoexceptSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>; |
| using ThrowingSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/false>; |
| |
| int main(int, char**) { |
| { |
| PropagatingAlloc a1(1), a2(42); |
| std::__swap_allocator(a1, a2); |
| assert(a1.i == 42); |
| assert(a2.i == 1); |
| } |
| |
| { |
| NonPropagatingAlloc a1(1), a2(42); |
| std::__swap_allocator(a1, a2); |
| assert(a1.i == 1); |
| assert(a2.i == 42); |
| } |
| |
| #if TEST_STD_VER >= 11 |
| { |
| NoexceptSwapAlloc noexcept_alloc; |
| static_assert(noexcept(std::__swap_allocator(noexcept_alloc, noexcept_alloc)), ""); |
| } |
| |
| #if TEST_STD_VER > 11 |
| { // From C++14, `__swap_allocator` is unconditionally noexcept. |
| ThrowingSwapAlloc throwing_alloc; |
| static_assert(noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), ""); |
| } |
| #else |
| { // Until C++14, `__swap_allocator` is only noexcept if the underlying `swap` function is `noexcept`. |
| ThrowingSwapAlloc throwing_alloc; |
| static_assert(!noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), ""); |
| } |
| #endif // TEST_STD_VER > 11 |
| #endif // TEST_STD_VER >= 11 |
| |
| return 0; |
| } |