diff --git a/src/util/filter.hpp b/src/util/filter.hpp index 5fcbd1fd687e9a191f168036fb5925c961743614..6da37f57c175dacfd1a989c4e39a3da6544f47f8 100644 --- a/src/util/filter.hpp +++ b/src/util/filter.hpp @@ -32,12 +32,29 @@ namespace impl { }; } +/* + * Iterate through a sequence such that dereference only + * gives items from the range that satisfy a given predicate. + * + * Type parameters: + * I Iterator type + * S Sentinel type compatible with I + * F Functional object + * + * The underlying sequence is described by an iterator of type + * I and a sentinel of type S. The predicate has type F. + */ + template <typename I, typename S, typename F> class filter_iterator { mutable I inner_; S end_; mutable bool ok_; - mutable uninitialized<F> f_; // always in initialized state post-construction + + // F may be a lambda type, and thus non-copy assignable. The + // use of `uninitalized` allows us to work around this limitation; + // f_ will always be in an initalized state post-construction. + mutable uninitialized<F> f_; void advance() const { if (ok_) return; diff --git a/src/util/transform.hpp b/src/util/transform.hpp index ec86ea71d5c46f053711783e21795a78d3904a41..71c49e723017deb92258dc02be21e66da7dd9118 100644 --- a/src/util/transform.hpp +++ b/src/util/transform.hpp @@ -26,7 +26,10 @@ class transform_iterator: public iterator_adaptor<transform_iterator<I, F>, I> { friend class iterator_adaptor<transform_iterator<I, F>, I>; I inner_; - uninitialized<F> f_; // always in initialized state post-construction + + // F may be a lambda type, and thus non-copy assignable. The + // use of `uninitalized` allows us to work around this limitation; + uninitialized<F> f_; // provides access to inner iterator for adaptor. const I& inner() const { return inner_; }