// -*- mode:c++ -*- // // Header file python_iterator.hpp // // Handy Python iterable iterators // // Copyright (c) 2003 Raoul M. Gough // // Use, modification and distribution is subject to 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) // // History // ======= // 2003/ 9/10 rmg File creation // 2008/12/08 Roman Change indexing suite layout // // $Id: python_iterator.hpp,v 1.1.2.5 2003/11/24 16:35:09 raoulgough Exp $ // // 2008 November 27 Roman Yakovenko // implementation of the member functions was moved from cpp to header. // this was done to simplify "installation" procedure. #ifndef BOOST_PYTHON_INDEXING_PYTHON_ITERATOR_HPP #define BOOST_PYTHON_INDEXING_PYTHON_ITERATOR_HPP #include <boost/python/object.hpp> #include <boost/python/handle.hpp> namespace boost { namespace python { namespace indexing { struct /*BOOST_PYTHON_DECL*/ 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() { } // Sets a python type exception and calls throw_error_already_set if // the passed object is not iterable via PyObject_GetIter bool next () { bool result = true; // Assume success try { m_current = m_next_method (); } catch (boost::python::error_already_set const &) { if (PyErr_ExceptionMatches (PyExc_StopIteration)) { // Eat this exception PyErr_Clear (); m_current = boost::python::object (); // No current object result = false; // Report failure via return value only } else { // Pass it up the line throw; } } return result; } // Get the next item from the iterator, returning true for success boost::python::object current() const { return m_current; } // Callable only after a successful next() private: ::boost::python::object m_iter_obj; ::boost::python::object m_next_method; ::boost::python::object m_current; }; } } } #endif // BOOST_PYTHON_INDEXING_PYTHON_ITERATOR_HPP