xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/decrement.pass.cpp (revision b8cb1dc9ea87faa8e8e9ab7a31710a8c0bb8b084)
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 
21 template <class Iter>
22 concept canDecrement = requires(Iter it) { --it; } || requires(Iter it) { it--; };
23 
24 struct NonBidi : IntBufferView {
25   using IntBufferView::IntBufferView;
26   using iterator = forward_iterator<int*>;
beginNonBidi27   constexpr iterator begin() const { return iterator(buffer_); }
endNonBidi28   constexpr sentinel_wrapper<iterator> end() const { return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); }
29 };
30 
test()31 constexpr 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 
main(int,char **)89 int main(int, char**) {
90   test();
91   static_assert(test());
92 
93   return 0;
94 }
95