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