mirror of
https://github.com/boostorg/python.git
synced 2026-02-01 20:52:13 +00:00
C++ interface to iterable Python objects
[SVN r1524]
This commit is contained in:
172
include/boost/python/suite/indexing/python_iterator.cpp
Executable file
172
include/boost/python/suite/indexing/python_iterator.cpp
Executable file
@@ -0,0 +1,172 @@
|
||||
// -*- mode:c++ -*-
|
||||
//
|
||||
// Module python_iterator.cpp
|
||||
//
|
||||
// Copyright (c) 2003 Raoul M. Gough
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this material for any purpose is hereby
|
||||
// granted without fee, provided the above notices are retained on all
|
||||
// copies. Permission to modify the material and to distribute modified
|
||||
// versions is granted, provided the above notices are retained, and a
|
||||
// notice that the material was modified is included with the above
|
||||
// copyright notice.
|
||||
//
|
||||
// History
|
||||
// =======
|
||||
// 2003/ 9/10 rmg File creation
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
#include "python_iterator.hpp"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// python_iterator factory
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::auto_ptr<indexing::python_iterator>
|
||||
indexing::make_iterator (boost::python::object temp)
|
||||
{
|
||||
std::auto_ptr<python_iterator> result;
|
||||
|
||||
try
|
||||
{
|
||||
result.reset (new python_iter_iterator (temp));
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
{
|
||||
PyErr_Clear ();
|
||||
|
||||
try
|
||||
{
|
||||
result.reset (new python_getitem_iterator (temp));
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
{
|
||||
PyErr_Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Base class (virtual) destructor
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
indexing::python_iterator::~python_iterator ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// python_getitem_iterator constructor
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
indexing::python_getitem_iterator
|
||||
::python_getitem_iterator (boost::python::object obj)
|
||||
: mGetitemMethod (obj.attr ("__getitem__"))
|
||||
, mIndex (0)
|
||||
, mCurrent()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Get our next item (if any)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool indexing::python_getitem_iterator::next ()
|
||||
{
|
||||
bool result = true; // Assume success
|
||||
|
||||
try
|
||||
{
|
||||
mCurrent = mGetitemMethod (mIndex);
|
||||
++mIndex;
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
{
|
||||
if (PyErr_ExceptionMatches (PyExc_IndexError))
|
||||
{
|
||||
// Eat this exception
|
||||
PyErr_Clear ();
|
||||
mCurrent = boost::python::object ();
|
||||
result = false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Pass it up the line
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Return our current item
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::python::object indexing::python_getitem_iterator::current () const
|
||||
{
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// python_iter_iterator constructor
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
indexing::python_iter_iterator
|
||||
::python_iter_iterator (boost::python::object obj)
|
||||
: mNextMethod (obj.attr ("__iter__")().attr ("next"))
|
||||
, mCurrent()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Get our next item (if any)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool indexing::python_iter_iterator::next ()
|
||||
{
|
||||
bool result = true; // Assume success
|
||||
|
||||
try
|
||||
{
|
||||
mCurrent = mNextMethod ();
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
{
|
||||
if (PyErr_ExceptionMatches (PyExc_StopIteration))
|
||||
{
|
||||
// Eat this exception
|
||||
PyErr_Clear ();
|
||||
mCurrent = boost::python::object ();
|
||||
result = false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Pass it up the line
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Return our current item
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::python::object indexing::python_iter_iterator::current () const
|
||||
{
|
||||
return mCurrent;
|
||||
}
|
||||
71
include/boost/python/suite/indexing/python_iterator.hpp
Executable file
71
include/boost/python/suite/indexing/python_iterator.hpp
Executable file
@@ -0,0 +1,71 @@
|
||||
// -*- mode:c++ -*-
|
||||
//
|
||||
// Header file python_iterator.hpp
|
||||
//
|
||||
// Handy Python iterable iterators
|
||||
//
|
||||
// Copyright (c) 2003 Raoul M. Gough
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this material for any purpose is hereby
|
||||
// granted without fee, provided the above notices are retained on all
|
||||
// copies. Permission to modify the material and to distribute modified
|
||||
// versions is granted, provided the above notices are retained, and a
|
||||
// notice that the material was modified is included with the above
|
||||
// copyright notice.
|
||||
//
|
||||
// History
|
||||
// =======
|
||||
// 2003/ 9/10 rmg File creation
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
#ifndef python_iterator_rmg_20030910_included
|
||||
#define python_iterator_rmg_20030910_included
|
||||
|
||||
#include <boost/python/object.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace indexing {
|
||||
struct python_iterator
|
||||
{
|
||||
virtual ~python_iterator ();
|
||||
virtual bool next () = 0;
|
||||
virtual boost::python::object current() const = 0;
|
||||
};
|
||||
|
||||
std::auto_ptr<python_iterator> 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
|
||||
|
||||
struct python_getitem_iterator : public python_iterator
|
||||
{
|
||||
public:
|
||||
python_getitem_iterator (boost::python::object);
|
||||
virtual bool next ();
|
||||
virtual boost::python::object current() const;
|
||||
|
||||
private:
|
||||
boost::python::object mGetitemMethod;
|
||||
int mIndex;
|
||||
boost::python::object mCurrent;
|
||||
};
|
||||
|
||||
struct 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 mNextMethod;
|
||||
boost::python::object mCurrent;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // python_iterator_rmg_20030910_included
|
||||
Reference in New Issue
Block a user