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 #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_DROP_TYPES_H 10 #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_DROP_TYPES_H 11 12 #include "test_macros.h" 13 #include "test_iterators.h" 14 15 int globalBuff[8]; 16 17 template <class T> 18 struct drop_sentinel { 19 T* ptr_; 20 int* num_of_sentinel_cmp_calls; 21 22 public: 23 friend constexpr bool operator==(drop_sentinel const s, T* const ptr) noexcept { 24 ++(*s.num_of_sentinel_cmp_calls); 25 return {s.ptr_ == ptr}; 26 } 27 friend constexpr bool operator==(T* const ptr, drop_sentinel const s) noexcept { 28 ++(*s.num_of_sentinel_cmp_calls); 29 return {s.ptr_ == ptr}; 30 } 31 friend constexpr bool operator!=(drop_sentinel const s, T* const ptr) noexcept { return !(s == ptr); } 32 friend constexpr bool operator!=(T* const ptr, drop_sentinel const s) noexcept { return !(s == ptr); } 33 }; 34 35 template <bool IsSimple> 36 struct MaybeSimpleNonCommonView : std::ranges::view_base { 37 int start_; 38 int* num_of_sentinel_cmp_calls; 39 constexpr std::size_t size() const { return 8; } 40 constexpr int* begin() { return globalBuff + start_; } 41 constexpr std::conditional_t<IsSimple, int*, const int*> begin() const { return globalBuff + start_; } 42 constexpr drop_sentinel<int> end() { return drop_sentinel<int>{globalBuff + size(), num_of_sentinel_cmp_calls}; } 43 constexpr auto end() const { 44 return std::conditional_t<IsSimple, drop_sentinel<int>, drop_sentinel<const int>>{ 45 globalBuff + size(), num_of_sentinel_cmp_calls}; 46 } 47 }; 48 49 struct MoveOnlyView : std::ranges::view_base { 50 int start_; 51 constexpr explicit MoveOnlyView(int start = 0) : start_(start) {} 52 constexpr MoveOnlyView(MoveOnlyView&&) = default; 53 constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; 54 constexpr int *begin() const { return globalBuff + start_; } 55 constexpr int *end() const { return globalBuff + 8; } 56 }; 57 static_assert( std::ranges::view<MoveOnlyView>); 58 static_assert( std::ranges::contiguous_range<MoveOnlyView>); 59 static_assert(!std::copyable<MoveOnlyView>); 60 61 struct CopyableView : std::ranges::view_base { 62 int start_; 63 constexpr explicit CopyableView(int start = 0) : start_(start) {} 64 constexpr CopyableView(CopyableView const&) = default; 65 constexpr CopyableView& operator=(CopyableView const&) = default; 66 constexpr int *begin() const { return globalBuff + start_; } 67 constexpr int *end() const { return globalBuff + 8; } 68 }; 69 70 using ForwardIter = forward_iterator<int*>; 71 struct ForwardView : std::ranges::view_base { 72 constexpr explicit ForwardView() = default; 73 constexpr ForwardView(ForwardView&&) = default; 74 constexpr ForwardView& operator=(ForwardView&&) = default; 75 constexpr forward_iterator<int*> begin() const { return forward_iterator<int*>(globalBuff); } 76 constexpr forward_iterator<int*> end() const { return forward_iterator<int*>(globalBuff + 8); } 77 }; 78 79 struct ForwardRange { 80 ForwardIter begin() const; 81 ForwardIter end() const; 82 }; 83 84 struct ThrowingDefaultCtorForwardView : std::ranges::view_base { 85 ThrowingDefaultCtorForwardView() noexcept(false); 86 ForwardIter begin() const; 87 ForwardIter end() const; 88 }; 89 90 struct NoDefaultCtorForwardView : std::ranges::view_base { 91 NoDefaultCtorForwardView() = delete; 92 ForwardIter begin() const; 93 ForwardIter end() const; 94 }; 95 96 struct BorrowableRange { 97 int *begin() const; 98 int *end() const; 99 }; 100 template<> 101 inline constexpr bool std::ranges::enable_borrowed_range<BorrowableRange> = true; 102 103 struct BorrowableView : std::ranges::view_base { 104 int *begin() const; 105 int *end() const; 106 }; 107 template<> 108 inline constexpr bool std::ranges::enable_borrowed_range<BorrowableView> = true; 109 110 struct InputView : std::ranges::view_base { 111 constexpr cpp20_input_iterator<int*> begin() const { return cpp20_input_iterator<int*>(globalBuff); } 112 constexpr int* end() const { return globalBuff + 8; } 113 }; 114 // TODO: remove these bogus operators 115 constexpr bool operator==(const cpp20_input_iterator<int*> &lhs, int* rhs) { return base(lhs) == rhs; } 116 constexpr bool operator==(int* lhs, const cpp20_input_iterator<int*> &rhs) { return base(rhs) == lhs; } 117 118 struct Range { 119 int *begin() const; 120 int *end() const; 121 }; 122 123 using CountedIter = operation_counting_iterator<forward_iterator<int*>>; 124 struct CountedView : std::ranges::view_base { 125 explicit constexpr CountedView(IteratorOpCounts* opcounts) noexcept : opcounts_(opcounts) {} 126 constexpr CountedIter begin() const { return CountedIter(ForwardIter(globalBuff), opcounts_); } 127 constexpr CountedIter end() const { return CountedIter(ForwardIter(globalBuff + 8), opcounts_); } 128 129 private: 130 IteratorOpCounts* opcounts_; 131 }; 132 133 struct View : std::ranges::view_base { 134 constexpr explicit View(int* b, int* e) : begin_(b), end_(e) { } 135 136 constexpr int* begin() const { return begin_; } 137 constexpr int* end() const { return end_; } 138 139 private: 140 int* begin_; 141 int* end_; 142 }; 143 144 #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_DROP_TYPES_H 145