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