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, c++20 10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 11 12 // constexpr iterator& operator--() requires all-bidirectional<Const, Views...>; 13 // constexpr iterator operator--(int) requires all-bidirectional<Const, Views...>; 14 15 #include <array> 16 #include <cassert> 17 #include <ranges> 18 #include <tuple> 19 20 #include "../types.h" 21 22 template <class Iter> 23 concept canDecrement = requires(Iter it) { --it; } || requires(Iter it) { it--; }; 24 25 struct NonBidi : IntBufferView { 26 using IntBufferView::IntBufferView; 27 using iterator = forward_iterator<int*>; 28 constexpr iterator begin() const { return iterator(buffer_); } 29 constexpr sentinel_wrapper<iterator> end() const { return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); } 30 }; 31 32 constexpr bool test() { 33 std::array a{1, 2, 3, 4}; 34 std::array b{4.1, 3.2, 4.3}; 35 { 36 // all random access 37 std::ranges::zip_view v(a, b, std::views::iota(0, 5)); 38 auto it = v.end(); 39 using Iter = decltype(it); 40 41 static_assert(std::is_same_v<decltype(--it), Iter&>); 42 auto& it_ref = --it; 43 assert(&it_ref == &it); 44 45 assert(&(std::get<0>(*it)) == &(a[2])); 46 assert(&(std::get<1>(*it)) == &(b[2])); 47 assert(std::get<2>(*it) == 2); 48 49 static_assert(std::is_same_v<decltype(it--), Iter>); 50 it--; 51 assert(&(std::get<0>(*it)) == &(a[1])); 52 assert(&(std::get<1>(*it)) == &(b[1])); 53 assert(std::get<2>(*it) == 1); 54 } 55 56 { 57 // all bidi+ 58 int buffer[2] = {1, 2}; 59 60 std::ranges::zip_view v(BidiCommonView{buffer}, std::views::iota(0, 5)); 61 auto it = v.begin(); 62 using Iter = decltype(it); 63 64 ++it; 65 ++it; 66 67 static_assert(std::is_same_v<decltype(--it), Iter&>); 68 auto& it_ref = --it; 69 assert(&it_ref == &it); 70 71 assert(it == ++v.begin()); 72 73 static_assert(std::is_same_v<decltype(it--), Iter>); 74 auto tmp = it--; 75 assert(it == v.begin()); 76 assert(tmp == ++v.begin()); 77 } 78 79 { 80 // non bidi 81 int buffer[3] = {4, 5, 6}; 82 std::ranges::zip_view v(a, NonBidi{buffer}); 83 using Iter = std::ranges::iterator_t<decltype(v)>; 84 static_assert(!canDecrement<Iter>); 85 } 86 87 return true; 88 } 89 90 int main(int, char**) { 91 test(); 92 static_assert(test()); 93 94 return 0; 95 } 96