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