// Copyright Louis Dionne 2012. Use, modification and distribution is subject // to the Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ITERATOR_TRANSFORM_OUTPUT_ITERATOR_HPP #define BOOST_ITERATOR_TRANSFORM_OUTPUT_ITERATOR_HPP #include #include #include #include #include namespace boost { template struct is_transform_output_iterator_type; template class transform_output_iterator { UnaryFunction f_; Iterator out_; template class output_proxy { UnaryFunction_& f_; Iterator_& out_; public: explicit output_proxy(UnaryFunction_& f, Iterator_& out) : f_(f), out_(out) { } template output_proxy& operator=(T const& x) { *out_ = f_(x); return *this; } }; // Apply the append metafunction to a given type. This is only required // for the eval_if construct below. template struct apply_append { typedef typename It::template append::type type; }; // Metafunction computing the type of a transform_output_iterator applying // the G function after applying all the function it currently applies. template struct append { typedef transform_output_iterator, apply_append, mpl::identity > >::type > type; }; // We need to friend all types of transform_output_iterator because we // need to access the and_then_impl method of out_. template friend class transform_output_iterator; template typename enable_if, typename append::type>::type and_then_impl(G const& g) const { return typename append::type(f_, out_.and_then_impl(g)); } template typename disable_if, typename append::type>::type and_then_impl(G const& g) const { typedef transform_output_iterator last_type; typedef transform_output_iterator before_last_type; return before_last_type(f_, last_type(g, out_)); } public: typedef void value_type; typedef void reference; typedef void pointer; typedef void difference_type; typedef incrementable_traversal_tag iterator_category; template typename append::type and_then(G const& g = G()) const { return and_then_impl(g); } explicit transform_output_iterator(UnaryFunction const& f, Iterator const& iterator) : f_(f), out_(iterator) { } explicit transform_output_iterator(Iterator const& iterator) : out_(iterator) { } transform_output_iterator& operator++() { ++out_; return *this; } transform_output_iterator operator++(int) { transform_output_iterator tmp(*this); ++out_; return tmp; } output_proxy operator*() { return output_proxy(f_, out_); } output_proxy operator*() const { return output_proxy(f_, out_); } }; template struct is_transform_output_iterator_type : mpl::false_ { }; template struct is_transform_output_iterator_type< transform_output_iterator > : mpl::true_ { }; template bool is_transform_output_iterator(Iterator const&) { return ::boost::is_transform_output_iterator_type::value; } template transform_output_iterator make_transform_output_iterator(UnaryFunction const& f, Iterator const& iterator) { return transform_output_iterator(f, iterator); } template transform_output_iterator make_transform_output_iterator(Iterator const& iterator) { return transform_output_iterator(iterator); } } // end namespace boost #endif // !BOOST_ITERATOR_TRANSFORM_OUTPUT_ITERATOR_HPP