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