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_ZIP_TYPES_H 10 #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H 11 12 #include <functional> 13 #include <ranges> 14 15 #include "test_macros.h" 16 #include "test_iterators.h" 17 #include "test_range.h" 18 19 #if TEST_STD_VER <= 20 20 # error "range.zip/types.h" can only be included in builds supporting C++20 21 #endif // TEST_STD_VER <= 20 22 23 template <class T> 24 struct BufferView : std::ranges::view_base { 25 T* buffer_; 26 std::size_t size_; 27 28 template <std::size_t N> BufferViewBufferView29 constexpr BufferView(T (&b)[N]) : buffer_(b), size_(N) {} 30 }; 31 32 using IntBufferView = BufferView<int>; 33 34 template <bool Simple> 35 struct Common : IntBufferView { 36 using IntBufferView::IntBufferView; 37 beginCommon38 constexpr int* begin() 39 requires(!Simple) 40 { 41 return buffer_; 42 } beginCommon43 constexpr const int* begin() const { return buffer_; } endCommon44 constexpr int* end() 45 requires(!Simple) 46 { 47 return buffer_ + size_; 48 } endCommon49 constexpr const int* end() const { return buffer_ + size_; } 50 }; 51 using SimpleCommon = Common<true>; 52 using NonSimpleCommon = Common<false>; 53 54 using SimpleCommonRandomAccessSized = SimpleCommon; 55 using NonSimpleCommonRandomAccessSized = NonSimpleCommon; 56 57 static_assert(std::ranges::common_range<Common<true>>); 58 static_assert(std::ranges::random_access_range<SimpleCommon>); 59 static_assert(std::ranges::sized_range<SimpleCommon>); 60 static_assert(simple_view<SimpleCommon>); 61 static_assert(!simple_view<NonSimpleCommon>); 62 63 template <bool Simple> 64 struct CommonNonRandom : IntBufferView { 65 using IntBufferView::IntBufferView; 66 using const_iterator = forward_iterator<const int*>; 67 using iterator = forward_iterator<int*>; beginCommonNonRandom68 constexpr iterator begin() 69 requires(!Simple) { 70 return iterator(buffer_); 71 } beginCommonNonRandom72 constexpr const_iterator begin() const { return const_iterator(buffer_); } endCommonNonRandom73 constexpr iterator end() 74 requires(!Simple) { 75 return iterator(buffer_ + size_); 76 } endCommonNonRandom77 constexpr const_iterator end() const { return const_iterator(buffer_ + size_); } 78 }; 79 80 using SimpleCommonNonRandom = CommonNonRandom<true>; 81 using NonSimpleCommonNonRandom = CommonNonRandom<false>; 82 83 static_assert(std::ranges::common_range<SimpleCommonNonRandom>); 84 static_assert(!std::ranges::random_access_range<SimpleCommonNonRandom>); 85 static_assert(!std::ranges::sized_range<SimpleCommonNonRandom>); 86 static_assert(simple_view<SimpleCommonNonRandom>); 87 static_assert(!simple_view<NonSimpleCommonNonRandom>); 88 89 template <bool Simple> 90 struct NonCommon : IntBufferView { 91 using IntBufferView::IntBufferView; beginNonCommon92 constexpr int* begin() 93 requires(!Simple) { 94 return buffer_; 95 } beginNonCommon96 constexpr const int* begin() const { return buffer_; } endNonCommon97 constexpr sentinel_wrapper<int*> end() 98 requires(!Simple) { 99 return sentinel_wrapper<int*>(buffer_ + size_); 100 } endNonCommon101 constexpr sentinel_wrapper<const int*> end() const { return sentinel_wrapper<const int*>(buffer_ + size_); } 102 }; 103 104 using SimpleNonCommon = NonCommon<true>; 105 using NonSimpleNonCommon = NonCommon<false>; 106 107 static_assert(!std::ranges::common_range<SimpleNonCommon>); 108 static_assert(std::ranges::random_access_range<SimpleNonCommon>); 109 static_assert(!std::ranges::sized_range<SimpleNonCommon>); 110 static_assert(simple_view<SimpleNonCommon>); 111 static_assert(!simple_view<NonSimpleNonCommon>); 112 113 template <bool Simple> 114 struct NonCommonSized : IntBufferView { 115 using IntBufferView::IntBufferView; beginNonCommonSized116 constexpr int* begin() 117 requires(!Simple) { 118 return buffer_; 119 } beginNonCommonSized120 constexpr const int* begin() const { return buffer_; } endNonCommonSized121 constexpr sentinel_wrapper<int*> end() 122 requires(!Simple) { 123 return sentinel_wrapper<int*>(buffer_ + size_); 124 } endNonCommonSized125 constexpr sentinel_wrapper<const int*> end() const { return sentinel_wrapper<const int*>(buffer_ + size_); } sizeNonCommonSized126 constexpr std::size_t size() const { return size_; } 127 }; 128 129 using SimpleNonCommonSized = NonCommonSized<true>; 130 using SimpleNonCommonRandomAccessSized = SimpleNonCommonSized; 131 using NonSimpleNonCommonSized = NonCommonSized<false>; 132 using NonSimpleNonCommonRandomAccessSized = NonSimpleNonCommonSized; 133 134 static_assert(!std::ranges::common_range<SimpleNonCommonSized>); 135 static_assert(std::ranges::random_access_range<SimpleNonCommonSized>); 136 static_assert(std::ranges::sized_range<SimpleNonCommonSized>); 137 static_assert(simple_view<SimpleNonCommonSized>); 138 static_assert(!simple_view<NonSimpleNonCommonSized>); 139 140 template <bool Simple> 141 struct NonCommonNonRandom : IntBufferView { 142 using IntBufferView::IntBufferView; 143 144 using const_iterator = forward_iterator<const int*>; 145 using iterator = forward_iterator<int*>; 146 beginNonCommonNonRandom147 constexpr iterator begin() 148 requires(!Simple) { 149 return iterator(buffer_); 150 } beginNonCommonNonRandom151 constexpr const_iterator begin() const { return const_iterator(buffer_); } endNonCommonNonRandom152 constexpr sentinel_wrapper<iterator> end() 153 requires(!Simple) { 154 return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); 155 } endNonCommonNonRandom156 constexpr sentinel_wrapper<const_iterator> end() const { 157 return sentinel_wrapper<const_iterator>(const_iterator(buffer_ + size_)); 158 } 159 }; 160 161 using SimpleNonCommonNonRandom = NonCommonNonRandom<true>; 162 using NonSimpleNonCommonNonRandom = NonCommonNonRandom<false>; 163 164 static_assert(!std::ranges::common_range<SimpleNonCommonNonRandom>); 165 static_assert(!std::ranges::random_access_range<SimpleNonCommonNonRandom>); 166 static_assert(!std::ranges::sized_range<SimpleNonCommonNonRandom>); 167 static_assert(simple_view<SimpleNonCommonNonRandom>); 168 static_assert(!simple_view<NonSimpleNonCommonNonRandom>); 169 170 template <class Iter, class Sent = Iter, class NonConstIter = Iter, class NonConstSent = Sent> 171 struct BasicView : IntBufferView { 172 using IntBufferView::IntBufferView; 173 beginBasicView174 constexpr NonConstIter begin() 175 requires(!std::is_same_v<Iter, NonConstIter>) { 176 return NonConstIter(buffer_); 177 } beginBasicView178 constexpr Iter begin() const { return Iter(buffer_); } 179 endBasicView180 constexpr NonConstSent end() 181 requires(!std::is_same_v<Sent, NonConstSent>) { 182 if constexpr (std::is_same_v<NonConstIter, NonConstSent>) { 183 return NonConstIter(buffer_ + size_); 184 } else { 185 return NonConstSent(NonConstIter(buffer_ + size_)); 186 } 187 } 188 endBasicView189 constexpr Sent end() const { 190 if constexpr (std::is_same_v<Iter, Sent>) { 191 return Iter(buffer_ + size_); 192 } else { 193 return Sent(Iter(buffer_ + size_)); 194 } 195 } 196 }; 197 198 template <class Base = int*> 199 struct forward_sized_iterator { 200 Base it_ = nullptr; 201 202 using iterator_category = std::forward_iterator_tag; 203 using value_type = int; 204 using difference_type = std::intptr_t; 205 using pointer = Base; 206 using reference = decltype(*Base{}); 207 208 forward_sized_iterator() = default; forward_sized_iteratorforward_sized_iterator209 constexpr forward_sized_iterator(Base it) : it_(it) {} 210 211 constexpr reference operator*() const { return *it_; } 212 213 constexpr forward_sized_iterator& operator++() { 214 ++it_; 215 return *this; 216 } 217 constexpr forward_sized_iterator operator++(int) { return forward_sized_iterator(it_++); } 218 219 friend constexpr bool operator==(const forward_sized_iterator&, const forward_sized_iterator&) = default; 220 221 friend constexpr difference_type operator-(const forward_sized_iterator& x, const forward_sized_iterator& y) { 222 return x.it_ - y.it_; 223 } 224 }; 225 static_assert(std::forward_iterator<forward_sized_iterator<>>); 226 static_assert(std::sized_sentinel_for<forward_sized_iterator<>, forward_sized_iterator<>>); 227 228 using ForwardSizedView = BasicView<forward_sized_iterator<>>; 229 static_assert(std::ranges::forward_range<ForwardSizedView>); 230 static_assert(std::ranges::sized_range<ForwardSizedView>); 231 static_assert(std::ranges::common_range<ForwardSizedView>); 232 static_assert(!std::ranges::random_access_range<ForwardSizedView>); 233 static_assert(simple_view<ForwardSizedView>); 234 235 using NonSimpleForwardSizedView = BasicView<forward_sized_iterator<const int*>, forward_sized_iterator<const int*>, 236 forward_sized_iterator<int*>, forward_sized_iterator<int*>>; 237 static_assert(std::ranges::forward_range<NonSimpleForwardSizedView>); 238 static_assert(std::ranges::sized_range<NonSimpleForwardSizedView>); 239 static_assert(std::ranges::common_range<NonSimpleForwardSizedView>); 240 static_assert(!std::ranges::random_access_range<NonSimpleForwardSizedView>); 241 static_assert(!simple_view<NonSimpleForwardSizedView>); 242 243 using ForwardSizedNonCommon = BasicView<forward_sized_iterator<>, sized_sentinel<forward_sized_iterator<>>>; 244 static_assert(std::ranges::forward_range<ForwardSizedNonCommon>); 245 static_assert(std::ranges::sized_range<ForwardSizedNonCommon>); 246 static_assert(!std::ranges::common_range<ForwardSizedNonCommon>); 247 static_assert(!std::ranges::random_access_range<ForwardSizedNonCommon>); 248 static_assert(simple_view<ForwardSizedNonCommon>); 249 250 using NonSimpleForwardSizedNonCommon = 251 BasicView<forward_sized_iterator<const int*>, sized_sentinel<forward_sized_iterator<const int*>>, 252 forward_sized_iterator<int*>, sized_sentinel<forward_sized_iterator<int*>>>; 253 static_assert(std::ranges::forward_range<NonSimpleForwardSizedNonCommon>); 254 static_assert(std::ranges::sized_range<NonSimpleForwardSizedNonCommon>); 255 static_assert(!std::ranges::common_range<NonSimpleForwardSizedNonCommon>); 256 static_assert(!std::ranges::random_access_range<NonSimpleForwardSizedNonCommon>); 257 static_assert(!simple_view<NonSimpleForwardSizedNonCommon>); 258 259 struct SizedRandomAccessView : IntBufferView { 260 using IntBufferView::IntBufferView; 261 using iterator = random_access_iterator<int*>; 262 beginSizedRandomAccessView263 constexpr auto begin() const { return iterator(buffer_); } endSizedRandomAccessView264 constexpr auto end() const { return sized_sentinel<iterator>(iterator(buffer_ + size_)); } 265 decltypeSizedRandomAccessView266 constexpr decltype(auto) operator[](std::size_t n) const { return *(begin() + n); } 267 }; 268 static_assert(std::ranges::view<SizedRandomAccessView>); 269 static_assert(std::ranges::random_access_range<SizedRandomAccessView>); 270 static_assert(std::ranges::sized_range<SizedRandomAccessView>); 271 272 using NonSizedRandomAccessView = 273 BasicView<random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>>>; 274 static_assert(!std::ranges::contiguous_range<NonSizedRandomAccessView>); 275 static_assert(std::ranges::random_access_range<SizedRandomAccessView>); 276 static_assert(!std::ranges::common_range<NonSizedRandomAccessView>); 277 static_assert(!std::ranges::sized_range<NonSizedRandomAccessView>); 278 static_assert(simple_view<NonSizedRandomAccessView>); 279 280 using NonSimpleNonSizedRandomAccessView = 281 BasicView<random_access_iterator<const int*>, sentinel_wrapper<random_access_iterator<const int*>>, 282 random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>> >; 283 static_assert(!std::ranges::contiguous_range<NonSimpleNonSizedRandomAccessView>); 284 static_assert(std::ranges::random_access_range<NonSimpleNonSizedRandomAccessView>); 285 static_assert(!std::ranges::common_range<NonSimpleNonSizedRandomAccessView>); 286 static_assert(!std::ranges::sized_range<NonSimpleNonSizedRandomAccessView>); 287 static_assert(!simple_view<NonSimpleNonSizedRandomAccessView>); 288 289 using ContiguousCommonView = BasicView<int*>; 290 static_assert(std::ranges::contiguous_range<ContiguousCommonView>); 291 static_assert(std::ranges::common_range<ContiguousCommonView>); 292 static_assert(std::ranges::sized_range<ContiguousCommonView>); 293 294 using ContiguousNonCommonView = BasicView<int*, sentinel_wrapper<int*>>; 295 static_assert(std::ranges::contiguous_range<ContiguousNonCommonView>); 296 static_assert(!std::ranges::common_range<ContiguousNonCommonView>); 297 static_assert(!std::ranges::sized_range<ContiguousNonCommonView>); 298 299 using ContiguousNonCommonSized = BasicView<int*, sized_sentinel<int*>>; 300 301 static_assert(std::ranges::contiguous_range<ContiguousNonCommonSized>); 302 static_assert(!std::ranges::common_range<ContiguousNonCommonSized>); 303 static_assert(std::ranges::sized_range<ContiguousNonCommonSized>); 304 305 using InputCommonView = BasicView<common_input_iterator<int*>>; 306 static_assert(std::ranges::input_range<InputCommonView>); 307 static_assert(!std::ranges::forward_range<InputCommonView>); 308 static_assert(std::ranges::common_range<InputCommonView>); 309 static_assert(simple_view<InputCommonView>); 310 311 using NonSimpleInputCommonView = BasicView<common_input_iterator<const int*>, common_input_iterator<const int*>, 312 common_input_iterator<int*>, common_input_iterator<int*>>; 313 static_assert(std::ranges::input_range<NonSimpleInputCommonView>); 314 static_assert(!std::ranges::forward_range<NonSimpleInputCommonView>); 315 static_assert(std::ranges::common_range<NonSimpleInputCommonView>); 316 static_assert(!simple_view<NonSimpleInputCommonView>); 317 318 using InputNonCommonView = BasicView<common_input_iterator<int*>, sentinel_wrapper<common_input_iterator<int*>>>; 319 static_assert(std::ranges::input_range<InputNonCommonView>); 320 static_assert(!std::ranges::forward_range<InputNonCommonView>); 321 static_assert(!std::ranges::common_range<InputNonCommonView>); 322 static_assert(simple_view<InputNonCommonView>); 323 324 using NonSimpleInputNonCommonView = 325 BasicView<common_input_iterator<const int*>, sentinel_wrapper<common_input_iterator<const int*>>, 326 common_input_iterator<int*>, sentinel_wrapper<common_input_iterator<int*>>>; 327 static_assert(std::ranges::input_range<InputNonCommonView>); 328 static_assert(!std::ranges::forward_range<InputNonCommonView>); 329 static_assert(!std::ranges::common_range<InputNonCommonView>); 330 static_assert(!simple_view<NonSimpleInputNonCommonView>); 331 332 using BidiCommonView = BasicView<bidirectional_iterator<int*>>; 333 static_assert(!std::ranges::sized_range<BidiCommonView>); 334 static_assert(std::ranges::bidirectional_range<BidiCommonView>); 335 static_assert(!std::ranges::random_access_range<BidiCommonView>); 336 static_assert(std::ranges::common_range<BidiCommonView>); 337 static_assert(simple_view<BidiCommonView>); 338 339 using NonSimpleBidiCommonView = BasicView<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, 340 bidirectional_iterator<int*>, bidirectional_iterator<int*>>; 341 static_assert(!std::ranges::sized_range<NonSimpleBidiCommonView>); 342 static_assert(std::ranges::bidirectional_range<NonSimpleBidiCommonView>); 343 static_assert(!std::ranges::random_access_range<NonSimpleBidiCommonView>); 344 static_assert(std::ranges::common_range<NonSimpleBidiCommonView>); 345 static_assert(!simple_view<NonSimpleBidiCommonView>); 346 347 struct SizedBidiCommon : BidiCommonView { 348 using BidiCommonView::BidiCommonView; sizeSizedBidiCommon349 std::size_t size() const { return base(end()) - base(begin()); } 350 }; 351 static_assert(std::ranges::sized_range<SizedBidiCommon>); 352 static_assert(std::ranges::bidirectional_range<SizedBidiCommon>); 353 static_assert(!std::ranges::random_access_range<SizedBidiCommon>); 354 static_assert(std::ranges::common_range<SizedBidiCommon>); 355 static_assert(simple_view<SizedBidiCommon>); 356 357 struct NonSimpleSizedBidiCommon : NonSimpleBidiCommonView { 358 using NonSimpleBidiCommonView::NonSimpleBidiCommonView; sizeNonSimpleSizedBidiCommon359 std::size_t size() const { return base(end()) - base(begin()); } 360 }; 361 static_assert(std::ranges::sized_range<NonSimpleSizedBidiCommon>); 362 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiCommon>); 363 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiCommon>); 364 static_assert(std::ranges::common_range<NonSimpleSizedBidiCommon>); 365 static_assert(!simple_view<NonSimpleSizedBidiCommon>); 366 367 using BidiNonCommonView = BasicView<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>; 368 static_assert(!std::ranges::sized_range<BidiNonCommonView>); 369 static_assert(std::ranges::bidirectional_range<BidiNonCommonView>); 370 static_assert(!std::ranges::random_access_range<BidiNonCommonView>); 371 static_assert(!std::ranges::common_range<BidiNonCommonView>); 372 static_assert(simple_view<BidiNonCommonView>); 373 374 using NonSimpleBidiNonCommonView = 375 BasicView<bidirectional_iterator<const int*>, sentinel_wrapper<bidirectional_iterator<const int*>>, 376 bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>; 377 static_assert(!std::ranges::sized_range<NonSimpleBidiNonCommonView>); 378 static_assert(std::ranges::bidirectional_range<NonSimpleBidiNonCommonView>); 379 static_assert(!std::ranges::random_access_range<NonSimpleBidiNonCommonView>); 380 static_assert(!std::ranges::common_range<NonSimpleBidiNonCommonView>); 381 static_assert(!simple_view<NonSimpleBidiNonCommonView>); 382 383 using SizedBidiNonCommonView = BasicView<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>; 384 static_assert(std::ranges::sized_range<SizedBidiNonCommonView>); 385 static_assert(std::ranges::bidirectional_range<SizedBidiNonCommonView>); 386 static_assert(!std::ranges::random_access_range<SizedBidiNonCommonView>); 387 static_assert(!std::ranges::common_range<SizedBidiNonCommonView>); 388 static_assert(simple_view<SizedBidiNonCommonView>); 389 390 using NonSimpleSizedBidiNonCommonView = 391 BasicView<bidirectional_iterator<const int*>, sized_sentinel<bidirectional_iterator<const int*>>, 392 bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>; 393 static_assert(std::ranges::sized_range<NonSimpleSizedBidiNonCommonView>); 394 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiNonCommonView>); 395 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiNonCommonView>); 396 static_assert(!std::ranges::common_range<NonSimpleSizedBidiNonCommonView>); 397 static_assert(!simple_view<NonSimpleSizedBidiNonCommonView>); 398 399 namespace adltest{ 400 struct iter_move_swap_iterator { 401 402 std::reference_wrapper<int> iter_move_called_times; 403 std::reference_wrapper<int> iter_swap_called_times; 404 int i = 0; 405 406 using iterator_category = std::input_iterator_tag; 407 using value_type = int; 408 using difference_type = std::intptr_t; 409 410 constexpr int operator*() const { return i; } 411 412 constexpr iter_move_swap_iterator& operator++() { 413 ++i; 414 return *this; 415 } 416 constexpr void operator++(int) { ++i; } 417 418 friend constexpr bool operator==(const iter_move_swap_iterator& x, std::default_sentinel_t) { return x.i == 5; } 419 iter_moveiter_move_swap_iterator420 friend constexpr int iter_move(iter_move_swap_iterator const& it) { 421 ++it.iter_move_called_times; 422 return it.i; 423 } iter_swapiter_move_swap_iterator424 friend constexpr void iter_swap(iter_move_swap_iterator const& x, iter_move_swap_iterator const& y) { 425 ++x.iter_swap_called_times; 426 ++y.iter_swap_called_times; 427 } 428 }; 429 430 struct IterMoveSwapRange { 431 int iter_move_called_times = 0; 432 int iter_swap_called_times = 0; beginIterMoveSwapRange433 constexpr auto begin() { return iter_move_swap_iterator{iter_move_called_times, iter_swap_called_times}; } endIterMoveSwapRange434 constexpr auto end() const { return std::default_sentinel; } 435 }; 436 } // namespace adltest 437 438 #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H 439