Zen C++ Libraries
Zero-dependency re-usable components for C++
Loading...
Searching...
No Matches
iterator_range.hpp
Go to the documentation of this file.
1
3#ifndef ZEN_ITERATOR_RANGE_HPP
4#define ZEN_ITERATOR_RANGE_HPP
5
6#include <iterator>
7#include <tuple>
8#include <type_traits>
9#include <utility>
10
11#include "zen/config.hpp"
12#include "zen/concepts.hpp"
13#include "zen/compat.hpp"
14#include "zen/mapped_iterator.hpp"
15#include "zen/zip_iterator.hpp"
16
17ZEN_NAMESPACE_START
18
19template<typename IterT>
20class iterator_range {
21
22 IterT left;
23 IterT right;
24
25 using trait_type = std::iterator_traits<IterT>;
26
27public:
28
29 using value_type = typename trait_type::value_type;
30 using reference = typename trait_type::reference;
31 using iterator = IterT;
32 using difference_type = typename trait_type::difference_type;
33
34 iterator_range(IterT left, IterT right):
35 left(left), right(right) {}
36
37
39 IterT begin() {
40 return left;
41 }
42
44 IterT end() {
45 return right;
46 }
47
48 iterator_range& operator++() requires std::incrementable<IterT> {
49 ++left;
50 return *this;
51 }
52
53 iterator_range operator++(int) requires std::incrementable<IterT> {
54 return iterator_range { left++, right };
55 }
56
57 iterator_range& operator--() requires std::incrementable<IterT> {
58 --left;
59 return *this;
60 }
61
62 iterator_range operator--(int) requires std::incrementable<IterT> {
63 return iterator_range { left--, right };
64 }
65
66 template<typename F>
67 auto map(F func) {
68 using iter = mapped_iterator<IterT, F>;
69 return iterator_range<iter> {
70 iter { left, func },
71 iter { right, func },
72 };
73 }
74
75 auto map_first() {
76 return map([](auto pair) { return pair.first; });
77 }
78
79 auto map_second() {
80 return map([](auto pair) { return pair.second; });
81 }
82
83};
84
92template <typename IterT> auto make_iterator_range(IterT &&a, IterT &&b) {
93 return iterator_range<IterT> { std::forward<IterT>(a), std::forward<IterT>(b) };
94}
95
106template<typename IterT>
107auto make_iterator_range(std::pair<IterT, IterT>&& pair) {
108 return iterator_range<IterT> { std::forward<IterT>(pair.first), std::forward<IterT>(pair.second) };
109}
110
111template<range T>
113 return make_iterator_range(
114 std::begin(container),
115 std::end(container)
116 );
117}
118
119// By default, we don't allow rvalues.
120//
121// For example, a container passed to `zip` would be destroyed before the
122// iterator can run.
123template <typename T>
124struct _zip_accept_rvalue : std::false_type {};
125
126// An iterator_range should be passed by value.
127template<typename IterT>
128struct _zip_accept_rvalue<iterator_range<IterT>> : std::true_type {};
129
135template<range ...Ts>
136auto zip(Ts&& ...args) {
137 // TODO
138 // static_assert(
139 // meta::andmap_v<
140 // meta::bind<
141 // std::disjunction<
142 // std::is_lvalue_reference<meta::_1>,
143 // _zip_accept_rvalue<std::remove_reference_t<meta::_1>>
144 // >
145 // >,
146 // std::tuple<Ts...>
147 // >,
148 // "the provided value cannot be passed in as an rvalue"
149 // );
150 return make_iterator_range(
151 zip(std::begin(args)...),
152 zip(std::end(args)...)
153 );
154}
155
156ZEN_NAMESPACE_END
157
158#endif // of #ifndef ZEN_ITERATOR_RANGE_HPP
Definition iterator_range.hpp:20
IterT end()
Get an iterator pointing just beyond the last element in this range.
Definition iterator_range.hpp:44
IterT begin()
Get an iterator pointing to the first element in this range.
Definition iterator_range.hpp:39
Definition concepts.hpp:25
Definition concepts.hpp:15
right_t< void > right()
Definition either.hpp:329
left_t< void > left()
Definition either.hpp:297
auto make_iterator_range(IterT &&a, IterT &&b)
Definition iterator_range.hpp:92
auto zip(Ts &&...args)
Definition iterator_range.hpp:136
Definition iterator_range.hpp:124
Definitions for an iterator that merges several other iteerators.