FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python/include/boost/python/object/iterator.hpp at develop · elmopl/python · GitHub
elmopl
/
python
Public
forked from
boostorg/python
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
python
/
include
/
boost
/
python
/
object
/
iterator.hpp
Copy path
More file actions
More file actions
Latest commit
History
History
History
227 lines (195 loc) · 6.97 KB
Breadcrumbs
python
/
include
/
boost
/
python
/
object
/
iterator.hpp
Copy path
File metadata and controls
227 lines (195 loc) · 6.97 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//
Copyright David Abrahams 2002.
//
Distributed under the Boost Software License, Version 1.0. (See
//
accompanying file LICENSE_1_0.txt or copy at
//
http://www.boost.org/LICENSE_1_0.txt)
#
ifndef
ITERATOR_DWA2002510_HPP
#
define
ITERATOR_DWA2002510_HPP
#
include
<
boost/python/detail/prefix.hpp
>
#
include
<
boost/python/detail/type_traits.hpp
>
#
include
<
boost/python/class.hpp
>
#
include
<
boost/python/return_value_policy.hpp
>
#
include
<
boost/python/return_by_value.hpp
>
#
include
<
boost/python/handle.hpp
>
#
include
<
boost/python/make_function.hpp
>
#
include
<
boost/python/object/iterator_core.hpp
>
#
include
<
boost/python/object/class_detail.hpp
>
#
include
<
boost/python/object/function_object.hpp
>
#
include
<
boost/mpl/vector/vector10.hpp
>
#
include
<
boost/mpl/if.hpp
>
#
include
<
boost/python/detail/raw_pyobject.hpp
>
#
include
<
boost/type.hpp
>
#
include
<
boost/detail/iterator.hpp
>
namespace
boost
{
namespace
python
{
namespace
objects
{
//
CallPolicies for the next() method of iterators. We don't want
//
users to have to explicitly specify that the references returned by
//
iterators are copied, so we just replace the result_converter from
//
the default_iterator_call_policies with a permissive one which
//
always copies the result.
typedef
return_value_policy<return_by_value> default_iterator_call_policies;
//
Instantiations of these are wrapped to produce Python iterators.
template
<
class
NextPolicies
,
class
Iterator
>
struct
iterator_range
{
iterator_range
(object sequence, Iterator start, Iterator finish);
typedef
boost::detail::iterator_traits<Iterator>
traits_t
;
struct
next
{
typedef
typename
mpl::if_<
is_reference<
typename
traits_t
::reference
>
,
typename
traits_t
::reference
,
typename
traits_t
::value_type
>::type result_type;
result_type
operator
()(iterator_range<NextPolicies,Iterator>& self)
{
if
(self.
m_start
== self.
m_finish
)
stop_iteration_error
();
return
*self.
m_start
++;
}
#
if
BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
//
CWPro8 has a codegen problem when this is an empty class
int
garbage;
#
endif
};
typedef
next next_fn;
object m_sequence;
//
Keeps the sequence alive while iterating.
Iterator m_start;
Iterator m_finish;
};
namespace
detail
{
//
Get a Python class which contains the given iterator and
//
policies, creating it if necessary. Requires: NextPolicies is
//
default-constructible.
template
<
class
Iterator
,
class
NextPolicies
>
object
demand_iterator_class
(
char
const
* name, Iterator* =
0
, NextPolicies
const
& policies = NextPolicies())
{
typedef
iterator_range<NextPolicies,Iterator> range_;
//
Check the registry. If one is already registered, return it.
handle<>
class_obj
(
objects::registered_class_object
(python::type_id<range_>()));
if
(class_obj.
get
() !=
0
)
return
object
(class_obj);
typedef
typename
range_::next_fn next_fn;
typedef
typename
next_fn::result_type result_type;
return
class_<range_>(name, no_init)
.
def
(
"
__iter__
"
,
identity_function
())
.
def
(
#
if
PY_VERSION_HEX >= 0x03000000
"
__next__
"
#
else
"
next
"
#
endif
,
make_function
(
next_fn
()
, policies
, mpl::vector2<result_type,range_&>()
));
}
//
A function object which builds an iterator_range.
template
<
class
Target
,
class
Iterator
,
class
Accessor1
,
class
Accessor2
,
class
NextPolicies
>
struct
py_iter_
{
py_iter_
(Accessor1
const
& get_start, Accessor2
const
& get_finish)
: m_get_start(get_start)
, m_get_finish(get_finish)
{}
//
Extract an object x of the Target type from the first Python
//
argument, and invoke get_start(x)/get_finish(x) to produce
//
iterators, which are used to construct a new iterator_range<>
//
object that gets wrapped into a Python iterator.
iterator_range<NextPolicies,Iterator>
operator
()(back_reference<Target&> x)
const
{
//
Make sure the Python class is instantiated.
detail::demand_iterator_class
(
"
iterator
"
, (Iterator*)
0
,
NextPolicies
());
return
iterator_range<NextPolicies,Iterator>(
x.
source
()
,
m_get_start
(x.
get
())
,
m_get_finish
(x.
get
())
);
}
private:
Accessor1 m_get_start;
Accessor2 m_get_finish;
};
template
<
class
Target
,
class
Iterator
,
class
NextPolicies
,
class
Accessor1
,
class
Accessor2
>
inline
object
make_iterator_function
(
Accessor1
const
& get_start
, Accessor2
const
& get_finish
, NextPolicies
const
&
/*
next_policies
*/
, Iterator
const
& (*)()
, boost::type<Target>*
, int
)
{
return
make_function
(
py_iter_<Target,Iterator,Accessor1,Accessor2,NextPolicies>(get_start, get_finish)
,
default_call_policies
()
, mpl::vector2<iterator_range<NextPolicies,Iterator>, back_reference<Target&> >()
);
}
template
<
class
Target
,
class
Iterator
,
class
NextPolicies
,
class
Accessor1
,
class
Accessor2
>
inline
object
make_iterator_function
(
Accessor1
const
& get_start
, Accessor2
const
& get_finish
, NextPolicies
const
& next_policies
, Iterator& (*)()
, boost::type<Target>*
, ...)
{
return
make_iterator_function
(
get_start
, get_finish
, next_policies
, (Iterator
const
&(*)())
0
, (boost::type<Target>*)
0
,
0
);
}
}
//
Create a Python callable object which accepts a single argument
//
convertible to the C++ Target type and returns a Python
//
iterator. The Python iterator uses get_start(x) and get_finish(x)
//
(where x is an instance of Target) to produce begin and end
//
iterators for the range, and an instance of NextPolicies is used as
//
CallPolicies for the Python iterator's next() function.
template
<
class
Target
,
class
NextPolicies
,
class
Accessor1
,
class
Accessor2
>
inline
object
make_iterator_function
(
Accessor1
const
& get_start
, Accessor2
const
& get_finish
, NextPolicies
const
& next_policies
, boost::type<Target>* =
0
)
{
typedef
typename
Accessor1::result_type iterator;
typedef
typename
boost::python::detail::add_const<iterator>::type iterator_const;
typedef
typename
boost::python::detail::add_lvalue_reference<iterator_const>::type iterator_cref;
return
detail::make_iterator_function
(
get_start
, get_finish
, next_policies
, (
iterator_cref
(*)())
0
, (boost::type<Target>*)
0
,
0
);
}
//
//
implementation
//
template
<
class
NextPolicies
,
class
Iterator
>
inline
iterator_range<NextPolicies,Iterator>::iterator_range(
object sequence, Iterator start, Iterator finish)
: m_sequence(sequence), m_start(start), m_finish(finish)
{
}
}}}
//
namespace boost::python::objects
#
endif
//
ITERATOR_DWA2002510_HPP
Back
|
FazBrowse Home
|
New Git URL