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 // constexpr inner-iterator& inner-iterator::operator++(); 13 // 14 // constexpr decltype(auto) inner-iterator::operator++(int); 15 16 #include <ranges> 17 18 #include <cassert> 19 #include <type_traits> 20 #include "test_macros.h" 21 #include "../types.h" 22 23 struct EmptyView : std::ranges::view_base { 24 constexpr int* begin() const { return nullptr; } 25 constexpr int* end() const { return nullptr; } 26 constexpr static size_t size() { return 0; } 27 }; 28 static_assert(std::ranges::forward_range<EmptyView>); 29 static_assert(std::ranges::view<EmptyView>); 30 LIBCPP_STATIC_ASSERT(std::ranges::__tiny_range<EmptyView>); 31 32 constexpr bool test() { 33 // Can call `inner-iterator::operator++`; `View` is a forward range. 34 { 35 SplitViewForward v("abc def", " "); 36 auto val = *v.begin(); 37 38 // ++i 39 { 40 auto i = val.begin(); 41 assert(*i == 'a'); 42 43 decltype(auto) i2 = ++i; 44 static_assert(std::is_lvalue_reference_v<decltype(i2)>); 45 assert(&i2 == &i); 46 assert(*i2 == 'b'); 47 } 48 49 // i++ 50 { 51 auto i = val.begin(); 52 assert(*i == 'a'); 53 54 decltype(auto) i2 = i++; 55 static_assert(!std::is_reference_v<decltype(i2)>); 56 assert(*i2 == 'a'); 57 assert(*i == 'b'); 58 } 59 } 60 61 // Can call `inner-iterator::operator++`; `View` is an input range. 62 { 63 // ++i 64 { 65 SplitViewInput v("abc def", ' '); 66 auto val = *v.begin(); 67 68 auto i = val.begin(); 69 assert(*i == 'a'); 70 71 decltype(auto) i2 = ++i; 72 static_assert(std::is_lvalue_reference_v<decltype(i2)>); 73 assert(&i2 == &i); 74 assert(*i2 == 'b'); 75 } 76 77 // i++ 78 { 79 SplitViewInput v("abc def", ' '); 80 auto val = *v.begin(); 81 82 auto i = val.begin(); 83 assert(*i == 'a'); 84 85 static_assert(std::is_void_v<decltype(i++)>); 86 i++; 87 assert(*i == 'b'); 88 } 89 } 90 91 // Can call `inner-iterator::operator++`; `View` is an input range and `Pattern` is an "empty" range. 92 { 93 // ++i 94 { 95 std::ranges::lazy_split_view<InputView, EmptyView> v("a", EmptyView()); 96 auto val = *v.begin(); 97 98 auto i = val.begin(); 99 assert(*i.base() == 'a'); 100 assert(i != std::default_sentinel); 101 102 // The iterator doesn't move to the next character but is considered to point to the end. 103 decltype(auto) i2 = ++i; 104 assert(&i2 == &i); 105 assert(*i2.base() == 'a'); 106 assert(i2 == std::default_sentinel); 107 } 108 109 // i++ 110 { 111 std::ranges::lazy_split_view<InputView, EmptyView> v("a", EmptyView()); 112 auto val = *v.begin(); 113 114 auto i = val.begin(); 115 assert(*i.base() == 'a'); 116 assert(i != std::default_sentinel); 117 118 // The iterator doesn't move to the next character but is considered to point to the end. 119 i++; 120 assert(*i.base() == 'a'); 121 assert(i == std::default_sentinel); 122 } 123 } 124 125 return true; 126 } 127 128 int main(int, char**) { 129 test(); 130 static_assert(test()); 131 132 return 0; 133 } 134