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 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleCommon>); 61 LIBCPP_STATIC_ASSERT(!std::ranges::__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 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleCommonNonRandom>); 87 LIBCPP_STATIC_ASSERT(!std::ranges::__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 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleNonCommon>); 111 LIBCPP_STATIC_ASSERT(!std::ranges::__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 SimpleNonCommonRandomAcessSized = SimpleNonCommonSized; 131 using NonSimpleNonCommonSized = NonCommonSized<false>; 132 using NonSimpleNonCommonRandomAcessSized = 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 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleNonCommonSized>); 138 LIBCPP_STATIC_ASSERT(!std::ranges::__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 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleNonCommonNonRandom>); 168 LIBCPP_STATIC_ASSERT(!std::ranges::__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 = 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 LIBCPP_STATIC_ASSERT(std::ranges::__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 LIBCPP_STATIC_ASSERT(!std::ranges::__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 LIBCPP_STATIC_ASSERT(std::ranges::__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 LIBCPP_STATIC_ASSERT(!std::ranges::__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 LIBCPP_STATIC_ASSERT(std::ranges::__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 LIBCPP_STATIC_ASSERT(!std::ranges::__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 template <class Base = int*> 306 struct common_input_iterator { 307 Base it_; 308 309 using value_type = int; 310 using difference_type = std::intptr_t; 311 using iterator_concept = std::input_iterator_tag; 312 313 constexpr common_input_iterator() = default; common_input_iteratorcommon_input_iterator314 constexpr explicit common_input_iterator(Base it) : it_(it) {} 315 316 constexpr common_input_iterator& operator++() { 317 ++it_; 318 return *this; 319 } 320 constexpr void operator++(int) { ++it_; } 321 322 constexpr int& operator*() const { return *it_; } 323 324 friend constexpr bool operator==(common_input_iterator const&, common_input_iterator const&) = default; 325 }; 326 327 using InputCommonView = BasicView<common_input_iterator<>>; 328 static_assert(std::ranges::input_range<InputCommonView>); 329 static_assert(!std::ranges::forward_range<InputCommonView>); 330 static_assert(std::ranges::common_range<InputCommonView>); 331 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<InputCommonView>); 332 333 using NonSimpleInputCommonView = BasicView<common_input_iterator<const int*>, common_input_iterator<const int*>, 334 common_input_iterator<int*>, common_input_iterator<int*>>; 335 static_assert(std::ranges::input_range<NonSimpleInputCommonView>); 336 static_assert(!std::ranges::forward_range<NonSimpleInputCommonView>); 337 static_assert(std::ranges::common_range<NonSimpleInputCommonView>); 338 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleInputCommonView>); 339 340 using InputNonCommonView = BasicView<common_input_iterator<>, sentinel_wrapper<common_input_iterator<>>>; 341 static_assert(std::ranges::input_range<InputNonCommonView>); 342 static_assert(!std::ranges::forward_range<InputNonCommonView>); 343 static_assert(!std::ranges::common_range<InputNonCommonView>); 344 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<InputNonCommonView>); 345 346 using NonSimpleInputNonCommonView = 347 BasicView<common_input_iterator<const int*>, sentinel_wrapper<common_input_iterator<const int*>>, 348 common_input_iterator<int*>, sentinel_wrapper<common_input_iterator<int*>>>; 349 static_assert(std::ranges::input_range<InputNonCommonView>); 350 static_assert(!std::ranges::forward_range<InputNonCommonView>); 351 static_assert(!std::ranges::common_range<InputNonCommonView>); 352 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleInputNonCommonView>); 353 354 using BidiCommonView = BasicView<bidirectional_iterator<int*>>; 355 static_assert(!std::ranges::sized_range<BidiCommonView>); 356 static_assert(std::ranges::bidirectional_range<BidiCommonView>); 357 static_assert(!std::ranges::random_access_range<BidiCommonView>); 358 static_assert(std::ranges::common_range<BidiCommonView>); 359 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<BidiCommonView>); 360 361 using NonSimpleBidiCommonView = BasicView<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, 362 bidirectional_iterator<int*>, bidirectional_iterator<int*>>; 363 static_assert(!std::ranges::sized_range<NonSimpleBidiCommonView>); 364 static_assert(std::ranges::bidirectional_range<NonSimpleBidiCommonView>); 365 static_assert(!std::ranges::random_access_range<NonSimpleBidiCommonView>); 366 static_assert(std::ranges::common_range<NonSimpleBidiCommonView>); 367 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleBidiCommonView>); 368 369 struct SizedBidiCommon : BidiCommonView { 370 using BidiCommonView::BidiCommonView; sizeSizedBidiCommon371 std::size_t size() const { return base(end()) - base(begin()); } 372 }; 373 static_assert(std::ranges::sized_range<SizedBidiCommon>); 374 static_assert(std::ranges::bidirectional_range<SizedBidiCommon>); 375 static_assert(!std::ranges::random_access_range<SizedBidiCommon>); 376 static_assert(std::ranges::common_range<SizedBidiCommon>); 377 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SizedBidiCommon>); 378 379 struct NonSimpleSizedBidiCommon : NonSimpleBidiCommonView { 380 using NonSimpleBidiCommonView::NonSimpleBidiCommonView; sizeNonSimpleSizedBidiCommon381 std::size_t size() const { return base(end()) - base(begin()); } 382 }; 383 static_assert(std::ranges::sized_range<NonSimpleSizedBidiCommon>); 384 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiCommon>); 385 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiCommon>); 386 static_assert(std::ranges::common_range<NonSimpleSizedBidiCommon>); 387 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleSizedBidiCommon>); 388 389 using BidiNonCommonView = BasicView<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>; 390 static_assert(!std::ranges::sized_range<BidiNonCommonView>); 391 static_assert(std::ranges::bidirectional_range<BidiNonCommonView>); 392 static_assert(!std::ranges::random_access_range<BidiNonCommonView>); 393 static_assert(!std::ranges::common_range<BidiNonCommonView>); 394 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<BidiNonCommonView>); 395 396 using NonSimpleBidiNonCommonView = 397 BasicView<bidirectional_iterator<const int*>, sentinel_wrapper<bidirectional_iterator<const int*>>, 398 bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>; 399 static_assert(!std::ranges::sized_range<NonSimpleBidiNonCommonView>); 400 static_assert(std::ranges::bidirectional_range<NonSimpleBidiNonCommonView>); 401 static_assert(!std::ranges::random_access_range<NonSimpleBidiNonCommonView>); 402 static_assert(!std::ranges::common_range<NonSimpleBidiNonCommonView>); 403 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleBidiNonCommonView>); 404 405 using SizedBidiNonCommonView = BasicView<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>; 406 static_assert(std::ranges::sized_range<SizedBidiNonCommonView>); 407 static_assert(std::ranges::bidirectional_range<SizedBidiNonCommonView>); 408 static_assert(!std::ranges::random_access_range<SizedBidiNonCommonView>); 409 static_assert(!std::ranges::common_range<SizedBidiNonCommonView>); 410 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SizedBidiNonCommonView>); 411 412 using NonSimpleSizedBidiNonCommonView = 413 BasicView<bidirectional_iterator<const int*>, sized_sentinel<bidirectional_iterator<const int*>>, 414 bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>; 415 static_assert(std::ranges::sized_range<NonSimpleSizedBidiNonCommonView>); 416 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiNonCommonView>); 417 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiNonCommonView>); 418 static_assert(!std::ranges::common_range<NonSimpleSizedBidiNonCommonView>); 419 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleSizedBidiNonCommonView>); 420 421 namespace adltest{ 422 struct iter_move_swap_iterator { 423 424 std::reference_wrapper<int> iter_move_called_times; 425 std::reference_wrapper<int> iter_swap_called_times; 426 int i = 0; 427 428 using iterator_category = std::input_iterator_tag; 429 using value_type = int; 430 using difference_type = intptr_t; 431 432 constexpr int operator*() const { return i; } 433 434 constexpr iter_move_swap_iterator& operator++() { 435 ++i; 436 return *this; 437 } 438 constexpr void operator++(int) { ++i; } 439 440 friend constexpr bool operator==(const iter_move_swap_iterator& x, std::default_sentinel_t) { return x.i == 5; } 441 iter_moveiter_move_swap_iterator442 friend constexpr int iter_move(iter_move_swap_iterator const& it) { 443 ++it.iter_move_called_times; 444 return it.i; 445 } iter_swapiter_move_swap_iterator446 friend constexpr void iter_swap(iter_move_swap_iterator const& x, iter_move_swap_iterator const& y) { 447 ++x.iter_swap_called_times; 448 ++y.iter_swap_called_times; 449 } 450 }; 451 452 struct IterMoveSwapRange { 453 int iter_move_called_times = 0; 454 int iter_swap_called_times = 0; beginIterMoveSwapRange455 constexpr auto begin() { return iter_move_swap_iterator{iter_move_called_times, iter_swap_called_times}; } endIterMoveSwapRange456 constexpr auto end() const { return std::default_sentinel; } 457 }; 458 } // namespace adltest 459 460 #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H 461