diff --git a/src/util/transform.hpp b/src/util/transform.hpp index a5ab0b348a61fb0f3a174058dc31fdb128776e24..046b201e13c6d8a43989b5cf1d7f063c207a2ce3 100644 --- a/src/util/transform.hpp +++ b/src/util/transform.hpp @@ -23,7 +23,7 @@ class transform_iterator: public iterator_adaptor<transform_iterator<I, F>, I> { friend class iterator_adaptor<transform_iterator<I, F>, I>; I inner_; - F f_; + uninitialized<F> f_; // always in initialized state post-construction // provides access to inner iterator for adaptor. const I& inner() const { return inner_; } @@ -40,17 +40,39 @@ public: transform_iterator() = default; template <typename J, typename G> - transform_iterator(J&& c, G&& g): inner_(std::forward<J>(c)), f_(std::forward<G>(g)) {} + transform_iterator(J&& c, G&& g): inner_(std::forward<J>(c)) { + f_.construct(std::forward<G>(g)); + } + + transform_iterator(const transform_iterator& other): inner_(other.inner_) { + f_.construct(other.f_.cref()); + } + + transform_iterator(transform_iterator&& other): inner_(std::move(other.inner_)) { + f_.construct(std::move(other.f_.ref())); + } + + transform_iterator& operator=(transform_iterator&& other) { + if (this!=&other) { + inner_ = std::move(other.inner_); + f_.construct(std::move(other.f_.ref())); + } + return *this; + } - transform_iterator(const transform_iterator&) = default; - transform_iterator(transform_iterator&&) = default; - transform_iterator& operator=(const transform_iterator&) = default; - transform_iterator& operator=(transform_iterator&&) = default; + transform_iterator& operator=(const transform_iterator& other) { + if (this!=&other) { + inner_ = other.inner_; + f_.destruct(); + f_.construct(other.f_.cref()); + } + return *this; + } // forward and input iterator requirements value_type operator*() const { - return f_(*inner_); + return f_.cref()(*inner_); } util::pointer_proxy<value_type> operator->() const {