| Index: swig/Lib/python/pyiterators.swg
|
| ===================================================================
|
| --- swig/Lib/python/pyiterators.swg (revision 0)
|
| +++ swig/Lib/python/pyiterators.swg (revision 0)
|
| @@ -0,0 +1,393 @@
|
| +/* -----------------------------------------------------------------------------
|
| + * See the LICENSE file for information on copyright, usage and redistribution
|
| + * of SWIG, and the README file for authors - http://www.swig.org/release.html.
|
| + *
|
| + * pyiterators.swg
|
| + *
|
| + * Implement a python 'output' iterator for Python 2.2 or higher.
|
| + *
|
| + * Users can derive form the SwigPyIterator to implement their
|
| + * own iterators. As an example (real one since we use it for STL/STD
|
| + * containers), the template SwigPyIterator_T does the
|
| + * implementation for generic C++ iterators.
|
| + * ----------------------------------------------------------------------------- */
|
| +
|
| +%include <std_common.i>
|
| +
|
| +%fragment("SwigPyIterator","header") {
|
| +namespace swig {
|
| + struct stop_iteration {
|
| + };
|
| +
|
| + struct SwigPyIterator {
|
| + private:
|
| + SwigPtr_PyObject _seq;
|
| +
|
| + protected:
|
| + SwigPyIterator(PyObject *seq) : _seq(seq)
|
| + {
|
| + }
|
| +
|
| + public:
|
| + virtual ~SwigPyIterator() {}
|
| +
|
| + // Access iterator method, required by Python
|
| + virtual PyObject *value() const = 0;
|
| +
|
| + // Forward iterator method, required by Python
|
| + virtual SwigPyIterator *incr(size_t n = 1) = 0;
|
| +
|
| + // Backward iterator method, very common in C++, but not required in Python
|
| + virtual SwigPyIterator *decr(size_t /*n*/ = 1)
|
| + {
|
| + throw stop_iteration();
|
| + }
|
| +
|
| + // Random access iterator methods, but not required in Python
|
| + virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const
|
| + {
|
| + throw std::invalid_argument("operation not supported");
|
| + }
|
| +
|
| + virtual bool equal (const SwigPyIterator &/*x*/) const
|
| + {
|
| + throw std::invalid_argument("operation not supported");
|
| + }
|
| +
|
| + // C++ common/needed methods
|
| + virtual SwigPyIterator *copy() const = 0;
|
| +
|
| + PyObject *next()
|
| + {
|
| + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads
|
| + PyObject *obj = value();
|
| + incr();
|
| + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
|
| + return obj;
|
| + }
|
| +
|
| + /* Make an alias for Python 3.x */
|
| + PyObject *__next__()
|
| + {
|
| + return next();
|
| + }
|
| +
|
| + PyObject *previous()
|
| + {
|
| + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads
|
| + decr();
|
| + PyObject *obj = value();
|
| + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
|
| + return obj;
|
| + }
|
| +
|
| + SwigPyIterator *advance(ptrdiff_t n)
|
| + {
|
| + return (n > 0) ? incr(n) : decr(-n);
|
| + }
|
| +
|
| + bool operator == (const SwigPyIterator& x) const
|
| + {
|
| + return equal(x);
|
| + }
|
| +
|
| + bool operator != (const SwigPyIterator& x) const
|
| + {
|
| + return ! operator==(x);
|
| + }
|
| +
|
| + SwigPyIterator& operator += (ptrdiff_t n)
|
| + {
|
| + return *advance(n);
|
| + }
|
| +
|
| + SwigPyIterator& operator -= (ptrdiff_t n)
|
| + {
|
| + return *advance(-n);
|
| + }
|
| +
|
| + SwigPyIterator* operator + (ptrdiff_t n) const
|
| + {
|
| + return copy()->advance(n);
|
| + }
|
| +
|
| + SwigPyIterator* operator - (ptrdiff_t n) const
|
| + {
|
| + return copy()->advance(-n);
|
| + }
|
| +
|
| + ptrdiff_t operator - (const SwigPyIterator& x) const
|
| + {
|
| + return x.distance(*this);
|
| + }
|
| +
|
| + static swig_type_info* descriptor() {
|
| + static int init = 0;
|
| + static swig_type_info* desc = 0;
|
| + if (!init) {
|
| + desc = SWIG_TypeQuery("swig::SwigPyIterator *");
|
| + init = 1;
|
| + }
|
| + return desc;
|
| + }
|
| + };
|
| +}
|
| +}
|
| +
|
| +%fragment("SwigPyIterator_T","header",fragment="SwigPyIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
|
| +namespace swig {
|
| + template<typename OutIterator>
|
| + class SwigPyIterator_T : public SwigPyIterator
|
| + {
|
| + public:
|
| + typedef OutIterator out_iterator;
|
| + typedef typename std::iterator_traits<out_iterator>::value_type value_type;
|
| + typedef SwigPyIterator_T<out_iterator> self_type;
|
| +
|
| + SwigPyIterator_T(out_iterator curr, PyObject *seq)
|
| + : SwigPyIterator(seq), current(curr)
|
| + {
|
| + }
|
| +
|
| + const out_iterator& get_current() const
|
| + {
|
| + return current;
|
| + }
|
| +
|
| +
|
| + bool equal (const SwigPyIterator &iter) const
|
| + {
|
| + const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
| + if (iters) {
|
| + return (current == iters->get_current());
|
| + } else {
|
| + throw std::invalid_argument("bad iterator type");
|
| + }
|
| + }
|
| +
|
| + ptrdiff_t distance(const SwigPyIterator &iter) const
|
| + {
|
| + const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
| + if (iters) {
|
| + return std::distance(current, iters->get_current());
|
| + } else {
|
| + throw std::invalid_argument("bad iterator type");
|
| + }
|
| + }
|
| +
|
| + protected:
|
| + out_iterator current;
|
| + };
|
| +
|
| + template <class ValueType>
|
| + struct from_oper
|
| + {
|
| + typedef const ValueType& argument_type;
|
| + typedef PyObject *result_type;
|
| + result_type operator()(argument_type v) const
|
| + {
|
| + return swig::from(v);
|
| + }
|
| + };
|
| +
|
| + template<typename OutIterator,
|
| + typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
| + typename FromOper = from_oper<ValueType> >
|
| + class SwigPyIteratorOpen_T : public SwigPyIterator_T<OutIterator>
|
| + {
|
| + public:
|
| + FromOper from;
|
| + typedef OutIterator out_iterator;
|
| + typedef ValueType value_type;
|
| + typedef SwigPyIterator_T<out_iterator> base;
|
| + typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
|
| +
|
| + SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq)
|
| + : SwigPyIterator_T<OutIterator>(curr, seq)
|
| + {
|
| + }
|
| +
|
| + PyObject *value() const {
|
| + return from(static_cast<const value_type&>(*(base::current)));
|
| + }
|
| +
|
| + SwigPyIterator *copy() const
|
| + {
|
| + return new self_type(*this);
|
| + }
|
| +
|
| + SwigPyIterator *incr(size_t n = 1)
|
| + {
|
| + while (n--) {
|
| + ++base::current;
|
| + }
|
| + return this;
|
| + }
|
| +
|
| + SwigPyIterator *decr(size_t n = 1)
|
| + {
|
| + while (n--) {
|
| + --base::current;
|
| + }
|
| + return this;
|
| + }
|
| + };
|
| +
|
| + template<typename OutIterator,
|
| + typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
| + typename FromOper = from_oper<ValueType> >
|
| + class SwigPyIteratorClosed_T : public SwigPyIterator_T<OutIterator>
|
| + {
|
| + public:
|
| + FromOper from;
|
| + typedef OutIterator out_iterator;
|
| + typedef ValueType value_type;
|
| + typedef SwigPyIterator_T<out_iterator> base;
|
| + typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
|
| +
|
| + SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
|
| + : SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
|
| + {
|
| + }
|
| +
|
| + PyObject *value() const {
|
| + if (base::current == end) {
|
| + throw stop_iteration();
|
| + } else {
|
| + return from(static_cast<const value_type&>(*(base::current)));
|
| + }
|
| + }
|
| +
|
| + SwigPyIterator *copy() const
|
| + {
|
| + return new self_type(*this);
|
| + }
|
| +
|
| + SwigPyIterator *incr(size_t n = 1)
|
| + {
|
| + while (n--) {
|
| + if (base::current == end) {
|
| + throw stop_iteration();
|
| + } else {
|
| + ++base::current;
|
| + }
|
| + }
|
| + return this;
|
| + }
|
| +
|
| + SwigPyIterator *decr(size_t n = 1)
|
| + {
|
| + while (n--) {
|
| + if (base::current == begin) {
|
| + throw stop_iteration();
|
| + } else {
|
| + --base::current;
|
| + }
|
| + }
|
| + return this;
|
| + }
|
| +
|
| + private:
|
| + out_iterator begin;
|
| + out_iterator end;
|
| + };
|
| +
|
| + template<typename OutIter>
|
| + inline SwigPyIterator*
|
| + make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0)
|
| + {
|
| + return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq);
|
| + }
|
| +
|
| + template<typename OutIter>
|
| + inline SwigPyIterator*
|
| + make_output_iterator(const OutIter& current, PyObject *seq = 0)
|
| + {
|
| + return new SwigPyIteratorOpen_T<OutIter>(current, seq);
|
| + }
|
| +}
|
| +}
|
| +
|
| +
|
| +%fragment("SwigPyIterator");
|
| +namespace swig
|
| +{
|
| + /*
|
| + Throw a StopIteration exception
|
| + */
|
| + %ignore stop_iteration;
|
| + struct stop_iteration {};
|
| +
|
| + %typemap(throws) stop_iteration {
|
| + (void)$1;
|
| + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
|
| + SWIG_fail;
|
| + }
|
| +
|
| + /*
|
| + Mark methods that return new objects
|
| + */
|
| + %newobject SwigPyIterator::copy;
|
| + %newobject SwigPyIterator::operator + (ptrdiff_t n) const;
|
| + %newobject SwigPyIterator::operator - (ptrdiff_t n) const;
|
| +
|
| + %nodirector SwigPyIterator;
|
| + %extend SwigPyIterator {
|
| + %pythoncode {def __iter__(self): return self}
|
| + }
|
| +
|
| + %catches(swig::stop_iteration) SwigPyIterator::value() const;
|
| + %catches(swig::stop_iteration) SwigPyIterator::incr(size_t n = 1);
|
| + %catches(swig::stop_iteration) SwigPyIterator::decr(size_t n = 1);
|
| + %catches(std::invalid_argument) SwigPyIterator::distance(const SwigPyIterator &x) const;
|
| + %catches(std::invalid_argument) SwigPyIterator::equal (const SwigPyIterator &x) const;
|
| + %catches(swig::stop_iteration) SwigPyIterator::__next__();
|
| + %catches(swig::stop_iteration) SwigPyIterator::next();
|
| + %catches(swig::stop_iteration) SwigPyIterator::previous();
|
| + %catches(swig::stop_iteration) SwigPyIterator::advance(ptrdiff_t n);
|
| + %catches(swig::stop_iteration) SwigPyIterator::operator += (ptrdiff_t n);
|
| + %catches(swig::stop_iteration) SwigPyIterator::operator -= (ptrdiff_t n);
|
| + %catches(swig::stop_iteration) SwigPyIterator::operator + (ptrdiff_t n) const;
|
| + %catches(swig::stop_iteration) SwigPyIterator::operator - (ptrdiff_t n) const;
|
| +
|
| +
|
| + struct SwigPyIterator
|
| + {
|
| + protected:
|
| + SwigPyIterator(PyObject *seq);
|
| +
|
| + public:
|
| + virtual ~SwigPyIterator();
|
| +
|
| + // Access iterator method, required by Python
|
| + virtual PyObject *value() const = 0;
|
| +
|
| + // Forward iterator method, required by Python
|
| + virtual SwigPyIterator *incr(size_t n = 1) = 0;
|
| +
|
| + // Backward iterator method, very common in C++, but not required in Python
|
| + virtual SwigPyIterator *decr(size_t n = 1);
|
| +
|
| + // Random access iterator methods, but not required in Python
|
| + virtual ptrdiff_t distance(const SwigPyIterator &x) const;
|
| +
|
| + virtual bool equal (const SwigPyIterator &x) const;
|
| +
|
| + // C++ common/needed methods
|
| + virtual SwigPyIterator *copy() const = 0;
|
| +
|
| + PyObject *next();
|
| + PyObject *__next__();
|
| + PyObject *previous();
|
| + SwigPyIterator *advance(ptrdiff_t n);
|
| +
|
| + bool operator == (const SwigPyIterator& x) const;
|
| + bool operator != (const SwigPyIterator& x) const;
|
| + SwigPyIterator& operator += (ptrdiff_t n);
|
| + SwigPyIterator& operator -= (ptrdiff_t n);
|
| + SwigPyIterator* operator + (ptrdiff_t n) const;
|
| + SwigPyIterator* operator - (ptrdiff_t n) const;
|
| + ptrdiff_t operator - (const SwigPyIterator& x) const;
|
| + };
|
| +}
|
| +
|
|
|