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 iterator& operator++(); 13 // constexpr void operator++(int); 14 // constexpr iterator operator++(int) 15 // requires ref-is-glvalue && forward_range<Base> && 16 // forward_range<range_reference_t<Base>>; 17 18 #include <cassert> 19 #include <ranges> 20 21 #include "test_macros.h" 22 #include "../types.h" 23 24 constexpr bool test() { 25 // This way if we read past end we'll catch the error. 26 int buffer1[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; 27 int dummy = 42; 28 (void) dummy; 29 int buffer2[2][4] = {{9, 10, 11, 12}, {13, 14, 15, 16}}; 30 31 // operator++(int); 32 { 33 std::ranges::join_view jv(buffer1); 34 auto iter = jv.begin(); 35 for (int i = 1; i < 9; ++i) { 36 assert(*iter++ == i); 37 } 38 } 39 40 { 41 ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])}; 42 std::ranges::join_view jv(ValueView<ValueView<int>>{children}); 43 auto iter = jv.begin(); 44 for (int i = 1; i < 17; ++i) { 45 assert(*iter == i); 46 iter++; 47 } 48 49 ASSERT_SAME_TYPE(decltype(iter++), void); 50 } 51 52 { 53 std::ranges::join_view jv(buffer1); 54 auto iter = std::next(jv.begin(), 7); 55 assert(*iter++ == 8); 56 assert(iter == jv.end()); 57 } 58 59 { 60 int small[2][1] = {{1}, {2}}; 61 std::ranges::join_view jv(small); 62 auto iter = jv.begin(); 63 for (int i = 1; i < 3; ++i) { 64 assert(*iter++ == i); 65 } 66 } 67 68 // Has some empty children. 69 { 70 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 1), CopyableChild(buffer2[1], 0)}; 71 auto jv = std::ranges::join_view(ParentView(children)); 72 auto iter = jv.begin(); 73 assert(*iter == 1); iter++; 74 assert(*iter == 2); iter++; 75 assert(*iter == 3); iter++; 76 assert(*iter == 4); iter++; 77 assert(*iter == 9); iter++; 78 assert(iter == jv.end()); 79 } 80 81 // Parent is empty. 82 { 83 CopyableChild children[4] = {CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])}; 84 std::ranges::join_view jv(ParentView(children, 0)); 85 assert(jv.begin() == jv.end()); 86 } 87 88 // Parent size is one. 89 { 90 CopyableChild children[1] = {CopyableChild(buffer1[0])}; 91 std::ranges::join_view jv(ParentView(children, 1)); 92 auto iter = jv.begin(); 93 assert(*iter == 1); iter++; 94 assert(*iter == 2); iter++; 95 assert(*iter == 3); iter++; 96 assert(*iter == 4); iter++; 97 assert(iter == jv.end()); 98 } 99 100 // Parent and child size is one. 101 { 102 CopyableChild children[1] = {CopyableChild(buffer1[0], 1)}; 103 std::ranges::join_view jv(ParentView(children, 1)); 104 auto iter = jv.begin(); 105 assert(*iter == 1); iter++; 106 assert(iter == jv.end()); 107 } 108 109 // Parent size is one child is empty 110 { 111 CopyableChild children[1] = {CopyableChild(buffer1[0], 0)}; 112 std::ranges::join_view jv(ParentView(children, 1)); 113 assert(jv.begin() == jv.end()); 114 } 115 116 // Has all empty children. 117 { 118 CopyableChild children[4] = {CopyableChild(buffer1[0], 0), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)}; 119 auto jv = std::ranges::join_view(ParentView(children)); 120 assert(jv.begin() == jv.end()); 121 } 122 123 // First child is empty, others are not. 124 { 125 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)}; 126 auto jv = std::ranges::join_view(ParentView(children)); 127 auto iter = jv.begin(); 128 assert(*iter == 1); iter++; 129 assert(*iter == 2); iter++; 130 assert(*iter == 3); iter++; 131 assert(*iter == 4); iter++; 132 assert(iter == jv.end()); 133 } 134 135 // Last child is empty, others are not. 136 { 137 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 4), CopyableChild(buffer2[0], 4), CopyableChild(buffer2[1], 0)}; 138 auto jv = std::ranges::join_view(ParentView(children)); 139 auto iter = jv.begin(); 140 for (int i = 1; i < 13; ++i) { 141 assert(*iter == i); 142 iter++; 143 } 144 } 145 146 // operator++(); 147 { 148 std::ranges::join_view jv(buffer1); 149 auto iter = jv.begin(); 150 for (int i = 2; i < 9; ++i) { 151 assert(*++iter == i); 152 } 153 } 154 155 { 156 ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])}; 157 std::ranges::join_view jv(ValueView<ValueView<int>>{children}); 158 auto iter = jv.begin(); 159 for (int i = 2; i < 17; ++i) { 160 assert(*++iter == i); 161 } 162 163 ASSERT_SAME_TYPE(decltype(++iter), decltype(iter)&); 164 } 165 166 { 167 // check return value 168 std::ranges::join_view jv(buffer1); 169 auto iter = jv.begin(); 170 using iterator = decltype(iter); 171 172 decltype(auto) iter2 = ++iter; 173 static_assert(std::is_same_v<decltype(iter2), iterator&>); 174 assert(&iter2 == &iter); 175 176 std::same_as<iterator> decltype(auto) iter3 = iter++; 177 assert(std::next(iter3) == iter); 178 } 179 180 { 181 // !ref-is-glvalue 182 BidiCommonInner inners[2] = {buffer1[0], buffer1[1]}; 183 InnerRValue<BidiCommonOuter<BidiCommonInner>> outer{inners}; 184 std::ranges::join_view jv(outer); 185 auto iter = jv.begin(); 186 static_assert(std::is_void_v<decltype(iter++)>); 187 } 188 189 { 190 // !forward_range<Base> 191 BufferView<int*> inners[2] = {buffer1[0], buffer1[1]}; 192 using Outer = SimpleInputCommonOuter<BufferView<int*>>; 193 std::ranges::join_view jv{Outer(inners)}; 194 auto iter = jv.begin(); 195 static_assert(std::is_void_v<decltype(iter++)>); 196 } 197 198 { 199 // !forward_range<range_reference_t<Base>> 200 InputCommonInner inners[1] = {buffer1[0]}; 201 std::ranges::join_view jv{inners}; 202 auto iter = jv.begin(); 203 static_assert(std::is_void_v<decltype(iter++)>); 204 } 205 206 return true; 207 } 208 209 int main(int, char**) { 210 test(); 211 static_assert(test()); 212 213 return 0; 214 } 215