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// <iterator>
12
13// move_iterator
14
15// template <class Iter1, three_way_comparable_with<Iter1> Iter2>
16// constexpr auto operator<=>(const move_iterator<Iter1>& x, const move_iterator<Iter2>& y)
17// -> compare_three_way_result_t<Iter1, Iter2>;
18
19#include <iterator>
20#include <cassert>
21
22#include "test_macros.h"
23#include "test_iterators.h"
24
25
26template<class T, class U> concept HasEquals = requires (T t, U u) { t == u; };
27template<class T, class U> concept HasSpaceship = requires (T t, U u) { t <=> u; };
28
29static_assert(!HasSpaceship<std::move_iterator<int*>, std::move_iterator<char*>>);
30static_assert( HasSpaceship<std::move_iterator<int*>, std::move_iterator<int*>>);
31static_assert( HasSpaceship<std::move_iterator<int*>, std::move_iterator<const int*>>);
32static_assert( HasSpaceship<std::move_iterator<const int*>, std::move_iterator<const int*>>);
33static_assert(!HasSpaceship<std::move_iterator<forward_iterator<int*>>, std::move_iterator<forward_iterator<int*>>>);
34static_assert(!HasSpaceship<std::move_iterator<random_access_iterator<int*>>, std::move_iterator<random_access_iterator<int*>>>);
35static_assert(!HasSpaceship<std::move_iterator<contiguous_iterator<int*>>, std::move_iterator<contiguous_iterator<int*>>>);
36static_assert( HasSpaceship<std::move_iterator<three_way_contiguous_iterator<int*>>, std::move_iterator<three_way_contiguous_iterator<int*>>>);
37
38static_assert(!HasSpaceship<std::move_iterator<int*>, std::move_sentinel<int*>>);
39static_assert(!HasSpaceship<std::move_iterator<three_way_contiguous_iterator<int*>>, std::move_sentinel<three_way_contiguous_iterator<int*>>>);
40
41void test_spaceshippable_but_not_three_way_comparable() {
42 struct A {
43 using value_type = int;
44 using difference_type = int;
45 int& operator*() const;
46 A& operator++();
47 A operator++(int);
48 std::strong_ordering operator<=>(const A&) const;
49 };
50 struct B {
51 using value_type = int;
52 using difference_type = int;
53 int& operator*() const;
54 B& operator++();
55 B operator++(int);
56 std::strong_ordering operator<=>(const B&) const;
57 bool operator==(const A&) const;
58 std::strong_ordering operator<=>(const A&) const;
59 };
60 static_assert( std::input_iterator<A>);
61 static_assert( std::input_iterator<B>);
62 static_assert( HasEquals<A, B>);
63 static_assert( HasSpaceship<A, B>);
64 static_assert(!std::three_way_comparable_with<A, B>);
65 static_assert( HasEquals<std::move_iterator<A>, std::move_iterator<B>>);
66 static_assert(!HasSpaceship<std::move_iterator<A>, std::move_iterator<B>>);
67}
68
69template <class It, class Jt>
70constexpr void test_two()
71{
72 int a[] = {3, 1, 4};
73 const std::move_iterator<It> i1 = std::move_iterator<It>(It(a));
74 const std::move_iterator<It> i2 = std::move_iterator<It>(It(a + 2));
75 const std::move_iterator<Jt> j1 = std::move_iterator<Jt>(Jt(a));
76 const std::move_iterator<Jt> j2 = std::move_iterator<Jt>(Jt(a + 2));
77 ASSERT_SAME_TYPE(decltype(i1 <=> i2), std::strong_ordering);
78 assert((i1 <=> i1) == std::strong_ordering::equal);
79 assert((i1 <=> i2) == std::strong_ordering::less);
80 assert((i2 <=> i1) == std::strong_ordering::greater);
81 ASSERT_SAME_TYPE(decltype(i1 <=> j2), std::strong_ordering);
82 assert((i1 <=> j1) == std::strong_ordering::equal);
83 assert((i1 <=> j2) == std::strong_ordering::less);
84 assert((i2 <=> j1) == std::strong_ordering::greater);
85}
86
87constexpr bool test()
88{
89 test_two<int*, int*>();
90 test_two<int*, const int*>();
91 test_two<const int*, int*>();
92 test_two<const int*, const int*>();
93 test_two<three_way_contiguous_iterator<int*>, three_way_contiguous_iterator<int*>>();
94 return true;
95}
96
97int main(int, char**)
98{
99 assert(test());
100 static_assert(test());
101
102 return 0;
103}
104

source code of libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.comp/op_spaceship.pass.cpp