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
|
// 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)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/copy_non_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/iterator.hpp>
#include <list>
#include <utility>
#include <iterator>
#include <algorithm>
using namespace boost::python;
typedef std::list<int> list_int;
typedef std::list<list_int> list_list;
void push_back(list_int& x, int y)
{
x.push_back(y);
}
void push_list_back(list_list& x, list_int const& y)
{
x.push_back(y);
}
int back(list_int& x)
{
return x.back();
}
typedef std::pair<list_int::iterator,list_int::iterator> list_range;
struct list_range2 : list_range
{
list_int::iterator& begin() { return this->first; }
list_int::iterator& end() { return this->second; }
};
list_range range(list_int& x)
{
return list_range(x.begin(), x.end());
}
struct two_lists
{
two_lists()
{
int primes[] = { 2, 3, 5, 7, 11, 13 };
std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one));
int evens[] = { 2, 4, 6, 8, 10, 12 };
std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two));
}
struct two_start
{
typedef list_int::iterator result_type;
result_type operator()(two_lists& ll) const { return ll.two.begin(); }
};
friend struct two_start;
list_int::iterator one_begin() { return one.begin(); }
list_int::iterator two_begin() { return two.begin(); }
list_int::iterator one_end() { return one.end(); }
list_int::iterator two_end() { return two.end(); }
private:
list_int one;
list_int two;
};
BOOST_PYTHON_MODULE(iterator_ext)
{
using boost::python::iterator; // gcc 2.96 bug workaround
def("range", &::range);
class_<list_int>("list_int")
.def("push_back", push_back)
.def("back", back)
.def("__iter__", iterator<list_int>())
;
class_<list_range>("list_range")
// We can specify data members
.def("__iter__"
, range(&list_range::first, &list_range::second))
;
// No runtime tests for this one yet
class_<list_range2>("list_range2")
// We can specify member functions returning a non-const reference
.def("__iter__", range(&list_range2::begin, &list_range2::end))
;
class_<two_lists>("two_lists")
// We can spcify member functions
.add_property(
"primes"
, range(&two_lists::one_begin, &two_lists::one_end))
// Prove that we can explicitly specify call policies
.add_property(
"evens"
, range<return_value_policy<copy_non_const_reference> >(
&two_lists::two_begin, &two_lists::two_end))
// Prove that we can specify call policies and target
.add_property(
"twosies"
, range<return_value_policy<copy_non_const_reference>, two_lists>(
// And we can use adaptable function objects when
// partial specialization is available.
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
two_lists::two_start()
# else
&two_lists::two_begin
# endif
, &two_lists::two_end))
;
class_<list_list>("list_list")
.def("push_back", push_list_back)
.def("__iter__", iterator<list_list,return_internal_reference<> >())
;
}
#include "module_tail.cpp"
|