llvm-project
142 строки · 4.0 Кб
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// UNSUPPORTED: c++03
10
11// <set>
12
13// void swap(set& c)
14// noexcept(!allocator_type::propagate_on_container_swap::value ||
15// __is_nothrow_swappable<allocator_type>::value);
16//
17// In C++17, the standard says that swap shall have:
18// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
19// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
20
21// This tests a conforming extension
22
23#include <set>24#include <utility>25#include <cassert>26
27#include "test_macros.h"28#include "MoveOnly.h"29#include "test_allocator.h"30
31template <class T>32struct some_comp33{
34typedef T value_type;35
36some_comp() {}37some_comp(const some_comp&) {}38bool operator()(const T&, const T&) const { return false; }39};40
41template <class T>42struct some_comp243{
44typedef T value_type;45
46some_comp2() {}47some_comp2(const some_comp2&) {}48bool operator()(const T&, const T&) const { return false; }49};50
51#if TEST_STD_VER >= 1452template <typename T>53void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}54#endif55
56template <class T>57struct some_alloc58{
59typedef T value_type;60
61some_alloc() {}62some_alloc(const some_alloc&);63void deallocate(void*, unsigned) {}64
65typedef std::true_type propagate_on_container_swap;66};67
68template <class T>69struct some_alloc270{
71typedef T value_type;72
73some_alloc2() {}74some_alloc2(const some_alloc2&);75void deallocate(void*, unsigned) {}76
77typedef std::false_type propagate_on_container_swap;78typedef std::true_type is_always_equal;79};80
81template <class T>82struct some_alloc383{
84typedef T value_type;85
86some_alloc3() {}87some_alloc3(const some_alloc3&);88void deallocate(void*, unsigned) {}89
90typedef std::false_type propagate_on_container_swap;91typedef std::false_type is_always_equal;92};93
94int main(int, char**)95{
96{97typedef std::set<MoveOnly> C;98static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");99}100#if defined(_LIBCPP_VERSION)101{102typedef std::set<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;103static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");104}105{106typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;107static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");108}109#endif // _LIBCPP_VERSION110{111typedef std::set<MoveOnly, some_comp<MoveOnly>> C;112static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");113}114
115#if TEST_STD_VER >= 14116{ // POCS allocator, throwable swap for comp117typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;118static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");119}120{ // always equal allocator, throwable swap for comp121typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;122static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");123}124{ // POCS allocator, nothrow swap for comp125typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;126static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");127}128{ // always equal allocator, nothrow swap for comp129typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;130static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");131}132#if defined(_LIBCPP_VERSION)133{ // NOT always equal allocator, nothrow swap for comp134typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;135static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");136}137#endif // _LIBCPP_VERSION138#endif139
140
141return 0;142}
143