xref: /llvm-project/libcxx/test/std/iterators/predef.iterators/counted.iterator/compare.pass.cpp (revision b8cb1dc9ea87faa8e8e9ab7a31710a8c0bb8b084)
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<common_with<I> I2>
12 //   friend constexpr bool operator==(
13 //     const counted_iterator& x, const counted_iterator<I2>& y);
14 // friend constexpr bool operator==(
15 //   const counted_iterator& x, default_sentinel_t);
16 
17 #include <iterator>
18 
19 #include "test_macros.h"
20 #include "test_iterators.h"
21 
22 // This iterator is common_with forward_iterator but NOT comparable with it.
23 template <class It>
24 class CommonWithForwardIter
25 {
26     It it_;
27 
28 public:
29     typedef          std::input_iterator_tag                   iterator_category;
30     typedef typename std::iterator_traits<It>::value_type      value_type;
31     typedef typename std::iterator_traits<It>::difference_type difference_type;
32     typedef It                                                 pointer;
33     typedef typename std::iterator_traits<It>::reference       reference;
34 
base() const35     constexpr It base() const {return it_;}
36 
37     CommonWithForwardIter() = default;
CommonWithForwardIter(It it)38     explicit constexpr CommonWithForwardIter(It it) : it_(it) {}
CommonWithForwardIter(const forward_iterator<It> & it)39     constexpr CommonWithForwardIter(const forward_iterator<It>& it) : it_(it.base()) {}
40 
operator *() const41     constexpr reference operator*() const {return *it_;}
42 
operator ++()43     constexpr CommonWithForwardIter& operator++() {++it_; return *this;}
operator ++(int)44     constexpr CommonWithForwardIter operator++(int)
45         {CommonWithForwardIter tmp(*this); ++(*this); return tmp;}
46 };
47 
48 struct InputOrOutputArchetype {
49   using difference_type = int;
50 
51   int *ptr;
52 
operator *InputOrOutputArchetype53   constexpr int operator*() { return *ptr; }
operator ++InputOrOutputArchetype54   constexpr void operator++(int) { ++ptr; }
operator ++InputOrOutputArchetype55   constexpr InputOrOutputArchetype& operator++() { ++ptr; return *this; }
56 };
57 
test()58 constexpr bool test() {
59   int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
60 
61   {
62     {
63       std::counted_iterator iter1(forward_iterator<int*>(buffer), 8);
64       std::counted_iterator iter2(CommonWithForwardIter<int*>(buffer), 8);
65 
66       assert(iter1 == iter2);
67       assert(iter2 == iter1);
68       ++iter1;
69       assert(iter1 != iter2);
70       assert(iter2 != iter1);
71     }
72   }
73 
74   {
75     {
76       std::counted_iterator iter(cpp20_input_iterator<int*>(buffer), 8);
77 
78       assert(iter != std::default_sentinel);
79       assert(std::default_sentinel == std::ranges::next(std::move(iter), 8));
80     }
81     {
82       std::counted_iterator iter(forward_iterator<int*>(buffer), 8);
83 
84       assert(iter != std::default_sentinel);
85       assert(std::default_sentinel == std::ranges::next(iter, 8));
86     }
87     {
88       std::counted_iterator iter(random_access_iterator<int*>(buffer), 8);
89 
90       assert(iter != std::default_sentinel);
91       assert(std::default_sentinel == std::ranges::next(iter, 8));
92     }
93     {
94       std::counted_iterator iter(InputOrOutputArchetype{buffer}, 8);
95 
96       assert(iter != std::default_sentinel);
97       assert(std::default_sentinel == std::ranges::next(iter, 8));
98     }
99   }
100 
101 
102   return true;
103 }
104 
main(int,char **)105 int main(int, char**) {
106   test();
107   static_assert(test());
108 
109   return 0;
110 }
111