diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 3207d1d4..35073438 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -96,6 +96,15 @@ namespace detail typename mpl::apply1::type cr; if (!cr.convertible()) return 0; + return cr(x); + } + template + static PyObject* convert_result(ValueType const& x) + { + typedef typename Policies::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + return cr(x); } }; diff --git a/test/Jamfile b/test/Jamfile index 96574a2f..bb0b6d82 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -65,7 +65,7 @@ bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; bpl-test multi_arg_constructor ; -bpl-test iterator ; +bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; if $(TEST_BIENSTMAN_NON_BUGS) { diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp new file mode 100644 index 00000000..005d393d --- /dev/null +++ b/test/input_iterator.cpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost::python; + +typedef std::list list_int; + +// Prove that we can handle InputIterators which return rvalues. This +// input iterator example was stolen from the iterator_adaptors +// documentation +typedef std::binder1st > doubler; +typedef boost::transform_iterator_generator::type doubling_iterator; +typedef std::pair list_range2; +list_range2 range2(list_int& x) +{ + return list_range2( + boost::make_transform_iterator(x.begin(), std::bind1st(std::multiplies(),2)) + , boost::make_transform_iterator(x.end(), std::bind1st(std::multiplies(),2))); +} + +// We do this in a separate module from iterators_ext (iterators.cpp) +// to work around an MSVC6 linker bug, which causes it to complain +// about a "duplicate comdat" if the input iterator is instantiated in +// the same module with the others. +BOOST_PYTHON_MODULE_INIT(input_iterator) +{ + module("input_iterator") + .def("range2", &::range2) + .add( + class_("list_range2") + + // We can wrap InputIterators which return by-value + .def("__iter__" + , range(&list_range2::first, &list_range2::second)) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/iterator.cpp b/test/iterator.cpp index 1ea2196b..aeb35648 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -14,12 +14,12 @@ #include #include - using namespace boost::python; typedef std::list list_int; typedef std::list list_list; + void push_back(list_int& x, int y) { x.push_back(y); diff --git a/test/iterator.py b/test/iterator.py index 4e6366ad..2f2f8e02 100644 --- a/test/iterator.py +++ b/test/iterator.py @@ -1,5 +1,6 @@ ''' >>> from iterator_ext import * +>>> from input_iterator import * >>> x = list_int() >>> x.push_back(1) >>> x.back() @@ -17,6 +18,17 @@ 1 3 5 + + Range2 wraps a transform_iterator which doubles the elements it + traverses. This proves we can wrap input iterators + +>>> z2 = range2(x) +>>> for y in z2: +... print y +2 +6 +10 + >>> l2 = two_lists() >>> for y in l2.primes: ... print y