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
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03
101f4231f8SEric Fiselier
115a83710eSEric Fiselier // <string>
125a83710eSEric Fiselier
135a83710eSEric Fiselier // void swap(basic_string& c)
145a83710eSEric Fiselier // noexcept(!allocator_type::propagate_on_container_swap::value ||
15*425620ccSNikolas Klauser // __is_nothrow_swappable<allocator_type>::value); // constexpr since C++20
16e3fbe143SMarshall Clow //
17e3fbe143SMarshall Clow // In C++17, the standard says that swap shall have:
18e3fbe143SMarshall Clow // noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
19*425620ccSNikolas Klauser // allocator_traits<Allocator>::is_always_equal::value); // constexpr since C++20
205a83710eSEric Fiselier
215a83710eSEric Fiselier // This tests a conforming extension
225a83710eSEric Fiselier
235a83710eSEric Fiselier #include <string>
242cd516e0SEric Fiselier #include <utility>
255a83710eSEric Fiselier #include <cassert>
265a83710eSEric Fiselier
271f4231f8SEric Fiselier #include "test_macros.h"
285a83710eSEric Fiselier #include "test_allocator.h"
295a83710eSEric Fiselier
305a83710eSEric Fiselier template <class T>
315a83710eSEric Fiselier struct some_alloc
325a83710eSEric Fiselier {
335a83710eSEric Fiselier typedef T value_type;
345a83710eSEric Fiselier
some_allocsome_alloc355a83710eSEric Fiselier some_alloc() {}
365a83710eSEric Fiselier some_alloc(const some_alloc&);
3776b26852SMarshall Clow T *allocate(size_t);
deallocatesome_alloc385a83710eSEric Fiselier void deallocate(void*, unsigned) {}
395a83710eSEric Fiselier typedef std::true_type propagate_on_container_swap;
405a83710eSEric Fiselier };
415a83710eSEric Fiselier
42e3fbe143SMarshall Clow template <class T>
43e3fbe143SMarshall Clow struct some_alloc2
44e3fbe143SMarshall Clow {
45e3fbe143SMarshall Clow typedef T value_type;
46e3fbe143SMarshall Clow
some_alloc2some_alloc247e3fbe143SMarshall Clow some_alloc2() {}
48e3fbe143SMarshall Clow some_alloc2(const some_alloc2&);
4976b26852SMarshall Clow T *allocate(size_t);
deallocatesome_alloc250e3fbe143SMarshall Clow void deallocate(void*, unsigned) {}
51e3fbe143SMarshall Clow
52e3fbe143SMarshall Clow typedef std::false_type propagate_on_container_swap;
53e3fbe143SMarshall Clow typedef std::true_type is_always_equal;
54e3fbe143SMarshall Clow };
55e3fbe143SMarshall Clow
main(int,char **)562df59c50SJF Bastien int main(int, char**)
575a83710eSEric Fiselier {
585a83710eSEric Fiselier {
595a83710eSEric Fiselier typedef std::string C;
602cd516e0SEric Fiselier static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
615a83710eSEric Fiselier }
6203fe6e2dSStephan T. Lavavej #if defined(_LIBCPP_VERSION)
635a83710eSEric Fiselier {
645a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C;
6503fe6e2dSStephan T. Lavavej static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
665a83710eSEric Fiselier }
6703fe6e2dSStephan T. Lavavej #endif // _LIBCPP_VERSION
685a83710eSEric Fiselier {
695a83710eSEric Fiselier typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
70e3fbe143SMarshall Clow #if TEST_STD_VER >= 14
719ea675efSStephan T. Lavavej // In C++14, if POCS is set, swapping the allocator is required not to throw
722cd516e0SEric Fiselier static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
73e3fbe143SMarshall Clow #else
742cd516e0SEric Fiselier static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
75e3fbe143SMarshall Clow #endif
765a83710eSEric Fiselier }
77e3fbe143SMarshall Clow #if TEST_STD_VER >= 14
78e3fbe143SMarshall Clow {
79e3fbe143SMarshall Clow typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C;
80e3fbe143SMarshall Clow // if the allocators are always equal, then the swap can be noexcept
812cd516e0SEric Fiselier static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
82e3fbe143SMarshall Clow }
83e3fbe143SMarshall Clow #endif
842df59c50SJF Bastien
852df59c50SJF Bastien return 0;
865a83710eSEric Fiselier }
87