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<indirectly_swappable<I> I2>
12// friend constexpr void
13// iter_swap(const counted_iterator& x, const counted_iterator<I2>& y)
14// noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
15
16#include <iterator>
17
18#include "test_macros.h"
19#include "test_iterators.h"
20
21template<bool IsNoexcept>
22class HasNoexceptIterSwap
23{
24 int *it_;
25
26public:
27 typedef std::input_iterator_tag iterator_category;
28 typedef int value_type;
29 typedef typename std::iterator_traits<int *>::difference_type difference_type;
30 typedef int * pointer;
31 typedef int & reference;
32
33 constexpr int *base() const {return it_;}
34
35 HasNoexceptIterSwap() = default;
36 explicit constexpr HasNoexceptIterSwap(int *it) : it_(it) {}
37
38 constexpr reference operator*() const {return *it_;}
39
40 constexpr HasNoexceptIterSwap& operator++() {++it_; return *this;}
41 constexpr HasNoexceptIterSwap operator++(int)
42 {HasNoexceptIterSwap tmp(*this); ++(*this); return tmp;}
43
44 friend void iter_swap(
45 const HasNoexceptIterSwap&, const HasNoexceptIterSwap&) noexcept(IsNoexcept) {}
46};
47
48constexpr bool test() {
49 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
50
51 {
52 auto iter1 = cpp17_input_iterator<int*>(buffer);
53 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
54 auto commonIter2 = std::counted_iterator<decltype(iter1)>(iter1, 8);
55 for (auto i = 0; i < 4; ++i) ++commonIter2;
56 assert(*commonIter2 == 5);
57 std::ranges::iter_swap(commonIter1, commonIter2);
58 assert(*commonIter1 == 5);
59 assert(*commonIter2 == 1);
60 std::ranges::iter_swap(commonIter2, commonIter1);
61 }
62 {
63 auto iter1 = forward_iterator<int*>(buffer);
64 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
65 auto commonIter2 = std::counted_iterator<decltype(iter1)>(iter1, 8);
66 for (auto i = 0; i < 4; ++i) ++commonIter2;
67 assert(*commonIter2 == 5);
68 std::ranges::iter_swap(commonIter1, commonIter2);
69 assert(*commonIter1 == 5);
70 assert(*commonIter2 == 1);
71 std::ranges::iter_swap(commonIter2, commonIter1);
72 }
73 {
74 auto iter1 = random_access_iterator<int*>(buffer);
75 auto commonIter1 = std::counted_iterator<decltype(iter1)>(iter1, 8);
76 auto commonIter2 = std::counted_iterator<decltype(iter1)>(iter1, 8);
77 for (auto i = 0; i < 4; ++i) ++commonIter2;
78 assert(*commonIter2 == 5);
79 std::ranges::iter_swap(commonIter1, commonIter2);
80 assert(*commonIter1 == 5);
81 assert(*commonIter2 == 1);
82 std::ranges::iter_swap(commonIter2, commonIter1);
83 }
84
85 // Test noexceptness.
86 {
87 static_assert( noexcept(std::ranges::iter_swap(
88 std::declval<std::counted_iterator<HasNoexceptIterSwap<true>>&>(),
89 std::declval<std::counted_iterator<HasNoexceptIterSwap<true>>&>()
90 )));
91 static_assert(!noexcept(std::ranges::iter_swap(
92 std::declval<std::counted_iterator<HasNoexceptIterSwap<false>>&>(),
93 std::declval<std::counted_iterator<HasNoexceptIterSwap<false>>&>()
94 )));
95 }
96
97 return true;
98}
99
100int main(int, char**) {
101 test();
102 static_assert(test());
103
104 return 0;
105}
106

source code of libcxx/test/std/iterators/predef.iterators/counted.iterator/iter_swap.pass.cpp