]>
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 | #include <boost/python/module.hpp> | |
6 | #include <boost/python/def.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 | using namespace boost::python; | |
18 | ||
19 | typedef std::list<int> list_int; | |
20 | typedef std::list<list_int> list_list; | |
21 | ||
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 | struct list_range2 : list_range | |
41 | { | |
42 | list_int::iterator& begin() { return this->first; } | |
43 | list_int::iterator& end() { return this->second; } | |
44 | }; | |
45 | ||
46 | list_range range(list_int& x) | |
47 | { | |
48 | return list_range(x.begin(), x.end()); | |
49 | } | |
50 | ||
51 | struct two_lists | |
52 | { | |
53 | two_lists() | |
54 | { | |
55 | int primes[] = { 2, 3, 5, 7, 11, 13 }; | |
56 | std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one)); | |
57 | int evens[] = { 2, 4, 6, 8, 10, 12 }; | |
58 | std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two)); | |
59 | } | |
60 | ||
61 | struct two_start | |
62 | { | |
63 | typedef list_int::iterator result_type; | |
64 | result_type operator()(two_lists& ll) const { return ll.two.begin(); } | |
65 | }; | |
66 | friend struct two_start; | |
67 | ||
68 | list_int::iterator one_begin() { return one.begin(); } | |
69 | list_int::iterator two_begin() { return two.begin(); } | |
70 | ||
71 | list_int::iterator one_end() { return one.end(); } | |
72 | list_int::iterator two_end() { return two.end(); } | |
73 | ||
74 | private: | |
75 | list_int one; | |
76 | list_int two; | |
77 | }; | |
78 | ||
79 | BOOST_PYTHON_MODULE(iterator_ext) | |
80 | { | |
81 | using boost::python::iterator; // gcc 2.96 bug workaround | |
82 | def("range", &::range); | |
83 | ||
84 | class_<list_int>("list_int") | |
85 | .def("push_back", push_back) | |
86 | .def("back", back) | |
87 | .def("__iter__", iterator<list_int>()) | |
88 | ; | |
89 | ||
90 | class_<list_range>("list_range") | |
91 | ||
92 | // We can specify data members | |
93 | .def("__iter__" | |
94 | , range(&list_range::first, &list_range::second)) | |
95 | ; | |
96 | ||
97 | // No runtime tests for this one yet | |
98 | class_<list_range2>("list_range2") | |
99 | ||
100 | // We can specify member functions returning a non-const reference | |
101 | .def("__iter__", range(&list_range2::begin, &list_range2::end)) | |
102 | ; | |
103 | ||
104 | class_<two_lists>("two_lists") | |
105 | ||
106 | // We can spcify member functions | |
107 | .add_property( | |
108 | "primes" | |
109 | , range(&two_lists::one_begin, &two_lists::one_end)) | |
110 | ||
111 | // Prove that we can explicitly specify call policies | |
112 | .add_property( | |
113 | "evens" | |
114 | , range<return_value_policy<copy_non_const_reference> >( | |
115 | &two_lists::two_begin, &two_lists::two_end)) | |
116 | ||
117 | // Prove that we can specify call policies and target | |
118 | .add_property( | |
119 | "twosies" | |
120 | , range<return_value_policy<copy_non_const_reference>, two_lists>( | |
121 | // And we can use adaptable function objects when | |
122 | // partial specialization is available. | |
123 | # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
124 | two_lists::two_start() | |
125 | # else | |
126 | &two_lists::two_begin | |
127 | # endif | |
128 | , &two_lists::two_end)) | |
129 | ; | |
130 | ||
131 | class_<list_list>("list_list") | |
132 | .def("push_back", push_list_back) | |
133 | .def("__iter__", iterator<list_list,return_internal_reference<> >()) | |
134 | ; | |
135 | } | |
136 | ||
137 | #include "module_tail.cpp" |