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