Chris@16
|
1 // Copyright David Abrahams 2002.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 #ifndef ITERATOR_DWA2002512_HPP
|
Chris@16
|
6 # define ITERATOR_DWA2002512_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/python/detail/prefix.hpp>
|
Chris@16
|
9
|
Chris@16
|
10 # include <boost/python/detail/target.hpp>
|
Chris@16
|
11 # include <boost/python/object/iterator.hpp>
|
Chris@16
|
12 # include <boost/python/object_core.hpp>
|
Chris@16
|
13
|
Chris@16
|
14 # include <boost/type_traits/cv_traits.hpp>
|
Chris@16
|
15 # include <boost/type_traits/transform_traits.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 # if defined(BOOST_MSVC) && (BOOST_MSVC == 1400) /*
|
Chris@16
|
18 > warning C4180: qualifier applied to function type has no meaning; ignored
|
Chris@16
|
19 Peter Dimov wrote:
|
Chris@16
|
20 This warning is caused by an overload resolution bug in VC8 that cannot be
|
Chris@16
|
21 worked around and will probably not be fixed by MS in the VC8 line. The
|
Chris@16
|
22 problematic overload is only instantiated and never called, and the code
|
Chris@16
|
23 works correctly. */
|
Chris@16
|
24 # pragma warning(disable: 4180)
|
Chris@16
|
25 # endif
|
Chris@16
|
26
|
Chris@16
|
27 # include <boost/bind.hpp>
|
Chris@16
|
28 # include <boost/bind/protect.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 namespace boost { namespace python {
|
Chris@16
|
31
|
Chris@16
|
32 namespace detail
|
Chris@16
|
33 {
|
Chris@16
|
34 // Adds an additional layer of binding to
|
Chris@16
|
35 // objects::make_iterator(...), which allows us to pass member
|
Chris@16
|
36 // function and member data pointers.
|
Chris@16
|
37 template <class Target, class Accessor1, class Accessor2, class NextPolicies>
|
Chris@16
|
38 inline object make_iterator(
|
Chris@16
|
39 Accessor1 get_start
|
Chris@16
|
40 , Accessor2 get_finish
|
Chris@16
|
41 , NextPolicies next_policies
|
Chris@16
|
42 , Target&(*)()
|
Chris@16
|
43 )
|
Chris@16
|
44 {
|
Chris@16
|
45 return objects::make_iterator_function<Target>(
|
Chris@16
|
46 boost::protect(boost::bind(get_start, _1))
|
Chris@16
|
47 , boost::protect(boost::bind(get_finish, _1))
|
Chris@16
|
48 , next_policies
|
Chris@16
|
49 );
|
Chris@16
|
50 }
|
Chris@16
|
51
|
Chris@16
|
52 // Guts of template class iterators<>, below.
|
Chris@16
|
53 template <bool const_ = false>
|
Chris@16
|
54 struct iterators_impl
|
Chris@16
|
55 {
|
Chris@16
|
56 template <class T>
|
Chris@16
|
57 struct apply
|
Chris@16
|
58 {
|
Chris@16
|
59 typedef typename T::iterator iterator;
|
Chris@16
|
60 static iterator begin(T& x) { return x.begin(); }
|
Chris@16
|
61 static iterator end(T& x) { return x.end(); }
|
Chris@16
|
62 };
|
Chris@16
|
63 };
|
Chris@16
|
64
|
Chris@16
|
65 template <>
|
Chris@16
|
66 struct iterators_impl<true>
|
Chris@16
|
67 {
|
Chris@16
|
68 template <class T>
|
Chris@16
|
69 struct apply
|
Chris@16
|
70 {
|
Chris@16
|
71 typedef typename T::const_iterator iterator;
|
Chris@16
|
72 static iterator begin(T& x) { return x.begin(); }
|
Chris@16
|
73 static iterator end(T& x) { return x.end(); }
|
Chris@16
|
74 };
|
Chris@16
|
75 };
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 // An "ordinary function generator" which contains static begin(x) and
|
Chris@16
|
79 // end(x) functions that invoke T::begin() and T::end(), respectively.
|
Chris@16
|
80 template <class T>
|
Chris@16
|
81 struct iterators
|
Chris@16
|
82 : detail::iterators_impl<
|
Chris@16
|
83 boost::is_const<T>::value
|
Chris@16
|
84 >::template apply<T>
|
Chris@16
|
85 {
|
Chris@16
|
86 };
|
Chris@16
|
87
|
Chris@16
|
88 // Create an iterator-building function which uses the given
|
Chris@16
|
89 // accessors. Deduce the Target type from the accessors. The iterator
|
Chris@16
|
90 // returns copies of the inderlying elements.
|
Chris@16
|
91 template <class Accessor1, class Accessor2>
|
Chris@16
|
92 object range(Accessor1 start, Accessor2 finish)
|
Chris@16
|
93 {
|
Chris@16
|
94 return detail::make_iterator(
|
Chris@16
|
95 start, finish
|
Chris@16
|
96 , objects::default_iterator_call_policies()
|
Chris@16
|
97 , detail::target(start)
|
Chris@16
|
98 );
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 // Create an iterator-building function which uses the given accessors
|
Chris@16
|
102 // and next() policies. Deduce the Target type.
|
Chris@16
|
103 template <class NextPolicies, class Accessor1, class Accessor2>
|
Chris@16
|
104 object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
|
Chris@16
|
105 {
|
Chris@16
|
106 return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 // Create an iterator-building function which uses the given accessors
|
Chris@16
|
110 // and next() policies, operating on the given Target type
|
Chris@16
|
111 template <class NextPolicies, class Target, class Accessor1, class Accessor2>
|
Chris@16
|
112 object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
|
Chris@16
|
113 {
|
Chris@16
|
114 // typedef typename add_reference<Target>::type target;
|
Chris@16
|
115 return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 // A Python callable object which produces an iterator traversing
|
Chris@16
|
119 // [x.begin(), x.end()), where x is an instance of the Container
|
Chris@16
|
120 // type. NextPolicies are used as the CallPolicies for the iterator's
|
Chris@16
|
121 // next() function.
|
Chris@16
|
122 template <class Container
|
Chris@16
|
123 , class NextPolicies = objects::default_iterator_call_policies>
|
Chris@16
|
124 struct iterator : object
|
Chris@16
|
125 {
|
Chris@16
|
126 iterator()
|
Chris@16
|
127 : object(
|
Chris@16
|
128 python::range<NextPolicies>(
|
Chris@16
|
129 &iterators<Container>::begin, &iterators<Container>::end
|
Chris@16
|
130 ))
|
Chris@16
|
131 {
|
Chris@16
|
132 }
|
Chris@16
|
133 };
|
Chris@16
|
134
|
Chris@16
|
135 }} // namespace boost::python
|
Chris@16
|
136
|
Chris@16
|
137 #endif // ITERATOR_DWA2002512_HPP
|