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

source code of libcxx/test/std/ranges/range.adaptors/range.zip/iterator/decrement.pass.cpp