64template<
typename T>
bool no_nullptr(T* in) {
return in !=
nullptr; }
78#define APF_ITERATOR_CONSTRUCTORS(iterator_name, base_iterator_type, base_member) \
80 explicit iterator_name(base_iterator_type base_iterator) \
81 : base_member(base_iterator) {} \
83 iterator_name() : base_member() {}
89#define APF_ITERATOR_BASE(base_iterator_type, base_member) \
91 base_iterator_type base() const { assert(apf::no_nullptr(base_member)); \
92 return (base_member); }
99#define APF_ITERATOR_OUTPUT_DEREFERENCE(base_member) \
101 reference operator*() const { assert(apf::no_nullptr(base_member)); \
102 return *(base_member); }
107#define APF_ITERATOR_OUTPUT_PREINCREMENT(base_member) \
109 self& operator++() { assert(apf::no_nullptr(base_member)); \
110 ++(base_member); return *this; }
114#define APF_ITERATOR_OUTPUT_POSTINCREMENT \
116 self operator++(int) { self tmp = *this; ++(*this); return tmp; }
123#define APF_ITERATOR_INPUT_DEREFERENCE APF_ITERATOR_OUTPUT_DEREFERENCE
128#define APF_ITERATOR_INPUT_ARROW(base_member) \
130 pointer operator->() const { assert(apf::no_nullptr(base_member)); \
131 return (base_member); }
136#define APF_ITERATOR_INPUT_EQUAL(base_member) \
138 bool operator==(const self& rhs) const { \
139 return ((base_member) == (rhs.base_member)); }
144#define APF_ITERATOR_INPUT_PREINCREMENT APF_ITERATOR_OUTPUT_PREINCREMENT
148#define APF_ITERATOR_INPUT_POSTINCREMENT APF_ITERATOR_OUTPUT_POSTINCREMENT
152#define APF_ITERATOR_INPUT_UNEQUAL \
154 bool operator!=(const self& rhs) const { return !operator==(rhs); } \
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
177#define APF_ITERATOR_FORWARD_POSTINCREMENT APF_ITERATOR_INPUT_POSTINCREMENT
180#define APF_ITERATOR_FORWARD_UNEQUAL APF_ITERATOR_INPUT_UNEQUAL
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
204#define APF_ITERATOR_BIDIRECTIONAL_PREDECREMENT(base_member) \
206 self& operator--() { assert(apf::no_nullptr(base_member)); \
207 --(base_member); return *this; }
211#define APF_ITERATOR_BIDIRECTIONAL_POSTINCREMENT APF_ITERATOR_FORWARD_POSTINCREMENT
214#define APF_ITERATOR_BIDIRECTIONAL_UNEQUAL APF_ITERATOR_FORWARD_UNEQUAL
218#define APF_ITERATOR_BIDIRECTIONAL_POSTDECREMENT \
220 self operator--(int) { self tmp = *this; --(*this); return tmp; }
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
248#define APF_ITERATOR_RANDOMACCESS_ADDITION_ASSIGNMENT(base_member) \
250 self& operator+=(difference_type n) { \
251 assert(!n || apf::no_nullptr(base_member)); \
252 (base_member) += n; return *this; }
257#define APF_ITERATOR_RANDOMACCESS_DIFFERENCE(base_member) \
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)); }
266#define APF_ITERATOR_RANDOMACCESS_SUBSCRIPT \
268 reference operator[](difference_type n) const { \
269 return *(*this + n); }
274#define APF_ITERATOR_RANDOMACCESS_LESS(base_member) \
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); }
284#define APF_ITERATOR_RANDOMACCESS_UNEQUAL APF_ITERATOR_BIDIRECTIONAL_UNEQUAL
289#define APF_ITERATOR_RANDOMACCESS_OTHER_COMPARISONS \
291 friend bool operator>(const self& lhs, const self& rhs) \
292 { return rhs < lhs; } \
294 friend bool operator<=(const self& lhs, const self& rhs) \
295 { return !(rhs < lhs); } \
297 friend bool operator>=(const self& lhs, const self& rhs) \
298 { return !(lhs < rhs); }
302#define APF_ITERATOR_RANDOMACCESS_POSTINCREMENT APF_ITERATOR_BIDIRECTIONAL_POSTINCREMENT
306#define APF_ITERATOR_RANDOMACCESS_POSTDECREMENT APF_ITERATOR_BIDIRECTIONAL_POSTDECREMENT
314#define APF_ITERATOR_RANDOMACCESS_THE_REST \
316 self operator+(difference_type n) const { self tmp(*this); return tmp += n; }\
318 friend self operator+(difference_type n, const self& it) { \
319 self temp(it); return temp += n; } \
321 self& operator-=(difference_type n) { *this += -n; return *this; } \
323 self operator-(difference_type n) const { self tmp(*this); return tmp += -n; }
338 using reference =
typename std::iterator_traits<I>::reference;
339 using difference_type =
typename std::iterator_traits<I>::difference_type;
348 template<
typename Distance>
353 std::advance(_end,
static_cast<std::make_signed_t<Distance>
>(length));
361 iterator
begin()
const {
return _begin; }
366 iterator
end()
const {
return _end; }
370 reference
operator[](difference_type n)
const {
return _begin[n]; }
373 iterator _begin, _end;
376template<
typename I,
typename... Args>
377has_begin_and_end<I> make_begin_and_end(I first, Args&&... args)
379 return {first, std::forward<Args>(args)...};
384template<
typename I,
typename Container>
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;
396 iterator begin()
const {
return iterator(_l.begin()); }
397 iterator end()
const {
return iterator(_l.end()); }
399 rbegin()
const {
return reverse_iterator(iterator(_l.end())); }
401 rend()
const {
return reverse_iterator(iterator(_l.begin())); }
402 size_type size()
const {
return _l.size(); }
410template<
typename I,
typename Container>
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;
422 iterator begin()
const {
return iterator(_l.begin()); }
423 iterator end()
const {
return iterator(_l.end()); }
425 rbegin()
const {
return reverse_iterator(iterator(_l.end())); }
427 rend()
const {
return reverse_iterator(iterator(_l.begin())); }
428 size_type size()
const {
return _l.size(); }
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;
522template<
typename T,
typename I>
529 using value_type = 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;
542 reference operator*()
const
545 return *this->operator->();
554 return _cast_helper(*_base_iterator);
563 return *_cast_helper(_base_iterator[n]);
588 pointer _cast_helper(X* ptr)
const
590 return static_cast<pointer
>(ptr);
604template<
typename T,
typename I>
616template<
typename T,
typename Container>
618 cast_iterator<T, typename Container::iterator>, Container>
620 using value_type = T;
624 T,
typename Container::iterator>, Container>(l)
630template<
typename T,
typename Container>
641template<
typename T,
typename Container>
643 cast_iterator<const T, typename Container::const_iterator>, Container>
645 using value_type = T;
649 const T,
typename Container::const_iterator>, Container>(l)
655template<
typename T,
typename Container>
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;
698 , _current((current == end) ? begin : current)
701 assert(_begin != _end);
702 assert(_current != _end);
715 assert(_begin != _end);
730 assert(_begin != _end);
754 if (_current == _end) _current = _begin;
763 if (_current == _begin) _current = _end;
774 difference_type length = _end - _begin;
775 difference_type index = _current - _begin;
796 assert(lhs._begin == rhs._begin);
797 assert(lhs._end == rhs._end );
799 difference_type d = lhs._current - rhs._current;
803 d = lhs._current - lhs._begin + rhs._end - rhs._current;
875template<
typename I,
typename F>
881 using _signature = F(
typename std::iterator_traits<I>::value_type&);
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;
894 : _base_iterator(base_iterator)
942template<typename I, typename F>
954template<
typename F,
typename Container>
956 transform_iterator<typename Container::iterator, F>, Container>
960 typename Container::iterator, F>, Container>(l)
968template<
typename F,
typename Container>
970 transform_iterator<typename Container::const_iterator, F>, Container>
974 typename Container::const_iterator, F>, Container>(l)
991 using iterator_category = std::random_access_iterator_tag;
992 using value_type = T;
994 using difference_type = T;
995 using pointer = void;
1059 =
typename std::iterator_traits<I>::iterator_category;
1062 using reference =
typename std::iterator_traits<I>::reference;
1063 using pointer =
typename std::iterator_traits<I>::pointer;
1070#ifdef APF_STRIDE_ITERATOR_DEFAULT_STRIDE
1071 = APF_STRIDE_ITERATOR_DEFAULT_STRIDE
1074 : _iter(base_iterator)
1082 : _iter(base_iterator.
base())
1083 , _step(base_iterator.step_size() * step)
1097 return _iter == rhs._iter && _step == rhs._step;
1104 std::advance(_iter, _step);
1112 std::advance(_iter, -_step);
1120 return _iter[n * _step];
1127 std::advance(_iter, n * _step);
1136 assert(lhs._step == rhs._step);
1137 return (lhs._iter - rhs._iter) / lhs._step;
1142 operator<(
const self& lhs,
const self& rhs)
1145 assert(lhs._step == rhs._step);
1146 return lhs._iter < rhs._iter;
1151 operator<=(
const self& lhs,
const self& rhs)
1154 assert(lhs._step == rhs._step);
1155 return lhs._iter <= rhs._iter;
1163 assert(lhs._step == rhs._step);
1164 return lhs._iter > rhs._iter;
1172 assert(lhs._step == rhs._step);
1173 return lhs._iter >= rhs._iter;
1192 difference_type _step;
1208template<
typename I1,
typename I2 = I1>
1217 using iterator_category = std::forward_iterator_tag;
1219 using value_type = std::pair<typename std::iterator_traits<I1>::value_type
1220 ,
typename std::iterator_traits<I2>::value_type>;
1225 using difference_type = std::ptrdiff_t;
1226 using pointer = void;
1255 return (_i1 == rhs._i1) && (_i2 == rhs._i2);
1267template<
typename I1,
typename I2>
1271 explicit output_proxy(I1& i1, I2& i2) : _i1(i1), _i2(i2) {}
1276 template<
typename T1,
typename T2>
1277 operator std::pair<T1, T2>()
1279 return {*_i1, *_i2};
1283 template<
typename T1,
typename T2>
1292 template<
typename T>
1301 template<
typename T1,
typename T2>
1310 template<
typename T>
1332template<
typename I1,
typename I2>
1356 using iterator_category = std::output_iterator_tag;
1357 using value_type = void;
1358 using difference_type = void;
1359 using pointer = void;
1365 template<
typename T>
1369 template<
typename T>
1373 using reference = output_proxy;
output_proxy(I &i)
Constructor.
output_proxy & operator=(const V &v)
Assignment operator.
An output iterator which adds on assignment.
accumulating_iterator()
Default constructor.
output_proxy operator*()
Dereference operator.
I base() const
Get the base iterator, inspired by std::reverse_iterator::base().
Iterator that casts items to T* on dereferenciation.
pointer operator->() const
Arrow operator.
reference operator[](difference_type n) const
Subscript operator.
circular_iterator(I begin)
Constructor from one iterator.
friend difference_type operator-(const self &lhs, const self &rhs)
Difference operator.
self & operator+=(difference_type n)
Addition/assignment operator.
self & operator++()
Preincrement operator.
circular_iterator(I begin, I end, I current)
Constructor with explicit current iterator.
circular_iterator()
Default constructor.
circular_iterator(I begin, I end)
Constructor with implicit current iterator.
self & operator--()
Predecrement operator.
An iterator which does nothing.
reference operator*()
Dereference operator.
self & operator++()
Pre-increment operator (does nothing!)
bool operator==(const self &) const
Equality operator – always true!
Helper class for dual_iterator.
output_proxy & operator+=(const std::pair< T1, T2 > &rhs)
Special addition and assignment operator for std::pair.
output_proxy & operator+=(const T &rhs)
Default addition and assignment operator.
output_proxy & operator=(const T &rhs)
Default assignment operator.
output_proxy & operator=(const std::pair< T1, T2 > &rhs)
Special assignment operator for std::pair.
Iterate over two iterators at once.
dual_iterator(I1 i1, I2 i2)
Constructor from two iterators.
bool operator==(const self &rhs) const
Equality operator.
self & operator++()
Pre-increment operator.
reference operator*()
Dereference operator.
Convenience class providing begin() and end().
has_begin_and_end(iterator b, Distance length)
Constructor with begin and length.
iterator end() const
Get end.
reference operator[](difference_type n) const
Subscript operator.
iterator begin() const
Get begin.
has_begin_and_end(iterator b, iterator e)
Constructor with begin and end.
has_begin_and_end()
Default constructor. Singular iterators are created.
Iterator with a built-in number.
reference operator*() const
Dereference operator.
index_iterator(T start=T())
Constructor.
Helper class for cast_proxy_const and transform_proxy_const.
Helper class for apf::cast_proxy and apf::transform_proxy.
typename std::iterator_traits< I >::value_type value_type
Base iterator.
friend difference_type operator-(const self &lhs, const self &rhs)
Base iterator.
typename std::iterator_traits< I >::difference_type difference_type
Base iterator.
stride_iterator()
Default constructor.
typename std::iterator_traits< I >::reference reference
Base iterator.
typename std::iterator_traits< I >::pointer pointer
Base iterator.
self & operator--()
Base iterator.
stride_iterator(I base_iterator, difference_type step)
This is the normal constructor.
friend bool operator>=(const self &lhs, const self &rhs)
Base iterator.
self & operator+=(difference_type n)
Base iterator.
reference operator[](difference_type n) const
Base iterator.
stride_iterator(stride_iterator< I > base_iterator, difference_type step)
Create a stride iterator from another stride iterator.
bool operator==(const self &rhs) const
Base iterator.
self & operator++()
Base iterator.
typename std::iterator_traits< I >::iterator_category iterator_category
Base iterator.
friend bool operator>(const self &lhs, const self &rhs)
Base iterator.
#define APF_ITERATOR_RANDOMACCESS_POSTINCREMENT
Postincrement operator (using preincrement operator).
#define APF_ITERATOR_RANDOMACCESS_SUBSCRIPT
Straightforward subscript operator (using + and dereference operator).
#define APF_ITERATOR_RANDOMACCESS_ADDITION_ASSIGNMENT(base_member)
Straightforward addition/assignment operator.
#define APF_ITERATOR_RANDOMACCESS_THE_REST
The rest of the random access iterator requirements.
#define APF_ITERATOR_RANDOMACCESS_PREDECREMENT
Straightforward predecrement operator.
#define APF_ITERATOR_FORWARD_UNEQUAL
Unequality operator (using equality operator).
#define APF_ITERATOR_RANDOMACCESS_LESS(base_member)
Straightforward less-than operator.
#define APF_ITERATOR_FORWARD_POSTINCREMENT
Postincrement operator (using preincrement operator).
#define APF_ITERATOR_CONSTRUCTORS(iterator_name, base_iterator_type, base_member)
Straightforward default constructor and constructor from base iterator.
#define APF_ITERATOR_RANDOMACCESS_PREINCREMENT
Straightforward preincrement operator.
#define APF_ITERATOR_RANDOMACCESS_ARROW
Straightforward arrow operator.
#define APF_ITERATOR_OUTPUT_POSTINCREMENT
Postincrement operator (using preincrement operator).
#define APF_ITERATOR_RANDOMACCESS_UNEQUAL
Unequality operator (using equality operator).
#define APF_ITERATOR_OUTPUT_PREINCREMENT(base_member)
Straightforward preincrement operator.
#define APF_ITERATOR_RANDOMACCESS_EQUAL
Straightforward equality operator.
#define APF_ITERATOR_RANDOMACCESS_DEREFERENCE
Straightforward dereference operator.
#define APF_ITERATOR_RANDOMACCESS_POSTDECREMENT
Postdecrement operator (using predecrement operator)
#define APF_ITERATOR_BASE(base_iterator_type, base_member)
Get the base iterator.
#define APF_ITERATOR_RANDOMACCESS_OTHER_COMPARISONS
Other comparisons (>, <=, >=).
#define APF_ITERATOR_RANDOMACCESS_DIFFERENCE(base_member)
Straightforward difference operator.
dual_iterator< I1, I2 > make_dual_iterator(I1 i1, I2 i2)
Helper function to create an dual_iterator.
transform_iterator< I, F > make_transform_iterator(I base_iterator, F f)
Helper function to create a transform_iterator.
accumulating_iterator< I > make_accumulating_iterator(I base_iterator)
Helper function to create an accumulating_iterator.
circular_iterator< I > make_circular_iterator(I begin, I end)
Helper function to create a circular_iterator.
cast_iterator< T, I > make_cast_iterator(I base_iterator)
Helper function to create a cast_iterator.
index_iterator< T > make_index_iterator(T start)
Helper function to create an index_iterator.
Mathematical constants and helper functions.
T wrap(T x, T full)
Wrap x into the interval [0, full).
Audio Processing Framework.
bool no_nullptr(T *in)
Check for null-pointer.
cast_proxy_const< T, Container > make_cast_proxy_const(Container &l)
Helper function to create a cast_proxy_const.
cast_proxy< T, Container > make_cast_proxy(Container &l)
Helper function to create a cast_proxy.
Encapsulate a container of base pointers (const version).
Encapsulate a container of base pointers.
Helper class for discard_iterator.
output_proxy & operator=(const T &)
Assignment operator (does nothing!)
output_proxy & operator+=(const T &)
Addition and assignment operator (does nothing!)