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; |
+ }; |
+} |
+ |