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, c++11, c++14, c++17
10
11// template<class I1, class I2>
12// concept indirectly_swappable;
13
14#include <iterator>
15
16#include "test_macros.h"
17
18template<class T, class ValueType = T>
19struct PointerTo {
20 using value_type = ValueType;
21 T& operator*() const;
22};
23
24static_assert(std::indirectly_swappable<PointerTo<int>>);
25static_assert(std::indirectly_swappable<PointerTo<int>, PointerTo<int>>);
26
27struct B;
28
29struct A {
30 friend void iter_swap(const PointerTo<A>&, const PointerTo<A>&);
31};
32
33// Is indirectly swappable.
34struct B {
35 friend void iter_swap(const PointerTo<B>&, const PointerTo<B>&);
36 friend void iter_swap(const PointerTo<A>&, const PointerTo<B>&);
37 friend void iter_swap(const PointerTo<B>&, const PointerTo<A>&);
38};
39
40// Valid except ranges::iter_swap(i2, i1).
41struct C {
42 friend void iter_swap(const PointerTo<C>&, const PointerTo<C>&);
43 friend void iter_swap(const PointerTo<A>&, const PointerTo<C>&);
44 friend void iter_swap(const PointerTo<C>&, const PointerTo<A>&) = delete;
45};
46
47// Valid except ranges::iter_swap(i1, i2).
48struct D {
49 friend void iter_swap(const PointerTo<D>&, const PointerTo<D>&);
50 friend void iter_swap(const PointerTo<A>&, const PointerTo<D>&) = delete;
51 friend void iter_swap(const PointerTo<D>&, const PointerTo<A>&);
52};
53
54// Valid except ranges::iter_swap(i2, i2).
55struct E {
56 E operator=(const E&) = delete;
57 friend void iter_swap(const PointerTo<E>&, const PointerTo<E>&) = delete;
58 friend void iter_swap(const PointerTo<A>&, const PointerTo<E>&);
59 friend void iter_swap(const PointerTo<E>&, const PointerTo<A>&);
60};
61
62struct F {
63 friend void iter_swap(const PointerTo<F>&, const PointerTo<F>&) = delete;
64};
65
66// Valid except ranges::iter_swap(i1, i1).
67struct G {
68 friend void iter_swap(const PointerTo<G>&, const PointerTo<G>&);
69 friend void iter_swap(const PointerTo<F>&, const PointerTo<G>&);
70 friend void iter_swap(const PointerTo<G>&, const PointerTo<F>&);
71};
72
73
74static_assert( std::indirectly_swappable<PointerTo<A>, PointerTo<B>>);
75static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<C>>);
76static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<D>>);
77static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<E>>);
78static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<G>>);
79

source code of libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp