Skip to content

Commit 3ff935d

Browse files
committed
initial commit
[SVN r13844]
1 parent 9fa89e8 commit 3ff935d

3 files changed

Lines changed: 220 additions & 0 deletions

File tree

src/object/iterator.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright David Abrahams 2002. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
7+
#include <boost/python/object/iterator_core.hpp>
8+
#include <boost/python/object/function.hpp>
9+
#include <boost/python/reference.hpp>
10+
#include <boost/bind.hpp>
11+
12+
namespace boost { namespace python { namespace objects {
13+
14+
static PyObject* identity(PyObject* args_, PyObject*)
15+
{
16+
PyObject* x = PyTuple_GET_ITEM(args_,0);
17+
Py_INCREF(x);
18+
return x;
19+
}
20+
21+
BOOST_PYTHON_DECL ref identity_function()
22+
{
23+
static ref result(new objects::function(py_function(&identity), 1));
24+
return result;
25+
}
26+
27+
void set_stop_iteration_error()
28+
{
29+
PyErr_SetObject(PyExc_StopIteration, Py_None);
30+
}
31+
32+
}}} // namespace boost::python::objects

test/iterator.cpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright David Abrahams 2002. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
#include <boost/python/module.hpp>
7+
#include <boost/python/class.hpp>
8+
#include <boost/python/return_internal_reference.hpp>
9+
#include <boost/python/copy_non_const_reference.hpp>
10+
#include <boost/python/return_value_policy.hpp>
11+
#include <boost/python/iterator.hpp>
12+
#include <list>
13+
#include <utility>
14+
#include <iterator>
15+
#include <algorithm>
16+
17+
18+
using namespace boost::python;
19+
20+
typedef std::list<int> list_int;
21+
typedef std::list<list_int> list_list;
22+
23+
void push_back(list_int& x, int y)
24+
{
25+
x.push_back(y);
26+
}
27+
28+
void push_list_back(list_list& x, list_int const& y)
29+
{
30+
x.push_back(y);
31+
}
32+
33+
int back(list_int& x)
34+
{
35+
return x.back();
36+
}
37+
38+
typedef std::pair<list_int::iterator,list_int::iterator> list_range;
39+
40+
list_range range(list_int& x)
41+
{
42+
return list_range(x.begin(), x.end());
43+
}
44+
45+
struct two_lists
46+
{
47+
two_lists()
48+
{
49+
int primes[] = { 2, 3, 5, 7, 11, 13 };
50+
std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one));
51+
int evens[] = { 2, 4, 6, 8, 10, 12 };
52+
std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two));
53+
}
54+
55+
struct two_start
56+
{
57+
typedef list_int::iterator result_type;
58+
result_type operator()(two_lists& ll) const { return ll.two.begin(); }
59+
};
60+
friend struct two_start;
61+
62+
list_int::iterator one_begin() { return one.begin(); }
63+
list_int::iterator two_begin() { return two.begin(); }
64+
65+
list_int::iterator one_end() { return one.end(); }
66+
list_int::iterator two_end() { return two.end(); }
67+
68+
private:
69+
list_int one;
70+
list_int two;
71+
};
72+
73+
BOOST_PYTHON_MODULE_INIT(iterator_ext)
74+
{
75+
module("iterator_ext")
76+
.def("range", &::range)
77+
.add(
78+
class_<list_int>("list_int")
79+
.def_init()
80+
.def("push_back", push_back)
81+
.def("back", back)
82+
.def("__iter__", iterator<list_int>())
83+
)
84+
.add(
85+
class_<list_range>("list_range")
86+
87+
// We can specify data members
88+
.def("__iter__"
89+
, range(&list_range::first, &list_range::second))
90+
)
91+
.add(
92+
class_<two_lists>("two_lists")
93+
.def_init()
94+
95+
// We can spcify member functions
96+
.add_property(
97+
"primes"
98+
, range(&two_lists::one_begin, &two_lists::one_end))
99+
100+
// Prove that we can explicitly specify call policies
101+
.add_property(
102+
"evens"
103+
, range<return_value_policy<copy_non_const_reference> >(
104+
&two_lists::two_begin, &two_lists::two_end))
105+
106+
// Prove that we can specify call policies and target
107+
.add_property(
108+
"twosies"
109+
, range<return_value_policy<copy_non_const_reference>, two_lists>(
110+
// And we can use adaptable function objects when
111+
// partial specialization is available.
112+
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
113+
two_lists::two_start()
114+
# else
115+
&two_lists::two_begin
116+
# endif
117+
, &two_lists::two_end))
118+
)
119+
.add(
120+
class_<list_list>("list_list")
121+
.def_init()
122+
.def("push_back", push_list_back)
123+
.def("__iter__", iterator<list_list,return_internal_reference<> >())
124+
)
125+
;
126+
}
127+
128+
#include "module_tail.cpp"

test/iterator.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'''
2+
>>> from iterator_ext import *
3+
>>> x = list_int()
4+
>>> x.push_back(1)
5+
>>> x.back()
6+
1
7+
>>> x.push_back(3)
8+
>>> x.push_back(5)
9+
>>> for y in x:
10+
... print y
11+
1
12+
3
13+
5
14+
>>> z = range(x)
15+
>>> for y in z:
16+
... print y
17+
1
18+
3
19+
5
20+
>>> l2 = two_lists()
21+
>>> for y in l2.primes:
22+
... print y
23+
2
24+
3
25+
5
26+
7
27+
11
28+
13
29+
>>> for y in l2.evens:
30+
... print y
31+
2
32+
4
33+
6
34+
8
35+
10
36+
12
37+
>>> ll = list_list()
38+
>>> ll.push_back(x)
39+
>>> x.push_back(7)
40+
>>> ll.push_back(x)
41+
>>> for a in ll:
42+
... for b in a:
43+
... print b,
44+
... print
45+
...
46+
1 3 5
47+
1 3 5 7
48+
'''
49+
def run(args = None):
50+
import sys
51+
import doctest
52+
53+
if args is not None:
54+
sys.argv = args
55+
return doctest.testmod(sys.modules.get(__name__))
56+
57+
if __name__ == '__main__':
58+
print "running..."
59+
import sys
60+
sys.exit(run()[0])

0 commit comments

Comments
 (0)