From dfcce0f2a918d57e6974571e45616cd9fdae0687 Mon Sep 17 00:00:00 2001 From: Raoul Gough Date: Mon, 24 Nov 2003 16:35:19 +0000 Subject: [PATCH] Switch to a non-virtual interface by relying on PyObject_GetIter [SVN r20939] --- .../python/suite/indexing/python_iterator.hpp | 42 ++---- src/indexing/python_iterator.cpp | 120 ++---------------- 2 files changed, 21 insertions(+), 141 deletions(-) diff --git a/include/boost/python/suite/indexing/python_iterator.hpp b/include/boost/python/suite/indexing/python_iterator.hpp index 78df5191..ae37025c 100755 --- a/include/boost/python/suite/indexing/python_iterator.hpp +++ b/include/boost/python/suite/indexing/python_iterator.hpp @@ -21,46 +21,24 @@ #define BOOST_PYTHON_INDEXING_PYTHON_ITERATOR_HPP #include -#include namespace boost { namespace python { namespace indexing { struct BOOST_PYTHON_DECL python_iterator { - virtual ~python_iterator (); - virtual bool next () = 0; - virtual boost::python::object current() const = 0; - }; + python_iterator (boost::python::object); + // Sets a python type exception and calls throw_error_already_set if + // the passed object is not iterable via PyObject_GetIter - BOOST_PYTHON_DECL - std::auto_ptr - make_iterator (boost::python::object); - // Returns null auto_ptr if object does not provide __iter__ nor - // __getitem__, otherwise a pointer to a suitable implementation of - // python_iterator + bool next (); + // Get the next item from the iterator, returning true for success - struct BOOST_PYTHON_DECL python_getitem_iterator : public python_iterator - { - public: - python_getitem_iterator (boost::python::object); - virtual bool next (); - virtual boost::python::object current() const; + boost::python::object current() const; + // Callable only after a successful next() private: - boost::python::object m_getitem_method; - int m_index; - boost::python::object m_current; - }; - - struct BOOST_PYTHON_DECL python_iter_iterator : public python_iterator - { - public: - python_iter_iterator (boost::python::object); - virtual bool next (); - virtual boost::python::object current() const; - - private: - boost::python::object m_next_method; - boost::python::object m_current; + ::boost::python::object m_iter_obj; + ::boost::python::object m_next_method; + ::boost::python::object m_current; }; } } } diff --git a/src/indexing/python_iterator.cpp b/src/indexing/python_iterator.cpp index a2a8fbde..8ef34d16 100755 --- a/src/indexing/python_iterator.cpp +++ b/src/indexing/python_iterator.cpp @@ -16,60 +16,17 @@ // #include -#include +#include //////////////////////////////////////////////////////////////////////////// -// python_iterator factory +// python_iterator constructor /////////////////////////////////////////////////////////////////////////// -std::auto_ptr -boost::python::indexing::make_iterator (boost::python::object temp) -{ - typedef std::auto_ptr ptr_type; - ptr_type result; - - try - { - BOOST_PYTHON_INDEXING_RESET_AUTO_PTR( - result, (python_iterator *) new python_iter_iterator (temp)); - } - - catch (boost::python::error_already_set const &) - { - PyErr_Clear (); - - try - { - BOOST_PYTHON_INDEXING_RESET_AUTO_PTR( - result, (python_iterator *) new python_getitem_iterator (temp)); - } - - catch (boost::python::error_already_set const &) - { - PyErr_Clear (); - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////// -// Base class (virtual) destructor -/////////////////////////////////////////////////////////////////////////// - -boost::python::indexing::python_iterator::~python_iterator () -{ -} - -//////////////////////////////////////////////////////////////////////////// -// python_getitem_iterator constructor -/////////////////////////////////////////////////////////////////////////// - -boost::python::indexing::python_getitem_iterator -::python_getitem_iterator (boost::python::object obj) - : m_getitem_method (obj.attr ("__getitem__")), - m_index (0), - m_current() +boost::python::indexing::python_iterator +::python_iterator (boost::python::object obj) + : m_iter_obj (handle<> (PyObject_GetIter (obj.ptr()))), + m_next_method (m_iter_obj.attr ("next")), + m_current() { } @@ -77,62 +34,7 @@ boost::python::indexing::python_getitem_iterator // Get our next item (if any) /////////////////////////////////////////////////////////////////////////// -bool boost::python::indexing::python_getitem_iterator::next () -{ - bool result = true; // Assume success - - try - { - m_current = m_getitem_method (m_index); - ++m_index; - } - - catch (boost::python::error_already_set const &) - { - if (PyErr_ExceptionMatches (PyExc_IndexError)) - { - // Eat this exception - PyErr_Clear (); - m_current = boost::python::object (); - result = false; - } - - else - { - // Pass it up the line - throw; - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////// -// Return our current item -/////////////////////////////////////////////////////////////////////////// - -boost::python::object -boost::python::indexing::python_getitem_iterator::current () const -{ - return m_current; -} - -//////////////////////////////////////////////////////////////////////////// -// python_iter_iterator constructor -/////////////////////////////////////////////////////////////////////////// - -boost::python::indexing::python_iter_iterator -::python_iter_iterator (boost::python::object obj) - : m_next_method (obj.attr ("__iter__")().attr ("next")), - m_current() -{ -} - -//////////////////////////////////////////////////////////////////////////// -// Get our next item (if any) -/////////////////////////////////////////////////////////////////////////// - -bool boost::python::indexing::python_iter_iterator::next () +bool boost::python::indexing::python_iterator::next () { bool result = true; // Assume success @@ -147,8 +49,8 @@ bool boost::python::indexing::python_iter_iterator::next () { // Eat this exception PyErr_Clear (); - m_current = boost::python::object (); - result = false; + m_current = boost::python::object (); // No current object + result = false; // Report failure via return value only } else @@ -166,7 +68,7 @@ bool boost::python::indexing::python_iter_iterator::next () /////////////////////////////////////////////////////////////////////////// boost::python::object -boost::python::indexing::python_iter_iterator::current () const +boost::python::indexing::python_iterator::current () const { return m_current; }