]> git.lyx.org Git - lyx.git/blob - boost/boost/iterator/transform_iterator.hpp
update boost to 1.44
[lyx.git] / boost / boost / iterator / transform_iterator.hpp
1 // (C) Copyright David Abrahams 2002.
2 // (C) Copyright Jeremy Siek    2002.
3 // (C) Copyright Thomas Witt    2002.
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
8 #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
9
10 #include <boost/iterator.hpp>
11 #include <boost/iterator/detail/enable_if.hpp>
12 #include <boost/iterator/iterator_adaptor.hpp>
13 #include <boost/iterator/iterator_categories.hpp>
14 #include <boost/mpl/not.hpp>
15 #include <boost/mpl/bool.hpp>
16 #include <boost/type_traits/function_traits.hpp>
17 #include <boost/type_traits/is_const.hpp>
18 #include <boost/type_traits/is_class.hpp>
19 #include <boost/type_traits/is_function.hpp>
20 #include <boost/type_traits/is_reference.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22 #include <boost/type_traits/remove_reference.hpp>
23
24 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
25 # include <boost/type_traits/is_base_and_derived.hpp>
26
27 #endif 
28 #include <boost/iterator/detail/config_def.hpp>
29
30
31 namespace boost
32 {
33   template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
34   class transform_iterator;
35
36   namespace detail 
37   {
38
39     template <class UnaryFunc>
40     struct function_object_result
41     {
42       typedef typename UnaryFunc::result_type type;
43     };
44
45 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
46     template <class Return, class Argument>
47     struct function_object_result<Return(*)(Argument)>
48     {
49       typedef Return type;
50     };
51 #endif
52
53     // Compute the iterator_adaptor instantiation to be used for transform_iterator
54     template <class UnaryFunc, class Iterator, class Reference, class Value>
55     struct transform_iterator_base
56     {
57      private:
58         // By default, dereferencing the iterator yields the same as
59         // the function.  Do we need to adjust the way
60         // function_object_result is computed for the standard
61         // proposal (e.g. using Doug's result_of)?
62         typedef typename ia_dflt_help<
63             Reference
64           , function_object_result<UnaryFunc>
65         >::type reference;
66
67         // To get the default for Value: remove any reference on the
68         // result type, but retain any constness to signal
69         // non-writability.  Note that if we adopt Thomas' suggestion
70         // to key non-writability *only* on the Reference argument,
71         // we'd need to strip constness here as well.
72         typedef typename ia_dflt_help<
73             Value
74           , remove_reference<reference>
75         >::type cv_value_type;
76
77      public:
78         typedef iterator_adaptor<
79             transform_iterator<UnaryFunc, Iterator, Reference, Value>
80           , Iterator
81           , cv_value_type
82           , use_default    // Leave the traversal category alone
83           , reference
84         > type;
85     };
86   }
87
88   template <class UnaryFunc, class Iterator, class Reference, class Value>
89   class transform_iterator
90     : public boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
91   {
92     typedef typename
93     boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
94     super_t;
95
96     friend class iterator_core_access;
97
98   public:
99     transform_iterator() { }
100
101     transform_iterator(Iterator const& x, UnaryFunc f)
102       : super_t(x), m_f(f) { }
103
104     explicit transform_iterator(Iterator const& x)
105       : super_t(x)
106     {
107         // Pro8 is a little too aggressive about instantiating the
108         // body of this function.
109 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
110         // don't provide this constructor if UnaryFunc is a
111         // function pointer type, since it will be 0.  Too dangerous.
112         BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
113 #endif 
114     }
115
116     template<
117         class OtherUnaryFunction
118       , class OtherIterator
119       , class OtherReference
120       , class OtherValue>
121     transform_iterator(
122          transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
123        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
124 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
125        , typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
126 #endif 
127     )
128       : super_t(t.base()), m_f(t.functor())
129    {}
130
131     UnaryFunc functor() const
132       { return m_f; }
133
134   private:
135     typename super_t::reference dereference() const
136     { return m_f(*this->base()); }
137
138     // Probably should be the initial base class so it can be
139     // optimized away via EBO if it is an empty class.
140     UnaryFunc m_f;
141   };
142
143   template <class UnaryFunc, class Iterator>
144   transform_iterator<UnaryFunc, Iterator>
145   make_transform_iterator(Iterator it, UnaryFunc fun)
146   {
147       return transform_iterator<UnaryFunc, Iterator>(it, fun);
148   }
149
150   // Version which allows explicit specification of the UnaryFunc
151   // type.
152   //
153   // This generator is not provided if UnaryFunc is a function
154   // pointer type, because it's too dangerous: the default-constructed
155   // function pointer in the iterator be 0, leading to a runtime
156   // crash.
157   template <class UnaryFunc, class Iterator>
158 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
159   typename mpl::if_<
160 #else 
161   typename iterators::enable_if<
162 #endif 
163       is_class<UnaryFunc>   // We should probably find a cheaper test than is_class<>
164     , transform_iterator<UnaryFunc, Iterator>
165 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
166     , int[3]
167 #endif 
168   >::type
169   make_transform_iterator(Iterator it)
170   {
171       return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
172   }
173
174 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
175   template <class Return, class Argument, class Iterator>
176   transform_iterator< Return (*)(Argument), Iterator, Return>
177   make_transform_iterator(Iterator it, Return (*fun)(Argument))
178   {
179     return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
180   }
181 #endif
182
183 } // namespace boost
184
185 #include <boost/iterator/detail/config_undef.hpp>
186
187 #endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP