Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:17:31

0001 // (C) Copyright David Abrahams 2002.
0002 // (C) Copyright Jeremy Siek    2002.
0003 // (C) Copyright Thomas Witt    2002.
0004 // Distributed under the Boost Software License, Version 1.0. (See
0005 // accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
0008 #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
0009 
0010 #include <boost/config.hpp>
0011 #include <boost/config/workaround.hpp>
0012 #include <boost/iterator/detail/enable_if.hpp>
0013 #include <boost/iterator/iterator_adaptor.hpp>
0014 #include <boost/iterator/iterator_categories.hpp>
0015 #include <boost/type_traits/function_traits.hpp>
0016 #include <boost/type_traits/is_const.hpp>
0017 #include <boost/type_traits/is_class.hpp>
0018 #include <boost/type_traits/is_function.hpp>
0019 #include <boost/type_traits/is_reference.hpp>
0020 #include <boost/type_traits/remove_const.hpp>
0021 #include <boost/type_traits/remove_reference.hpp>
0022 #include <boost/utility/result_of.hpp>
0023 
0024 #include <iterator>
0025 
0026 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
0027 #include <boost/type_traits/is_base_and_derived.hpp>
0028 #endif
0029 
0030 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
0031 #include <boost/static_assert.hpp>
0032 #endif
0033 
0034 #include <boost/iterator/detail/config_def.hpp>
0035 
0036 
0037 namespace boost {
0038 namespace iterators {
0039 
0040   template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
0041   class transform_iterator;
0042 
0043   namespace detail
0044   {
0045     // Compute the iterator_adaptor instantiation to be used for transform_iterator
0046     template <class UnaryFunc, class Iterator, class Reference, class Value>
0047     struct transform_iterator_base
0048     {
0049      private:
0050         // By default, dereferencing the iterator yields the same as
0051         // the function.
0052         typedef typename ia_dflt_help<
0053             Reference
0054 #ifdef BOOST_RESULT_OF_USE_TR1
0055           , result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
0056 #else
0057           , result_of<const UnaryFunc&(typename std::iterator_traits<Iterator>::reference)>
0058 #endif
0059         >::type reference;
0060 
0061         // To get the default for Value: remove any reference on the
0062         // result type, but retain any constness to signal
0063         // non-writability.  Note that if we adopt Thomas' suggestion
0064         // to key non-writability *only* on the Reference argument,
0065         // we'd need to strip constness here as well.
0066         typedef typename ia_dflt_help<
0067             Value
0068           , remove_reference<reference>
0069         >::type cv_value_type;
0070 
0071      public:
0072         typedef iterator_adaptor<
0073             transform_iterator<UnaryFunc, Iterator, Reference, Value>
0074           , Iterator
0075           , cv_value_type
0076           , use_default    // Leave the traversal category alone
0077           , reference
0078         > type;
0079     };
0080   }
0081 
0082   template <class UnaryFunc, class Iterator, class Reference, class Value>
0083   class transform_iterator
0084     : public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
0085   {
0086     typedef typename
0087     boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
0088     super_t;
0089 
0090     friend class iterator_core_access;
0091 
0092   public:
0093     transform_iterator() { }
0094 
0095     transform_iterator(Iterator const& x, UnaryFunc f)
0096       : super_t(x), m_f(f) { }
0097 
0098     explicit transform_iterator(Iterator const& x)
0099       : super_t(x)
0100     {
0101         // Pro8 is a little too aggressive about instantiating the
0102         // body of this function.
0103 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
0104         // don't provide this constructor if UnaryFunc is a
0105         // function pointer type, since it will be 0.  Too dangerous.
0106         BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
0107 #endif
0108     }
0109 
0110     template <
0111         class OtherUnaryFunction
0112       , class OtherIterator
0113       , class OtherReference
0114       , class OtherValue>
0115     transform_iterator(
0116          transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
0117        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
0118 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
0119        , typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
0120 #endif
0121     )
0122       : super_t(t.base()), m_f(t.functor())
0123    {}
0124 
0125     UnaryFunc functor() const
0126       { return m_f; }
0127 
0128   private:
0129     typename super_t::reference dereference() const
0130     { return m_f(*this->base()); }
0131 
0132     // Probably should be the initial base class so it can be
0133     // optimized away via EBO if it is an empty class.
0134     UnaryFunc m_f;
0135   };
0136 
0137   template <class UnaryFunc, class Iterator>
0138   inline transform_iterator<UnaryFunc, Iterator>
0139   make_transform_iterator(Iterator it, UnaryFunc fun)
0140   {
0141       return transform_iterator<UnaryFunc, Iterator>(it, fun);
0142   }
0143 
0144   // Version which allows explicit specification of the UnaryFunc
0145   // type.
0146   //
0147   // This generator is not provided if UnaryFunc is a function
0148   // pointer type, because it's too dangerous: the default-constructed
0149   // function pointer in the iterator be 0, leading to a runtime
0150   // crash.
0151   template <class UnaryFunc, class Iterator>
0152   inline typename iterators::enable_if<
0153       is_class<UnaryFunc>   // We should probably find a cheaper test than is_class<>
0154     , transform_iterator<UnaryFunc, Iterator>
0155   >::type
0156   make_transform_iterator(Iterator it)
0157   {
0158       return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
0159   }
0160 
0161 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0162   template <class Return, class Argument, class Iterator>
0163   inline transform_iterator< Return (*)(Argument), Iterator, Return>
0164   make_transform_iterator(Iterator it, Return (*fun)(Argument))
0165   {
0166     return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
0167   }
0168 #endif
0169 
0170 } // namespace iterators
0171 
0172 using iterators::transform_iterator;
0173 using iterators::make_transform_iterator;
0174 
0175 } // namespace boost
0176 
0177 #include <boost/iterator/detail/config_undef.hpp>
0178 
0179 #endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP