diff --git a/src/util/transform.hpp b/src/util/transform.hpp index 5982cfea668354e1f13b5893336f656cca60f3e5..ec86ea71d5c46f053711783e21795a78d3904a41 100644 --- a/src/util/transform.hpp +++ b/src/util/transform.hpp @@ -26,7 +26,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_; } @@ -43,17 +43,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 {