Audacity 3.2.0
IteratorX.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file IteratorX.h
6
7 C++ standard header <iterator> with a few extensions
8
9 Paul Licameli split from MemoryX.h
10
11 **********************************************************************/
12#ifndef __AUDACITY_ITERATOR_X__
13#define __AUDACITY_ITERATOR_X__
14
15#include <algorithm>
16#include <functional>
17#include <iterator>
18#include <limits>
19
24template< typename Value, typename Category = std::forward_iterator_tag >
26 using iterator_category = Category;
27 using value_type = Value;
28 using difference_type = ptrdiff_t;
29 // void pointer type so that operator -> is disabled
30 using pointer = void;
31 // make "reference type" really the same as the value type
32 using reference = const Value;
33};
34
38template <typename Iterator>
39struct IteratorRange : public std::pair<Iterator, Iterator> {
40 using iterator = Iterator;
41 using reverse_iterator = std::reverse_iterator<Iterator>;
42
43 IteratorRange (const Iterator &a, const Iterator &b)
44 : std::pair<Iterator, Iterator> ( a, b ) {}
45
46 IteratorRange (Iterator &&a, Iterator &&b)
47 : std::pair<Iterator, Iterator> ( std::move(a), std::move(b) ) {}
48
50 { return { this->rbegin(), this->rend() }; }
51
52 Iterator begin() const { return this->first; }
53 Iterator end() const { return this->second; }
54
55 reverse_iterator rbegin() const { return reverse_iterator{ this->second }; }
56 reverse_iterator rend() const { return reverse_iterator{ this->first }; }
57
58 bool empty() const { return this->begin() == this->end(); }
59 explicit operator bool () const { return !this->empty(); }
60 size_t size() const { return std::distance(this->begin(), this->end()); }
61
62 template <typename T> iterator find(const T &t) const
63 { return std::find(this->begin(), this->end(), t); }
64
65 template <typename T> long index(const T &t) const
66 {
67 auto iter = this->find(t);
68 if (iter == this->end())
69 return -1;
70 return std::distance(this->begin(), iter);
71 }
72
73 template <typename T> bool contains(const T &t) const
74 { return this->end() != this->find(t); }
75
76 template <typename F> iterator find_if(const F &f) const
77 { return std::find_if(this->begin(), this->end(), f); }
78
79 template <typename F> long index_if(const F &f) const
80 {
81 auto iter = this->find_if(f);
82 if (iter == this->end())
83 return -1;
84 return std::distance(this->begin(), iter);
85 }
86
87 // to do: use std::all_of, any_of, none_of when available on all platforms
88 template <typename F> bool all_of(const F &f) const
89 {
90 auto notF =
91 [&](typename std::iterator_traits<Iterator>::reference v)
92 { return !f(v); };
93 return !this->any_of( notF );
94 }
95
96 template <typename F> bool any_of(const F &f) const
97 { return this->end() != this->find_if(f); }
98
99 template <typename F> bool none_of(const F &f) const
100 { return !this->any_of(f); }
101
102 template<typename T> struct identity
103 { const T&& operator () (T &&v) const { return std::forward(v); } };
104
105 // Like std::accumulate, but the iterators implied, and with another
106 // unary operation on the iterator value, pre-composed
107 template<
108 typename R,
109 typename Binary = std::plus< R >,
111 >
113 R init,
114 Binary binary_op = {},
115 Unary unary_op = {}
116 ) const
117 {
118 R result = init;
119 for (auto&& v : *this)
120 result = binary_op(result, unary_op(v));
121 return result;
122 }
123
124 // An overload making it more convenient to use with pointers to member
125 // functions
126 template<
127 typename R,
128 typename Binary = std::plus< R >,
129 typename R2, typename C
130 >
132 R init,
133 Binary binary_op,
134 R2 (C :: * pmf) () const
135 ) const
136 {
137 return this->accumulate( init, binary_op, std::mem_fn( pmf ) );
138 }
139
140 // Some accumulations frequent enough to be worth abbreviation:
141 template<
142 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
143 typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
144 >
145 R min( Unary unary_op = {} ) const
146 {
147 return this->accumulate(
148 std::numeric_limits< R >::max(),
149 (const R&(*)(const R&, const R&)) std::min,
150 unary_op
151 );
152 }
153
154 template<
155 typename R2, typename C,
156 typename R = R2
157 >
158 R min( R2 (C :: * pmf) () const ) const
159 {
160 return this->min( std::mem_fn( pmf ) );
161 }
162
163 template<
164 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
165 typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
166 >
167 R max( Unary unary_op = {} ) const
168 {
169 return this->accumulate(
170 std::numeric_limits< R >::lowest(),
171 (const R&(*)(const R&, const R&)) std::max,
172 unary_op
173 );
174 }
175
176 template<
177 typename R2, typename C,
178 typename R = R2
179 >
180 R max( R2 (C :: * pmf) () const ) const
181 {
182 return this->max( std::mem_fn( pmf ) );
183 }
184
185 template<
186 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
187 typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
188 >
189 R sum( Unary unary_op = {} ) const
190 {
191 return this->accumulate(
192 R{ 0 },
193 std::plus< R >{},
194 unary_op
195 );
196 }
197
198 template<
199 typename R2, typename C,
200 typename R = R2
201 >
202 R sum( R2 (C :: * pmf) () const ) const
203 {
204 return this->sum( std::mem_fn( pmf ) );
205 }
206};
207
208template< typename Iterator>
210make_iterator_range( const Iterator &i1, const Iterator &i2 )
211{
212 return { i1, i2 };
213}
214
215template< typename Container >
217make_iterator_range( Container &container )
218{
219 return { container.begin(), container.end() };
220}
221
222template< typename Container >
224make_iterator_range( const Container &container )
225{
226 return { container.begin(), container.end() };
227}
228
229// A utility function building a container of results
230template< typename Container, typename Iterator, typename Function >
231Container transform_range( Iterator first, Iterator last, Function &&fn )
232{
233 Container result;
234 std::transform( first, last, std::back_inserter( result ), fn );
235 return result;
236}
237// A utility function, often constructing a vector from another vector
238template< typename OutContainer, typename InContainer, typename Function >
239OutContainer transform_container( InContainer &inContainer, Function &&fn )
240{
241 return transform_range<OutContainer>(
242 inContainer.begin(), inContainer.end(), fn );
243}
244
245template<typename Range, typename Function>
246void for_each_in_range(Range &&range, Function &&fn)
247{
248 std::for_each(range.begin(), range.end(), std::forward<Function>(fn));
249}
250
251template<typename Integral = int>
252class NumberIterator : public ValueIterator<Integral>
253{
254public:
255 explicit NumberIterator(Integral value) : mValue{ value } {}
256
257 Integral operator *() const { return mValue; }
258 NumberIterator &operator ++() { ++mValue; return *this; }
260 { auto result = *this; ++result; return result; }
261
263 { return x.mValue == y.mValue; }
265 { return !(x == y); }
266
267private:
268 Integral mValue;
269};
270
271template<typename Integral> struct IotaRange
272 : IteratorRange<NumberIterator<Integral>>
273{
274 IotaRange(Integral inclusiveLower, Integral exclusiveUpper)
275 : IteratorRange<NumberIterator<Integral>>{
276 NumberIterator{ inclusiveLower }, NumberIterator{ exclusiveUpper } }
277 {}
278};
279
280#endif // __AUDACITY_MEMORY_X_H__
int min(int a, int b)
Container transform_range(Iterator first, Iterator last, Function &&fn)
Definition: IteratorX.h:231
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
void for_each_in_range(Range &&range, Function &&fn)
Definition: IteratorX.h:246
OutContainer transform_container(InContainer &inContainer, Function &&fn)
Definition: IteratorX.h:239
static const auto fn
friend bool operator==(NumberIterator x, NumberIterator y)
Definition: IteratorX.h:262
NumberIterator & operator++()
Definition: IteratorX.h:258
Integral operator*() const
Definition: IteratorX.h:257
Integral mValue
Definition: IteratorX.h:268
friend bool operator!=(NumberIterator x, NumberIterator y)
Definition: IteratorX.h:264
NumberIterator(Integral value)
Definition: IteratorX.h:255
STL namespace.
IotaRange(Integral inclusiveLower, Integral exclusiveUpper)
Definition: IteratorX.h:274
const T && operator()(T &&v) const
Definition: IteratorX.h:103
A convenience for use with range-for.
Definition: IteratorX.h:39
R accumulate(R init, Binary binary_op, R2(C ::*pmf)() const) const
Definition: IteratorX.h:131
bool contains(const T &t) const
Definition: IteratorX.h:73
bool empty() const
Definition: IteratorX.h:58
R sum(R2(C ::*pmf)() const) const
Definition: IteratorX.h:202
R sum(Unary unary_op={}) const
Definition: IteratorX.h:189
R accumulate(R init, Binary binary_op={}, Unary unary_op={}) const
Definition: IteratorX.h:112
bool all_of(const F &f) const
Definition: IteratorX.h:88
std::reverse_iterator< Iterator > reverse_iterator
Definition: IteratorX.h:41
iterator find_if(const F &f) const
Definition: IteratorX.h:76
iterator find(const T &t) const
Definition: IteratorX.h:62
IteratorRange(Iterator &&a, Iterator &&b)
Definition: IteratorX.h:46
long index(const T &t) const
Definition: IteratorX.h:65
R max(Unary unary_op={}) const
Definition: IteratorX.h:167
IteratorRange< reverse_iterator > reversal() const
Definition: IteratorX.h:49
R min(R2(C ::*pmf)() const) const
Definition: IteratorX.h:158
Iterator end() const
Definition: IteratorX.h:53
bool any_of(const F &f) const
Definition: IteratorX.h:96
Iterator iterator
Definition: IteratorX.h:40
long index_if(const F &f) const
Definition: IteratorX.h:79
reverse_iterator rend() const
Definition: IteratorX.h:56
bool none_of(const F &f) const
Definition: IteratorX.h:99
Iterator begin() const
Definition: IteratorX.h:52
size_t size() const
Definition: IteratorX.h:60
R min(Unary unary_op={}) const
Definition: IteratorX.h:145
IteratorRange(const Iterator &a, const Iterator &b)
Definition: IteratorX.h:43
reverse_iterator rbegin() const
Definition: IteratorX.h:55
R max(R2(C ::*pmf)() const) const
Definition: IteratorX.h:180
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
Definition: IteratorX.h:25
ptrdiff_t difference_type
Definition: IteratorX.h:28
const Value reference
Definition: IteratorX.h:32
void pointer
Definition: IteratorX.h:30
Category iterator_category
Definition: IteratorX.h:26
Value value_type
Definition: IteratorX.h:27