1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<indirectly_swappable<I> I2, class S2>
12 // friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
13 // noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
17 #include <type_traits>
19 #include "test_iterators.h"
20 #include "test_macros.h"
23 struct IterSwappingIt
{
24 using value_type
= int;
25 using difference_type
= int;
26 constexpr explicit IterSwappingIt(int *swaps
) : swaps_(swaps
) {}
27 IterSwappingIt(const IterSwappingIt
&); // copyable, but this test shouldn't make copies
28 IterSwappingIt(IterSwappingIt
&&) = default;
29 IterSwappingIt
& operator=(const IterSwappingIt
&);
30 int& operator*() const;
31 constexpr IterSwappingIt
& operator++() { return *this; }
32 IterSwappingIt
operator++(int);
35 friend constexpr int iter_swap(const IterSwappingIt
<K
>& lhs
, const IterSwappingIt
<L
>& rhs
) {
38 return 42; // should be accepted but ignored
41 bool operator==(std::default_sentinel_t
) const;
43 int *swaps_
= nullptr;
45 static_assert(std::input_iterator
<IterSwappingIt
<0>>);
46 static_assert(std::indirectly_swappable
<IterSwappingIt
<0>, IterSwappingIt
<0>>);
47 static_assert(std::indirectly_swappable
<IterSwappingIt
<0>, IterSwappingIt
<1>>);
49 constexpr bool test() {
52 using CommonIt
= std::common_iterator
<It
, sentinel_wrapper
<It
>>;
53 static_assert(std::indirectly_swappable
<CommonIt
, CommonIt
>);
56 CommonIt it
= CommonIt(It(a
));
57 CommonIt jt
= CommonIt(It(a
+1));
58 ASSERT_NOEXCEPT(iter_swap(it
, jt
));
59 ASSERT_SAME_TYPE(decltype(iter_swap(it
, jt
)), void);
65 using It
= const int*;
66 using CommonIt
= std::common_iterator
<It
, sentinel_wrapper
<It
>>;
67 static_assert(!std::indirectly_swappable
<CommonIt
, CommonIt
>);
70 using It
= IterSwappingIt
<0>;
71 using CommonIt
= std::common_iterator
<It
, std::default_sentinel_t
>;
72 static_assert(std::indirectly_swappable
<CommonIt
, CommonIt
>);
76 CommonIt it
= CommonIt(It(&iswaps
));
77 CommonIt jt
= CommonIt(It(&jswaps
));
78 ASSERT_NOT_NOEXCEPT(iter_swap(it
, jt
));
79 ASSERT_SAME_TYPE(decltype(iter_swap(it
, jt
)), void);
80 iter_swap(it
, jt
); // lvalue iterators
81 assert(iswaps
== 110);
82 assert(jswaps
== 101);
83 iter_swap(CommonIt(It(&iswaps
)), CommonIt(It(&jswaps
))); // rvalue iterators
84 assert(iswaps
== 120);
85 assert(jswaps
== 102);
86 std::ranges::iter_swap(it
, jt
);
87 assert(iswaps
== 130);
88 assert(jswaps
== 103);
91 using It
= IterSwappingIt
<0>;
92 using Jt
= IterSwappingIt
<1>;
93 static_assert(std::indirectly_swappable
<It
, Jt
>);
94 using CommonIt
= std::common_iterator
<It
, std::default_sentinel_t
>;
95 using CommonJt
= std::common_iterator
<Jt
, std::default_sentinel_t
>;
96 static_assert(std::indirectly_swappable
<CommonIt
, CommonJt
>);
100 CommonIt it
= CommonIt(It(&iswaps
));
101 CommonJt jt
= CommonJt(Jt(&jswaps
));
102 ASSERT_NOT_NOEXCEPT(iter_swap(it
, jt
));
103 ASSERT_SAME_TYPE(decltype(iter_swap(it
, jt
)), void);
104 iter_swap(it
, jt
); // lvalue iterators
105 assert(iswaps
== 110);
106 assert(jswaps
== 101);
107 iter_swap(CommonIt(It(&iswaps
)), CommonJt(Jt(&jswaps
))); // rvalue iterators
108 assert(iswaps
== 120);
109 assert(jswaps
== 102);
110 std::ranges::iter_swap(it
, jt
);
111 assert(iswaps
== 130);
112 assert(jswaps
== 103);
117 int main(int, char**) {
119 static_assert(test());