Chris@16: // (C) Copyright David Abrahams 2002. Chris@16: // (C) Copyright Jeremy Siek 2002. Chris@16: // (C) Copyright Thomas Witt 2002. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP Chris@16: #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) Chris@16: # include Chris@16: Chris@101: #endif Chris@16: #include Chris@16: Chris@16: Chris@101: namespace boost { Chris@101: namespace iterators { Chris@101: Chris@16: template Chris@16: class transform_iterator; Chris@16: Chris@101: namespace detail Chris@16: { Chris@16: // Compute the iterator_adaptor instantiation to be used for transform_iterator Chris@16: template Chris@16: struct transform_iterator_base Chris@16: { Chris@16: private: Chris@16: // By default, dereferencing the iterator yields the same as Chris@16: // the function. Chris@16: typedef typename ia_dflt_help< Chris@16: Reference Chris@16: , result_of::reference)> Chris@16: >::type reference; Chris@16: Chris@16: // To get the default for Value: remove any reference on the Chris@16: // result type, but retain any constness to signal Chris@16: // non-writability. Note that if we adopt Thomas' suggestion Chris@16: // to key non-writability *only* on the Reference argument, Chris@16: // we'd need to strip constness here as well. Chris@16: typedef typename ia_dflt_help< Chris@16: Value Chris@16: , remove_reference Chris@16: >::type cv_value_type; Chris@16: Chris@16: public: Chris@16: typedef iterator_adaptor< Chris@16: transform_iterator Chris@16: , Iterator Chris@16: , cv_value_type Chris@16: , use_default // Leave the traversal category alone Chris@16: , reference Chris@16: > type; Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: class transform_iterator Chris@101: : public boost::iterators::detail::transform_iterator_base::type Chris@16: { Chris@16: typedef typename Chris@101: boost::iterators::detail::transform_iterator_base::type Chris@16: super_t; Chris@16: Chris@16: friend class iterator_core_access; Chris@16: Chris@16: public: Chris@16: transform_iterator() { } Chris@16: Chris@16: transform_iterator(Iterator const& x, UnaryFunc f) Chris@16: : super_t(x), m_f(f) { } Chris@16: Chris@16: explicit transform_iterator(Iterator const& x) Chris@16: : super_t(x) Chris@16: { Chris@16: // Pro8 is a little too aggressive about instantiating the Chris@16: // body of this function. Chris@16: #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) Chris@16: // don't provide this constructor if UnaryFunc is a Chris@16: // function pointer type, since it will be 0. Too dangerous. Chris@16: BOOST_STATIC_ASSERT(is_class::value); Chris@101: #endif Chris@16: } Chris@16: Chris@16: template < Chris@16: class OtherUnaryFunction Chris@16: , class OtherIterator Chris@16: , class OtherReference Chris@16: , class OtherValue> Chris@16: transform_iterator( Chris@16: transform_iterator const& t Chris@16: , typename enable_if_convertible::type* = 0 Chris@16: #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) Chris@16: , typename enable_if_convertible::type* = 0 Chris@101: #endif Chris@16: ) Chris@16: : super_t(t.base()), m_f(t.functor()) Chris@16: {} Chris@16: Chris@16: UnaryFunc functor() const Chris@16: { return m_f; } Chris@16: Chris@16: private: Chris@16: typename super_t::reference dereference() const Chris@16: { return m_f(*this->base()); } Chris@16: Chris@16: // Probably should be the initial base class so it can be Chris@16: // optimized away via EBO if it is an empty class. Chris@16: UnaryFunc m_f; Chris@16: }; Chris@16: Chris@16: template Chris@101: inline transform_iterator Chris@16: make_transform_iterator(Iterator it, UnaryFunc fun) Chris@16: { Chris@16: return transform_iterator(it, fun); Chris@16: } Chris@16: Chris@16: // Version which allows explicit specification of the UnaryFunc Chris@16: // type. Chris@16: // Chris@16: // This generator is not provided if UnaryFunc is a function Chris@16: // pointer type, because it's too dangerous: the default-constructed Chris@16: // function pointer in the iterator be 0, leading to a runtime Chris@16: // crash. Chris@16: template Chris@101: inline typename iterators::enable_if< Chris@16: is_class // We should probably find a cheaper test than is_class<> Chris@16: , transform_iterator Chris@16: >::type Chris@16: make_transform_iterator(Iterator it) Chris@16: { Chris@16: return transform_iterator(it, UnaryFunc()); Chris@16: } Chris@16: Chris@16: #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: template Chris@101: inline transform_iterator< Return (*)(Argument), Iterator, Return> Chris@16: make_transform_iterator(Iterator it, Return (*fun)(Argument)) Chris@16: { Chris@16: return transform_iterator(it, fun); Chris@16: } Chris@16: #endif Chris@16: Chris@101: } // namespace iterators Chris@101: Chris@101: using iterators::transform_iterator; Chris@101: using iterators::make_transform_iterator; Chris@101: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP