Audio Processing Framework (APF) version 0.5.0
iterator.h
Go to the documentation of this file.
1/******************************************************************************
2 Copyright (c) 2012-2016 Institut für Nachrichtentechnik, Universität Rostock
3 Copyright (c) 2006-2012 Quality & Usability Lab
4 Deutsche Telekom Laboratories, TU Berlin
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23*******************************************************************************/
24
25// https://AudioProcessingFramework.github.io/
26
29
30#ifndef APF_ITERATOR_H
31#define APF_ITERATOR_H
32
33#include <cassert> // for assert()
34#include <iterator> // for std::iterator_traits, std::output_iterator_tag, ...
35#include <type_traits> // for std::remove_reference, std::result_of
36
37#include "apf/math.h" // for wrap()
38
60namespace apf
61{
64template<typename T> bool no_nullptr(T* in) { return in != nullptr; }
65
70template<typename T> bool no_nullptr(T&) { return true; }
71}
72
78#define APF_ITERATOR_CONSTRUCTORS(iterator_name, base_iterator_type, base_member) \
79 \
80 explicit iterator_name(base_iterator_type base_iterator) \
81 : base_member(base_iterator) {} \
82 \
83 iterator_name() : base_member() {}
84
89#define APF_ITERATOR_BASE(base_iterator_type, base_member) \
90 \
91 base_iterator_type base() const { assert(apf::no_nullptr(base_member)); \
92 return (base_member); }
93
94// Output Iterator Requirements
95
99#define APF_ITERATOR_OUTPUT_DEREFERENCE(base_member) \
100 \
101 reference operator*() const { assert(apf::no_nullptr(base_member)); \
102 return *(base_member); }
103
107#define APF_ITERATOR_OUTPUT_PREINCREMENT(base_member) \
108 \
109 self& operator++() { assert(apf::no_nullptr(base_member)); \
110 ++(base_member); return *this; }
111
114#define APF_ITERATOR_OUTPUT_POSTINCREMENT \
115 \
116 self operator++(int) { self tmp = *this; ++(*this); return tmp; }
117
118// Input Iterator Requirements
119
123#define APF_ITERATOR_INPUT_DEREFERENCE APF_ITERATOR_OUTPUT_DEREFERENCE
124
128#define APF_ITERATOR_INPUT_ARROW(base_member) \
129 \
130 pointer operator->() const { assert(apf::no_nullptr(base_member)); \
131 return (base_member); }
132
136#define APF_ITERATOR_INPUT_EQUAL(base_member) \
137 \
138 bool operator==(const self& rhs) const { \
139 return ((base_member) == (rhs.base_member)); }
140
144#define APF_ITERATOR_INPUT_PREINCREMENT APF_ITERATOR_OUTPUT_PREINCREMENT
145
148#define APF_ITERATOR_INPUT_POSTINCREMENT APF_ITERATOR_OUTPUT_POSTINCREMENT
149
152#define APF_ITERATOR_INPUT_UNEQUAL \
153 \
154 bool operator!=(const self& rhs) const { return !operator==(rhs); } \
155
156// Forward Iterator Requirements
157
161#define APF_ITERATOR_FORWARD_EQUAL APF_ITERATOR_INPUT_EQUAL
165#define APF_ITERATOR_FORWARD_DEREFERENCE APF_ITERATOR_INPUT_DEREFERENCE
169#define APF_ITERATOR_FORWARD_ARROW APF_ITERATOR_INPUT_ARROW
173#define APF_ITERATOR_FORWARD_PREINCREMENT APF_ITERATOR_INPUT_PREINCREMENT
174
177#define APF_ITERATOR_FORWARD_POSTINCREMENT APF_ITERATOR_INPUT_POSTINCREMENT
180#define APF_ITERATOR_FORWARD_UNEQUAL APF_ITERATOR_INPUT_UNEQUAL
181
182// Bidirectional Iterator Requirements
183
187#define APF_ITERATOR_BIDIRECTIONAL_EQUAL APF_ITERATOR_FORWARD_EQUAL
191#define APF_ITERATOR_BIDIRECTIONAL_DEREFERENCE APF_ITERATOR_FORWARD_DEREFERENCE
195#define APF_ITERATOR_BIDIRECTIONAL_ARROW APF_ITERATOR_FORWARD_ARROW
199#define APF_ITERATOR_BIDIRECTIONAL_PREINCREMENT APF_ITERATOR_FORWARD_PREINCREMENT
200
204#define APF_ITERATOR_BIDIRECTIONAL_PREDECREMENT(base_member) \
205 \
206 self& operator--() { assert(apf::no_nullptr(base_member)); \
207 --(base_member); return *this; }
208
211#define APF_ITERATOR_BIDIRECTIONAL_POSTINCREMENT APF_ITERATOR_FORWARD_POSTINCREMENT
214#define APF_ITERATOR_BIDIRECTIONAL_UNEQUAL APF_ITERATOR_FORWARD_UNEQUAL
215
218#define APF_ITERATOR_BIDIRECTIONAL_POSTDECREMENT \
219 \
220 self operator--(int) { self tmp = *this; --(*this); return tmp; }
221
222// Random Access Iterator Requirements
223
227#define APF_ITERATOR_RANDOMACCESS_EQUAL APF_ITERATOR_BIDIRECTIONAL_EQUAL
231#define APF_ITERATOR_RANDOMACCESS_DEREFERENCE APF_ITERATOR_BIDIRECTIONAL_DEREFERENCE
235#define APF_ITERATOR_RANDOMACCESS_ARROW APF_ITERATOR_BIDIRECTIONAL_ARROW
239#define APF_ITERATOR_RANDOMACCESS_PREINCREMENT APF_ITERATOR_BIDIRECTIONAL_PREINCREMENT
243#define APF_ITERATOR_RANDOMACCESS_PREDECREMENT APF_ITERATOR_BIDIRECTIONAL_PREDECREMENT
244
248#define APF_ITERATOR_RANDOMACCESS_ADDITION_ASSIGNMENT(base_member) \
249 \
250 self& operator+=(difference_type n) { \
251 assert(!n || apf::no_nullptr(base_member)); \
252 (base_member) += n; return *this; }
253
257#define APF_ITERATOR_RANDOMACCESS_DIFFERENCE(base_member) \
258 \
259 friend difference_type operator-(const self& lhs, const self& rhs) { \
260 assert(apf::no_nullptr(lhs.base_member) \
261 && apf::no_nullptr(rhs.base_member)); \
262 return ((lhs.base_member) - (rhs.base_member)); }
263
266#define APF_ITERATOR_RANDOMACCESS_SUBSCRIPT \
267 \
268 reference operator[](difference_type n) const { \
269 return *(*this + n); }
270
274#define APF_ITERATOR_RANDOMACCESS_LESS(base_member) \
275 \
276 friend bool operator<(const self& lhs, const self& rhs) { \
277 assert(apf::no_nullptr(lhs.base_member) \
278 && apf::no_nullptr(rhs.base_member)); \
279 return (lhs.base_member) < (rhs.base_member); }
280
284#define APF_ITERATOR_RANDOMACCESS_UNEQUAL APF_ITERATOR_BIDIRECTIONAL_UNEQUAL
285
289#define APF_ITERATOR_RANDOMACCESS_OTHER_COMPARISONS \
290 \
291 friend bool operator>(const self& lhs, const self& rhs) \
292 { return rhs < lhs; } \
293 \
294 friend bool operator<=(const self& lhs, const self& rhs) \
295 { return !(rhs < lhs); } \
296\
297 friend bool operator>=(const self& lhs, const self& rhs) \
298 { return !(lhs < rhs); }
299
302#define APF_ITERATOR_RANDOMACCESS_POSTINCREMENT APF_ITERATOR_BIDIRECTIONAL_POSTINCREMENT
303
306#define APF_ITERATOR_RANDOMACCESS_POSTDECREMENT APF_ITERATOR_BIDIRECTIONAL_POSTDECREMENT
307
314#define APF_ITERATOR_RANDOMACCESS_THE_REST \
315 \
316 self operator+(difference_type n) const { self tmp(*this); return tmp += n; }\
317 \
318 friend self operator+(difference_type n, const self& it) { \
319 self temp(it); return temp += n; } \
320 \
321 self& operator-=(difference_type n) { *this += -n; return *this; } \
322 \
323 self operator-(difference_type n) const { self tmp(*this); return tmp += -n; }
324
325namespace apf
326{
327
333template<typename I>
335{
336 public:
337 using iterator = I;
338 using reference = typename std::iterator_traits<I>::reference;
339 using difference_type = typename std::iterator_traits<I>::difference_type;
340
342 has_begin_and_end() : _begin(), _end() {}
343
345 has_begin_and_end(iterator b, iterator e) : _begin(b), _end(e) {}
346
348 template<typename Distance>
349 has_begin_and_end(iterator b, Distance length)
350 : _begin(b)
351 , _end(b)
352 {
353 std::advance(_end, static_cast<std::make_signed_t<Distance>>(length));
354 }
355
356 // auto-generated copy constructor is used
357
361 iterator begin() const { return _begin; }
362
366 iterator end() const { return _end; }
367
370 reference operator[](difference_type n) const { return _begin[n]; }
371
372 protected:
373 iterator _begin, _end;
374};
375
376template<typename I, typename... Args>
377has_begin_and_end<I> make_begin_and_end(I first, Args&&... args)
378{
379 return {first, std::forward<Args>(args)...};
380}
381
384template<typename I, typename Container>
386{
387 public:
388 using iterator = I;
389 using reverse_iterator = std::reverse_iterator<iterator>;
390 using size_type = typename Container::size_type;
391 using value_type = typename std::iterator_traits<I>::value_type;
392
393 // implicit conversion is desired, therefore no "explicit" keyword
394 iterator_proxy(Container& l) : _l(l) {}
395
396 iterator begin() const { return iterator(_l.begin()); }
397 iterator end() const { return iterator(_l.end()); }
398 reverse_iterator
399 rbegin() const { return reverse_iterator(iterator(_l.end())); }
400 reverse_iterator
401 rend() const { return reverse_iterator(iterator(_l.begin())); }
402 size_type size() const { return _l.size(); }
403
404 private:
405 Container& _l;
406};
407
410template<typename I, typename Container>
412{
413 public:
414 using iterator = I;
415 using reverse_iterator = std::reverse_iterator<iterator>;
416 using size_type = typename Container::size_type;
417 using value_type = typename std::iterator_traits<I>::value_type;
418
419 // implicit conversion is desired, therefore no "explicit" keyword
420 iterator_proxy_const(const Container& l) : _l(l) {}
421
422 iterator begin() const { return iterator(_l.begin()); }
423 iterator end() const { return iterator(_l.end()); }
424 reverse_iterator
425 rbegin() const { return reverse_iterator(iterator(_l.end())); }
426 reverse_iterator
427 rend() const { return reverse_iterator(iterator(_l.begin())); }
428 size_type size() const { return _l.size(); }
429
430 private:
431 const Container& _l;
432};
433
444template<typename I>
446{
447 private:
449
450 public:
451 using iterator_category = std::output_iterator_tag;
452 using value_type = void;
453 using difference_type = void;
454 using pointer = void;
455 using reference = void;
456
458
459
461 {
462 public:
464 explicit output_proxy(I& i) : _i(i) {}
465
468 template<typename V>
469 output_proxy& operator=(const V& v) { *_i += v; return *this; }
470
471 private:
472 I& _i;
473 };
474
478 {
479 assert(no_nullptr(_base_iterator));
480 return output_proxy(_base_iterator);
481 }
482
483 // operator-> doesn't make sense!
484
485 // straightforward operators:
488
489 APF_ITERATOR_BASE(I, _base_iterator)
490
491 private:
492 I _base_iterator;
493};
494
503template<typename I>
506{
507 return accumulating_iterator<I>(base_iterator);
508}
509
522template<typename T, typename I>
524{
525 private:
526 using self = cast_iterator;
527
528 public:
529 using value_type = T;
530 using pointer = T*;
531 using reference = T&;
532 using difference_type = typename std::iterator_traits<I>::difference_type;
533 using iterator_category
534 = typename std::iterator_traits<I>::iterator_category;
535
537
538 // auto-generated copy ctor and assignment operator are OK.
539
540
542 reference operator*() const
543 {
544 assert(no_nullptr(_base_iterator));
545 return *this->operator->();
546 }
547
550 pointer operator->() const
551 {
552 assert(no_nullptr(_base_iterator));
553 // I::value_type must be a pointer to something!
554 return _cast_helper(*_base_iterator);
555 }
556
560 reference operator[](difference_type n) const
561 {
562 assert(no_nullptr(_base_iterator));
563 return *_cast_helper(_base_iterator[n]);
564 }
565
566 // straightforward operators:
578
579 APF_ITERATOR_BASE(I, _base_iterator)
580
581 private:
587 template<typename X>
588 pointer _cast_helper(X* ptr) const
589 {
590 return static_cast<pointer>(ptr);
591 }
592
593 I _base_iterator;
594};
595
604template<typename T, typename I>
605cast_iterator<T, I>
606make_cast_iterator(I base_iterator)
607{
608 return cast_iterator<T, I>(base_iterator);
609}
610
616template<typename T, typename Container>
618 cast_iterator<T, typename Container::iterator>, Container>
619{
620 using value_type = T;
621
622 cast_proxy(Container& l)
624 T, typename Container::iterator>, Container>(l)
625 {}
626};
627
630template<typename T, typename Container>
632make_cast_proxy(Container& l)
633{
634 return cast_proxy<T, Container>(l);
635}
636
641template<typename T, typename Container>
643 cast_iterator<const T, typename Container::const_iterator>, Container>
644{
645 using value_type = T;
646
647 cast_proxy_const(const Container& l)
649 const T, typename Container::const_iterator>, Container>(l)
650 {}
651};
652
655template<typename T, typename Container>
658{
660}
661
670template<typename I>
672{
673 private:
674 using self = circular_iterator;
675
676 public:
678
679 using iterator_category
680 = typename std::iterator_traits<I>::iterator_category;
681 using value_type = typename std::iterator_traits<I>::value_type;
682 using difference_type = typename std::iterator_traits<I>::difference_type;
683 using pointer = typename std::iterator_traits<I>::pointer;
684 using reference = typename std::iterator_traits<I>::reference;
686
689
690
695 circular_iterator(I begin, I end, I current)
696 : _begin(begin)
697 , _end(end)
698 , _current((current == end) ? begin : current) // wrap around
699 {
700 assert(no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current));
701 assert(_begin != _end);
702 assert(_current != _end);
703 }
704
709 circular_iterator(I begin, I end)
710 : _begin(begin)
711 , _end(end)
712 , _current(begin)
713 {
714 assert(no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current));
715 assert(_begin != _end);
716 }
717
718 // Although this constructor is normally useless, it's good for unit tests.
724 explicit circular_iterator(I begin)
725 : _begin(begin)
726 , _end(begin + 1)
727 , _current(begin)
728 {
729 assert(no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current));
730 assert(_begin != _end);
731 }
732
737 : _begin()
738 , _end()
739 , _current()
740 {}
741
743
746
747
749 self&
751 {
752 assert(no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current));
753 ++_current;
754 if (_current == _end) _current = _begin;
755 return *this;
756 }
757
759 self&
761 {
762 assert(no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current));
763 if (_current == _begin) _current = _end;
764 --_current;
765 return *this;
766 }
767
769 self&
770 operator+=(difference_type n)
771 {
772 assert(!n
773 || (no_nullptr(_begin) && no_nullptr(_end) && no_nullptr(_current)));
774 difference_type length = _end - _begin;
775 difference_type index = _current - _begin;
776 index += n;
777 _current = _begin + apf::math::wrap(index, length);
778 return *this;
779 }
780
789 friend
790 difference_type
791 operator-(const self& lhs, const self& rhs)
792 {
793 assert(no_nullptr(lhs._begin) && no_nullptr(rhs._begin));
794 assert(no_nullptr(lhs._end) && no_nullptr(rhs._end));
795 assert(no_nullptr(lhs._current) && no_nullptr(rhs._current));
796 assert(lhs._begin == rhs._begin);
797 assert(lhs._end == rhs._end );
798
799 difference_type d = lhs._current - rhs._current;
800
801 if (d < 0)
802 {
803 d = lhs._current - lhs._begin + rhs._end - rhs._current;
804 }
805 // if lhs and rhs are the same, the difference is of course zero.
806 return d;
807 }
808
809 // straightforward operators:
818
820
821 APF_ITERATOR_BASE(I, _current)
822
823 private:
824 I _begin;
825 I _end;
826 I _current;
827};
828
838template<typename I>
841{
842 return circular_iterator<I>(begin, end);
843}
844
855template<typename I>
856circular_iterator<I>
857make_circular_iterator(I begin, I end, I current)
858{
859 return circular_iterator<I>(begin, end, current);
860}
861
875template<typename I, typename F>
877{
878 private:
879 using self = transform_iterator;
880 // NOTE: value_type& works for by-value, by-reference and by-const-reference
881 using _signature = F(typename std::iterator_traits<I>::value_type&);
882
883 public:
884 using iterator_category
885 = typename std::iterator_traits<I>::iterator_category;
887 using reference = typename std::result_of<_signature>::type;
888 using value_type = typename std::remove_reference<reference>::type;
889 using pointer = value_type*;
890 using difference_type = typename std::iterator_traits<I>::difference_type;
891
893 explicit transform_iterator(I base_iterator = I(), F f = F())
894 : _base_iterator(base_iterator)
895 , _f(f)
896 {}
897
902 reference operator*() { return _f(*_base_iterator); }
903
908 pointer operator->()
909 {
910 return &this->operator*();
911 }
912
925
926 APF_ITERATOR_BASE(I, _base_iterator)
927
928 private:
929 I _base_iterator;
930 F _f;
931};
932
942template<typename I, typename F>
944make_transform_iterator(I base_iterator, F f)
945{
946 return transform_iterator<I, F>(base_iterator, f);
947}
948
954template<typename F, typename Container>
956 transform_iterator<typename Container::iterator, F>, Container>
957{
958 transform_proxy(Container& l)
960 typename Container::iterator, F>, Container>(l)
961 {}
962};
963
968template<typename F, typename Container>
970 transform_iterator<typename Container::const_iterator, F>, Container>
971{
972 transform_proxy_const(const Container& l)
974 typename Container::const_iterator, F>, Container>(l)
975 {}
976};
977
984template<typename T>
986{
987 private:
988 using self = index_iterator;
989
990 public:
991 using iterator_category = std::random_access_iterator_tag;
992 using value_type = T;
993 using reference = T;
994 using difference_type = T;
995 using pointer = void;
996
998 explicit index_iterator(T start = T())
999 : _number(start)
1000 {}
1001
1003 reference operator*() const { return _number; }
1004
1005 // operator-> doesn't make sense!
1006
1019
1020 private:
1021 T _number;
1022};
1023
1032template<typename T>
1035{
1036 return index_iterator<T>(start);
1037}
1038
1049template<class I>
1051{
1052 private:
1053 using self = stride_iterator;
1054
1055 public:
1057
1059 = typename std::iterator_traits<I>::iterator_category;
1060 using value_type = typename std::iterator_traits<I>::value_type;
1061 using difference_type = typename std::iterator_traits<I>::difference_type;
1062 using reference = typename std::iterator_traits<I>::reference;
1063 using pointer = typename std::iterator_traits<I>::pointer;
1065
1069 explicit stride_iterator(I base_iterator, difference_type step
1070#ifdef APF_STRIDE_ITERATOR_DEFAULT_STRIDE
1071 = APF_STRIDE_ITERATOR_DEFAULT_STRIDE
1072#endif
1073 )
1074 : _iter(base_iterator)
1075 , _step(step)
1076 {}
1077
1082 : _iter(base_iterator.base())
1083 , _step(base_iterator.step_size() * step)
1084 {}
1085
1090 : _iter()
1091 , _step(0)
1092 {}
1093
1094 bool
1095 operator==(const self& rhs) const
1096 {
1097 return _iter == rhs._iter && _step == rhs._step;
1098 }
1099
1100 self&
1102 {
1103 assert(no_nullptr(_iter));
1104 std::advance(_iter, _step);
1105 return *this;
1106 }
1107
1108 self&
1110 {
1111 assert(no_nullptr(_iter));
1112 std::advance(_iter, -_step);
1113 return *this;
1114 }
1115
1116 reference
1118 {
1119 assert(no_nullptr(_iter));
1120 return _iter[n * _step];
1121 }
1122
1123 self&
1125 {
1126 assert(!n || no_nullptr(_iter));
1127 std::advance(_iter, n * _step);
1128 return *this;
1129 }
1130
1131 friend
1132 difference_type
1133 operator-(const self& lhs, const self& rhs)
1134 {
1135 assert(no_nullptr(lhs._iter) && no_nullptr(rhs._iter));
1136 assert(lhs._step == rhs._step);
1137 return (lhs._iter - rhs._iter) / lhs._step;
1138 }
1139
1140 friend
1141 bool
1142 operator<(const self& lhs, const self& rhs)
1143 {
1144 assert(no_nullptr(lhs._iter) && no_nullptr(rhs._iter));
1145 assert(lhs._step == rhs._step);
1146 return lhs._iter < rhs._iter;
1147 }
1148
1149 friend
1150 bool
1151 operator<=(const self& lhs, const self& rhs)
1152 {
1153 assert(no_nullptr(lhs._iter) && no_nullptr(rhs._iter));
1154 assert(lhs._step == rhs._step);
1155 return lhs._iter <= rhs._iter;
1156 }
1157
1158 friend
1159 bool
1160 operator>(const self& lhs, const self& rhs)
1161 {
1162 assert(no_nullptr(lhs._iter) && no_nullptr(rhs._iter));
1163 assert(lhs._step == rhs._step);
1164 return lhs._iter > rhs._iter;
1165 }
1166
1167 friend
1168 bool
1169 operator>=(const self& lhs, const self& rhs)
1170 {
1171 assert(no_nullptr(lhs._iter) && no_nullptr(rhs._iter));
1172 assert(lhs._step == rhs._step);
1173 return lhs._iter >= rhs._iter;
1174 }
1175
1176 // straightforward operators:
1183
1185
1187 difference_type step_size() const { return _step; }
1188
1189 private:
1190 I _iter;
1191 // This has to be non-const to allow automatic assignment operator:
1192 difference_type _step;
1193};
1194
1208template<typename I1, typename I2 = I1>
1210{
1211 private:
1212 using self = dual_iterator;
1213
1214 public:
1215 // TODO: what if I1 or I2 are only input or output iterators?
1216 // TODO: some witty metaprogram to find the greatest common denominator?
1217 using iterator_category = std::forward_iterator_tag;
1218
1219 using value_type = std::pair<typename std::iterator_traits<I1>::value_type
1220 , typename std::iterator_traits<I2>::value_type>;
1221
1222 class output_proxy; // For implementation see below
1223 using reference = output_proxy;
1224
1225 using difference_type = std::ptrdiff_t;
1226 using pointer = void;
1227
1228 dual_iterator() = default;
1229
1231 dual_iterator(I1 i1, I2 i2) : _i1(i1), _i2(i2) {}
1232
1236 {
1237 assert(no_nullptr(_i1) && no_nullptr(_i2));
1238 return reference(_i1, _i2);
1239 }
1240
1241 // operator-> doesn't really make sense
1242
1245 {
1246 assert(no_nullptr(_i1) && no_nullptr(_i2));
1247 ++_i1;
1248 ++_i2;
1249 return *this;
1250 }
1251
1253 bool operator==(const self& rhs) const
1254 {
1255 return (_i1 == rhs._i1) && (_i2 == rhs._i2);
1256 }
1257
1260
1261 private:
1262 I1 _i1;
1263 I2 _i2;
1264};
1265
1267template<typename I1, typename I2>
1269{
1270 public:
1271 explicit output_proxy(I1& i1, I2& i2) : _i1(i1), _i2(i2) {}
1272
1276 template<typename T1, typename T2>
1277 operator std::pair<T1, T2>()
1278 {
1279 return {*_i1, *_i2};
1280 }
1281
1283 template<typename T1, typename T2>
1284 output_proxy& operator=(const std::pair<T1, T2>& rhs)
1285 {
1286 *_i1 = rhs.first;
1287 *_i2 = rhs.second;
1288 return *this;
1289 }
1290
1292 template<typename T>
1294 {
1295 *_i1 = rhs;
1296 *_i2 = rhs;
1297 return *this;
1298 }
1299
1301 template<typename T1, typename T2>
1302 output_proxy& operator+=(const std::pair<T1, T2>& rhs)
1303 {
1304 *_i1 += rhs.first;
1305 *_i2 += rhs.second;
1306 return *this;
1307 }
1308
1310 template<typename T>
1312 {
1313 *_i1 += rhs;
1314 *_i2 += rhs;
1315 return *this;
1316 }
1317
1318 private:
1319 I1& _i1;
1320 I2& _i2;
1321};
1322
1332template<typename I1, typename I2>
1335{
1336 return dual_iterator<I1, I2>(i1, i2);
1337}
1338
1351{
1352 private:
1353 using self = discard_iterator;
1354
1355 public:
1356 using iterator_category = std::output_iterator_tag;
1357 using value_type = void;
1358 using difference_type = void;
1359 using pointer = void;
1360
1363 {
1365 template<typename T>
1366 output_proxy& operator=(const T&) { return *this; }
1367
1369 template<typename T>
1370 output_proxy& operator+=(const T&) { return *this; }
1371 };
1372
1373 using reference = output_proxy;
1374
1378 {
1379 return reference();
1380 }
1381
1383 self& operator++() { return *this; }
1384
1386 bool operator==(const self&) const { return true; }
1387
1390};
1391
1392} // namespace apf
1393
1394#endif
output_proxy & operator=(const V &v)
Assignment operator.
Definition: iterator.h:469
An output iterator which adds on assignment.
Definition: iterator.h:446
accumulating_iterator()
Default constructor.
Definition: iterator.h:457
output_proxy operator*()
Dereference operator.
Definition: iterator.h:477
I base() const
Get the base iterator, inspired by std::reverse_iterator::base().
Definition: iterator.h:489
Iterator that casts items to T* on dereferenciation.
Definition: iterator.h:524
pointer operator->() const
Arrow operator.
Definition: iterator.h:550
reference operator[](difference_type n) const
Subscript operator.
Definition: iterator.h:560
Circular iterator class.
Definition: iterator.h:672
circular_iterator(I begin)
Constructor from one iterator.
Definition: iterator.h:724
friend difference_type operator-(const self &lhs, const self &rhs)
Difference operator.
Definition: iterator.h:791
self & operator+=(difference_type n)
Addition/assignment operator.
Definition: iterator.h:770
self & operator++()
Preincrement operator.
Definition: iterator.h:750
circular_iterator(I begin, I end, I current)
Constructor with explicit current iterator.
Definition: iterator.h:695
circular_iterator()
Default constructor.
Definition: iterator.h:736
circular_iterator(I begin, I end)
Constructor with implicit current iterator.
Definition: iterator.h:709
self & operator--()
Predecrement operator.
Definition: iterator.h:760
An iterator which does nothing.
Definition: iterator.h:1351
reference operator*()
Dereference operator.
Definition: iterator.h:1377
self & operator++()
Pre-increment operator (does nothing!)
Definition: iterator.h:1383
bool operator==(const self &) const
Equality operator – always true!
Definition: iterator.h:1386
Helper class for dual_iterator.
Definition: iterator.h:1269
output_proxy & operator+=(const std::pair< T1, T2 > &rhs)
Special addition and assignment operator for std::pair.
Definition: iterator.h:1302
output_proxy & operator+=(const T &rhs)
Default addition and assignment operator.
Definition: iterator.h:1311
output_proxy & operator=(const T &rhs)
Default assignment operator.
Definition: iterator.h:1293
output_proxy & operator=(const std::pair< T1, T2 > &rhs)
Special assignment operator for std::pair.
Definition: iterator.h:1284
Iterate over two iterators at once.
Definition: iterator.h:1210
dual_iterator(I1 i1, I2 i2)
Constructor from two iterators.
Definition: iterator.h:1231
bool operator==(const self &rhs) const
Equality operator.
Definition: iterator.h:1253
self & operator++()
Pre-increment operator.
Definition: iterator.h:1244
reference operator*()
Dereference operator.
Definition: iterator.h:1235
Convenience class providing begin() and end().
Definition: iterator.h:335
has_begin_and_end(iterator b, Distance length)
Constructor with begin and length.
Definition: iterator.h:349
iterator end() const
Get end.
Definition: iterator.h:366
reference operator[](difference_type n) const
Subscript operator.
Definition: iterator.h:370
iterator begin() const
Get begin.
Definition: iterator.h:361
has_begin_and_end(iterator b, iterator e)
Constructor with begin and end.
Definition: iterator.h:345
has_begin_and_end()
Default constructor. Singular iterators are created.
Definition: iterator.h:342
Iterator with a built-in number.
Definition: iterator.h:986
reference operator*() const
Dereference operator.
Definition: iterator.h:1003
index_iterator(T start=T())
Constructor.
Definition: iterator.h:998
Helper class for cast_proxy_const and transform_proxy_const.
Definition: iterator.h:412
Helper class for apf::cast_proxy and apf::transform_proxy.
Definition: iterator.h:386
A stride iterator.
Definition: iterator.h:1051
typename std::iterator_traits< I >::value_type value_type
Base iterator.
Definition: iterator.h:1060
friend difference_type operator-(const self &lhs, const self &rhs)
Base iterator.
Definition: iterator.h:1133
typename std::iterator_traits< I >::difference_type difference_type
Base iterator.
Definition: iterator.h:1061
stride_iterator()
Default constructor.
Definition: iterator.h:1089
typename std::iterator_traits< I >::reference reference
Base iterator.
Definition: iterator.h:1062
typename std::iterator_traits< I >::pointer pointer
Base iterator.
Definition: iterator.h:1063
self & operator--()
Base iterator.
Definition: iterator.h:1109
stride_iterator(I base_iterator, difference_type step)
This is the normal constructor.
Definition: iterator.h:1069
friend bool operator>=(const self &lhs, const self &rhs)
Base iterator.
Definition: iterator.h:1169
self & operator+=(difference_type n)
Base iterator.
Definition: iterator.h:1124
reference operator[](difference_type n) const
Base iterator.
Definition: iterator.h:1117
stride_iterator(stride_iterator< I > base_iterator, difference_type step)
Create a stride iterator from another stride iterator.
Definition: iterator.h:1081
bool operator==(const self &rhs) const
Base iterator.
Definition: iterator.h:1095
self & operator++()
Base iterator.
Definition: iterator.h:1101
typename std::iterator_traits< I >::iterator_category iterator_category
Base iterator.
Definition: iterator.h:1059
friend bool operator>(const self &lhs, const self &rhs)
Base iterator.
Definition: iterator.h:1160
Iterator adaptor with a function call at dereferenciation.
Definition: iterator.h:877
typename std::result_of< _signature >::type reference
Can be a reference, but doesn't necessarily have to.
Definition: iterator.h:887
reference operator*()
Dereference operator.
Definition: iterator.h:902
pointer operator->()
Arrow operator.
Definition: iterator.h:908
transform_iterator(I base_iterator=I(), F f=F())
Constructor.
Definition: iterator.h:893
#define APF_ITERATOR_RANDOMACCESS_POSTINCREMENT
Postincrement operator (using preincrement operator).
Definition: iterator.h:302
#define APF_ITERATOR_RANDOMACCESS_SUBSCRIPT
Straightforward subscript operator (using + and dereference operator).
Definition: iterator.h:266
#define APF_ITERATOR_RANDOMACCESS_ADDITION_ASSIGNMENT(base_member)
Straightforward addition/assignment operator.
Definition: iterator.h:248
#define APF_ITERATOR_RANDOMACCESS_THE_REST
The rest of the random access iterator requirements.
Definition: iterator.h:314
#define APF_ITERATOR_RANDOMACCESS_PREDECREMENT
Straightforward predecrement operator.
Definition: iterator.h:243
#define APF_ITERATOR_FORWARD_UNEQUAL
Unequality operator (using equality operator).
Definition: iterator.h:180
#define APF_ITERATOR_RANDOMACCESS_LESS(base_member)
Straightforward less-than operator.
Definition: iterator.h:274
#define APF_ITERATOR_FORWARD_POSTINCREMENT
Postincrement operator (using preincrement operator).
Definition: iterator.h:177
#define APF_ITERATOR_CONSTRUCTORS(iterator_name, base_iterator_type, base_member)
Straightforward default constructor and constructor from base iterator.
Definition: iterator.h:78
#define APF_ITERATOR_RANDOMACCESS_PREINCREMENT
Straightforward preincrement operator.
Definition: iterator.h:239
#define APF_ITERATOR_RANDOMACCESS_ARROW
Straightforward arrow operator.
Definition: iterator.h:235
#define APF_ITERATOR_OUTPUT_POSTINCREMENT
Postincrement operator (using preincrement operator).
Definition: iterator.h:114
#define APF_ITERATOR_RANDOMACCESS_UNEQUAL
Unequality operator (using equality operator).
Definition: iterator.h:284
#define APF_ITERATOR_OUTPUT_PREINCREMENT(base_member)
Straightforward preincrement operator.
Definition: iterator.h:107
#define APF_ITERATOR_RANDOMACCESS_EQUAL
Straightforward equality operator.
Definition: iterator.h:227
#define APF_ITERATOR_RANDOMACCESS_DEREFERENCE
Straightforward dereference operator.
Definition: iterator.h:231
#define APF_ITERATOR_RANDOMACCESS_POSTDECREMENT
Postdecrement operator (using predecrement operator)
Definition: iterator.h:306
#define APF_ITERATOR_BASE(base_iterator_type, base_member)
Get the base iterator.
Definition: iterator.h:89
#define APF_ITERATOR_RANDOMACCESS_OTHER_COMPARISONS
Other comparisons (>, <=, >=).
Definition: iterator.h:289
#define APF_ITERATOR_RANDOMACCESS_DIFFERENCE(base_member)
Straightforward difference operator.
Definition: iterator.h:257
dual_iterator< I1, I2 > make_dual_iterator(I1 i1, I2 i2)
Helper function to create an dual_iterator.
Definition: iterator.h:1334
transform_iterator< I, F > make_transform_iterator(I base_iterator, F f)
Helper function to create a transform_iterator.
Definition: iterator.h:944
accumulating_iterator< I > make_accumulating_iterator(I base_iterator)
Helper function to create an accumulating_iterator.
Definition: iterator.h:505
circular_iterator< I > make_circular_iterator(I begin, I end)
Helper function to create a circular_iterator.
Definition: iterator.h:840
cast_iterator< T, I > make_cast_iterator(I base_iterator)
Helper function to create a cast_iterator.
Definition: iterator.h:606
index_iterator< T > make_index_iterator(T start)
Helper function to create an index_iterator.
Definition: iterator.h:1034
Mathematical constants and helper functions.
T wrap(T x, T full)
Wrap x into the interval [0, full).
Definition: math.h:151
Audio Processing Framework.
Definition: iterator.h:61
bool no_nullptr(T *in)
Check for null-pointer.
Definition: iterator.h:64
cast_proxy_const< T, Container > make_cast_proxy_const(Container &l)
Helper function to create a cast_proxy_const.
Definition: iterator.h:657
cast_proxy< T, Container > make_cast_proxy(Container &l)
Helper function to create a cast_proxy.
Definition: iterator.h:632
Encapsulate a container of base pointers (const version).
Definition: iterator.h:644
Encapsulate a container of base pointers.
Definition: iterator.h:619
Helper class for discard_iterator.
Definition: iterator.h:1363
output_proxy & operator=(const T &)
Assignment operator (does nothing!)
Definition: iterator.h:1366
output_proxy & operator+=(const T &)
Addition and assignment operator (does nothing!)
Definition: iterator.h:1370
Wrap a container and provide a transform_iterator (const version).
Definition: iterator.h:971
Wrap a container and provide a transform_iterator instead of the normal one.
Definition: iterator.h:957