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 iter_difference_t<I2> operator-( 13 // const counted_iterator& x, const counted_iterator<I2>& y); 14 15 #include <iterator> 16 17 #include "test_macros.h" 18 #include "test_iterators.h" 19 20 // This iterator is common_with forward_iterator but NOT comparable with it. 21 template <class It> 22 class CommonWithForwardIter 23 { 24 It it_; 25 26 public: 27 typedef std::input_iterator_tag iterator_category; 28 typedef typename std::iterator_traits<It>::value_type value_type; 29 typedef typename std::iterator_traits<It>::difference_type difference_type; 30 typedef It pointer; 31 typedef typename std::iterator_traits<It>::reference reference; 32 33 constexpr It base() const {return it_;} 34 35 CommonWithForwardIter() = default; 36 explicit constexpr CommonWithForwardIter(It it) : it_(it) {} 37 constexpr CommonWithForwardIter(const forward_iterator<It>& it) : it_(it.base()) {} 38 39 constexpr reference operator*() const {return *it_;} 40 41 constexpr CommonWithForwardIter& operator++() {++it_; return *this;} 42 constexpr CommonWithForwardIter operator++(int) 43 {CommonWithForwardIter tmp(*this); ++(*this); return tmp;} 44 }; 45 46 constexpr bool test() { 47 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 48 49 { 50 std::counted_iterator iter1(random_access_iterator<int*>{buffer}, 8); 51 std::counted_iterator iter2(random_access_iterator<int*>{buffer + 4}, 4); 52 assert(iter1 - iter2 == -4); 53 assert(iter2 - iter1 == 4); 54 assert(iter1.count() == 8); 55 assert(iter2.count() == 4); 56 57 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 58 } 59 { 60 const std::counted_iterator iter1(random_access_iterator<int*>{buffer}, 8); 61 const std::counted_iterator iter2(random_access_iterator<int*>{buffer + 4}, 4); 62 assert(iter1 - iter2 == -4); 63 assert(iter2 - iter1 == 4); 64 assert(iter1.count() == 8); 65 assert(iter2.count() == 4); 66 67 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 68 } 69 { 70 std::counted_iterator iter1(contiguous_iterator<int*>{buffer}, 8); 71 std::counted_iterator iter2(contiguous_iterator<int*>{buffer + 2}, 6); 72 assert(iter1 - iter2 == -2); 73 assert(iter2 - iter1 == 2); 74 assert(iter1.count() == 8); 75 assert(iter2.count() == 6); 76 77 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 78 } 79 { 80 const std::counted_iterator iter1(contiguous_iterator<int*>{buffer}, 8); 81 const std::counted_iterator iter2(contiguous_iterator<int*>{buffer + 2}, 6); 82 assert(iter1 - iter2 == -2); 83 assert(iter2 - iter1 == 2); 84 assert(iter1.count() == 8); 85 assert(iter2.count() == 6); 86 87 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 88 } 89 // The minus operator works even if Iter is not a random_access_iterator because 90 // counted_iterator is able to implement it by subtracting the counts rather than 91 // the underlying iterators. 92 { 93 std::counted_iterator iter1(CommonWithForwardIter<int*>{buffer}, 8); 94 std::counted_iterator iter2(forward_iterator<int*>{buffer + 2}, 6); 95 assert(iter1 - iter2 == -2); 96 assert(iter2 - iter1 == 2); 97 assert(iter1.count() == 8); 98 assert(iter2.count() == 6); 99 100 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 101 } 102 { 103 const std::counted_iterator iter1(CommonWithForwardIter<int*>{buffer}, 8); 104 const std::counted_iterator iter2(forward_iterator<int*>{buffer + 2}, 6); 105 assert(iter1 - iter2 == -2); 106 assert(iter2 - iter1 == 2); 107 assert(iter1.count() == 8); 108 assert(iter2.count() == 6); 109 110 ASSERT_SAME_TYPE(decltype(iter1 - iter2), std::iter_difference_t<int*>); 111 } 112 113 return true; 114 } 115 116 int main(int, char**) { 117 test(); 118 static_assert(test()); 119 120 return 0; 121 } 122