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 strong_ordering 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 
base() const33     constexpr It base() const {return it_;}
34 
35     CommonWithForwardIter() = default;
CommonWithForwardIter(It it)36     explicit constexpr CommonWithForwardIter(It it) : it_(it) {}
CommonWithForwardIter(const forward_iterator<It> & it)37     constexpr CommonWithForwardIter(const forward_iterator<It>& it) : it_(it.base()) {}
38 
operator *() const39     constexpr reference operator*() const {return *it_;}
40 
operator ++()41     constexpr CommonWithForwardIter& operator++() {++it_; return *this;}
operator ++(int)42     constexpr CommonWithForwardIter operator++(int)
43         {CommonWithForwardIter tmp(*this); ++(*this); return tmp;}
44 };
45 
test()46 constexpr bool test() {
47   int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
48 
49   auto& Eq = std::strong_ordering::equal;
50   auto& Less = std::strong_ordering::less;
51   auto& Greater = std::strong_ordering::greater;
52 
53   {
54     {
55       std::counted_iterator iter1(forward_iterator<int*>(buffer), 8);
56       std::counted_iterator iter2(CommonWithForwardIter<int*>(buffer), 8);
57 
58       assert((iter1 <=> iter2) == Eq);
59       assert((iter2 <=> iter1) == Eq);
60       ++iter1;
61       assert((iter1 <=> iter2) == Greater);
62       assert((iter2 <=> iter1) == Less);
63     }
64     {
65       std::counted_iterator iter1(forward_iterator<int*>(buffer), 8);
66       std::counted_iterator iter2(forward_iterator<int*>(buffer), 8);
67 
68       assert((iter1 <=> iter2) == Eq);
69       assert((iter2 <=> iter1) == Eq);
70       ++iter1;
71       assert((iter1 <=> iter2) == Greater);
72       assert((iter2 <=> iter1) == Less);
73     }
74   }
75 
76 
77   return true;
78 }
79 
main(int,char **)80 int main(int, char**) {
81   test();
82   static_assert(test());
83 
84   return 0;
85 }
86