VCCC  2024.05
VisualCamp Common C++ library
reverse_view.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2/8/24.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_REVERSE_VIEW_HPP
6 #define VCCC_RANGES_VIEWS_REVERSE_VIEW_HPP
7 
8 #include <iterator>
9 #include <type_traits>
10 #include <utility>
11 
13 #include "vccc/__iterator/next.hpp"
14 #include "vccc/__ranges/begin.hpp"
18 #include "vccc/__ranges/end.hpp"
21 #include "vccc/__ranges/view.hpp"
23 
24 namespace vccc {
25 namespace ranges {
26 namespace detail {
27 
29 struct reverse_view_cached_begin {
30  constexpr std::reverse_iterator<iterator_t<V>> begin(V& base) {
31  return std::make_reverse_iterator(ranges::end(base));
32  }
33 };
34 
35 template<typename V>
36 struct reverse_view_cached_begin<V, false> {
37  constexpr std::reverse_iterator<iterator_t<V>> begin(V& base) {
38  if (!cached_begin_.has_value()) {
39  cached_begin_.emplace(std::make_reverse_iterator(ranges::next(ranges::begin(base), ranges::end(base))));
40  }
41  return cached_begin_.value();
42  }
43 
44  non_propagating_cache<std::reverse_iterator<iterator_t<V>>> cached_begin_;
45 };
46 
47 } // namespace detail
48 
51 
56 template<typename V>
58  : public view_interface<reverse_view<V>>
59  , private detail::reverse_view_cached_begin<V>
60 {
61  using cache_begin_base = detail::reverse_view_cached_begin<V>;
62  public:
63  static_assert(view<V>::value, "Constraints not satisfied");
64  static_assert(bidirectional_range<V>::value, "Constraints not satisfied");
65 
66  reverse_view() = default;
67 
68  constexpr reverse_view(V r)
69  : base_(std::move(r)) {}
70 
72  constexpr V base() const& {
73  return base_;
74  }
75 
76  constexpr V base() && {
77  return std::move(base_);
78  }
79 
80  constexpr std::reverse_iterator<iterator_t<V>> begin() {
81  return cache_begin_base::begin(base_);
82  }
83 
85  constexpr auto begin() const {
86  return std::make_reverse_iterator(ranges::end(base_));
87  }
88 
89  constexpr std::reverse_iterator<iterator_t<V>> end() {
90  return std::make_reverse_iterator(ranges::begin(base_));
91  }
92 
94  constexpr auto end() const {
95  return std::make_reverse_iterator(ranges::begin(base_));
96  }
97 
99  constexpr auto size() {
100  return ranges::size(base_);
101  }
102 
104  constexpr auto size() const {
105  return ranges::size(base_);
106  }
107 
108  private:
109  V base_{};
110 };
111 
112 #if __cplusplus >= 201703L
113 
114 template<typename R>
115 reverse_view(R&&) -> reverse_view<views::all_t<R>>;
116 
117 #endif
118 
119 template<typename R>
121  return reverse_view<views::all_t<R>>(std::forward<R>(r));
122 }
123 
124 template<typename T>
126 
127 
129 
130 } // namespace ranges
131 } // namespace vccc
132 
133 #endif // VCCC_RANGES_VIEWS_REVERSE_VIEW_HPP
A range adaptor that represents a view of underlying view with reversed order.
Definition: reverse_view.hpp:60
constexpr V base() const &
Definition: reverse_view.hpp:72
constexpr auto size() const
Definition: reverse_view.hpp:104
constexpr auto size()
Definition: reverse_view.hpp:99
constexpr V base() &&
Definition: reverse_view.hpp:76
constexpr reverse_view(V r)
Definition: reverse_view.hpp:68
constexpr auto end() const
Definition: reverse_view.hpp:94
constexpr std::reverse_iterator< iterator_t< V > > begin()
Definition: reverse_view.hpp:80
constexpr auto begin() const
Definition: reverse_view.hpp:85
constexpr std::reverse_iterator< iterator_t< V > > end()
Definition: reverse_view.hpp:89
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC detail::next_niebloid next
Definition: next.hpp:65
constexpr reverse_view< views::all_t< R > > make_reverse_view(R &&r)
Definition: reverse_view.hpp:120
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::size_niebloid size
returns the size of a container or array
Definition: size.hpp:145
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
specifies a range whose iterator type satisfies bidirectional_iterator
Definition: bidirectional_range.hpp:49
Definition: enable_borrowed_range.hpp:17
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31