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