// -*- 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