xref: /llvm-project/libcxx/test/std/iterators/predef.iterators/counted.iterator/iter_swap.pass.cpp (revision d2baefae6846765eef6a6dd69d4fdf1082ce29ad)
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 
21 template<bool IsNoexcept>
22 class HasNoexceptIterSwap
23 {
24   int *it_;
25 
26 public:
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 
base() const33   constexpr int *base() const {return it_;}
34 
35   HasNoexceptIterSwap() = default;
HasNoexceptIterSwap(int * it)36   explicit constexpr HasNoexceptIterSwap(int *it) : it_(it) {}
37 
operator *() const38   constexpr reference operator*() const {return *it_;}
39 
operator ++()40   constexpr HasNoexceptIterSwap& operator++() {++it_; return *this;}
operator ++(int)41   constexpr HasNoexceptIterSwap operator++(int)
42       {HasNoexceptIterSwap tmp(*this); ++(*this); return tmp;}
43 
iter_swap(const HasNoexceptIterSwap &,const HasNoexceptIterSwap &)44   friend void iter_swap(
45     const HasNoexceptIterSwap&, const HasNoexceptIterSwap&) noexcept(IsNoexcept) {}
46 };
47 
test()48 constexpr 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 
main(int,char **)100 int main(int, char**) {
101   test();
102   static_assert(test());
103 
104   return 0;
105 }
106