From: Marcelo M. <mar...@us...> - 2005-10-31 09:56:26
|
Update of /cvsroot/swig/SWIG/Lib/python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1459 Modified Files: pycontainer.swg std_map.i std_set.i Log Message: add iterator support Index: pycontainer.swg =================================================================== RCS file: /cvsroot/swig/SWIG/Lib/python/pycontainer.swg,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pycontainer.swg 24 Oct 2005 14:59:05 -0000 1.14 --- pycontainer.swg 31 Oct 2005 09:56:13 -0000 1.15 *************** *** 1,5 **** ! // // Python sequence <-> C++ container wrapper ! // // This wrapper, and its iterator, allows a general use (and reuse) of // the the mapping between C++ and Python, thanks to the C++ --- 1,5 ---- ! // // Python sequence <-> C++ container wrapper ! // // This wrapper, and its iterator, allows a general use (and reuse) of // the the mapping between C++ and Python, thanks to the C++ *************** *** 11,15 **** // %{ ! #include <iostream> %} --- 11,15 ---- // %{ ! #include <iostream> %} *************** *** 23,33 **** %} %fragment("PySequence_Base","header") { namespace swig { inline size_t check_index(ptrdiff_t i, size_t size, bool insert = false) { if ( i < 0 ) { ! if ((size_t) (-i) <= size) return (size_t) (i + size); } else if ( (size_t) i < size ) { --- 23,36 ---- %} + %include std_except.i + %fragment("PySequence_Base","header") { namespace swig { + inline size_t check_index(ptrdiff_t i, size_t size, bool insert = false) { if ( i < 0 ) { ! if ((size_t) (-i) <= size) return (size_t) (i + size); } else if ( (size_t) i < size ) { *************** *** 54,60 **** template <class Sequence, class Difference> ! inline typename Sequence::iterator getpos(Sequence* self, Difference i) { ! typename Sequence::iterator pos = self->begin(); std::advance(pos, check_index(i,self->size())); return pos; --- 57,63 ---- template <class Sequence, class Difference> ! inline typename Sequence::iterator getpos(Sequence* self, Difference i) { ! typename Sequence::iterator pos = self->begin(); std::advance(pos, check_index(i,self->size())); return pos; *************** *** 62,68 **** template <class Sequence, class Difference> ! inline typename Sequence::const_iterator cgetpos(const Sequence* self, Difference i) { ! typename Sequence::const_iterator pos = self->begin(); std::advance(pos, check_index(i,self->size())); return pos; --- 65,71 ---- template <class Sequence, class Difference> ! inline typename Sequence::const_iterator cgetpos(const Sequence* self, Difference i) { ! typename Sequence::const_iterator pos = self->begin(); std::advance(pos, check_index(i,self->size())); return pos; *************** *** 71,79 **** template <class Sequence, class Difference> inline Sequence* ! getslice(const Sequence* self, Difference i, Difference j) { typename Sequence::size_type size = self->size(); typename Sequence::size_type ii = swig::check_index(i, size); typename Sequence::size_type jj = swig::slice_index(j, size); ! if (jj > ii) { typename Sequence::const_iterator vb = self->begin(); --- 74,82 ---- template <class Sequence, class Difference> inline Sequence* ! getslice(const Sequence* self, Difference i, Difference j) { typename Sequence::size_type size = self->size(); typename Sequence::size_type ii = swig::check_index(i, size); typename Sequence::size_type jj = swig::slice_index(j, size); ! if (jj > ii) { typename Sequence::const_iterator vb = self->begin(); *************** *** 100,104 **** self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); } ! template <class Sequence, class Difference> inline void --- 103,107 ---- self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); } ! template <class Sequence, class Difference> inline void *************** *** 118,121 **** --- 121,239 ---- } + + #define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS + + #if defined(SWIG_EXPORT_ITERATOR_METHODS) + /* + Throw a StopIteration exception + */ + namespace swig + { + %ignore stop_iteration; + %typemap(throws) stop_iteration { + Py_INCREF(Py_None); + PyErr_SetObject(PyExc_StopIteration, Py_None); + } + } + + namespace swig { + %newobject PySequence_OutputIterator::operator +; + %newobject PySequence_OutputIterator::operator - (ptrdiff_t n) const; + %newobject PySequence_OutputIterator::copy; + } + + %inline { + namespace swig { + struct stop_iteration + { + }; + + struct PySequence_OutputIterator + { + private: + PyObject *_seq; + + protected: + PySequence_OutputIterator(PyObject *seq) : _seq(seq) + { + if (_seq) Py_INCREF(_seq); + } + + public: + virtual ~PySequence_OutputIterator() { + if (_seq) Py_DECREF(_seq); + } + + virtual PyObject *value() const throw (stop_iteration) = 0; + virtual PySequence_OutputIterator *incr(size_t n = 1) throw (stop_iteration) = 0; + virtual PySequence_OutputIterator *decr(size_t n = 1) throw (stop_iteration) = 0; + virtual PySequence_OutputIterator *copy() const = 0; + virtual ptrdiff_t distance(const PySequence_OutputIterator &x) const = 0; + virtual bool equal (const PySequence_OutputIterator &x) const = 0; + + PyObject *next() throw (stop_iteration) + { + PyObject *obj = value(); + incr(); + return obj; + } + + PyObject *previous() throw (stop_iteration) + { + decr(); + return value(); + } + + PySequence_OutputIterator *advance(ptrdiff_t n) throw (stop_iteration) + { + return (n > 0) ? incr(n) : decr(-n); + } + + public: + + bool operator == (const PySequence_OutputIterator& x) const + { + return equal(x); + } + + bool operator != (const PySequence_OutputIterator& x) const + { + return ! operator==(x); + } + + PySequence_OutputIterator& operator += (ptrdiff_t n) throw (stop_iteration) + { + return *advance(n); + } + + PySequence_OutputIterator& operator -= (ptrdiff_t n) throw (stop_iteration) + { + return *advance(-n); + } + + PySequence_OutputIterator* operator + (ptrdiff_t n) const throw (stop_iteration) + { + return copy()->advance(n); + } + + PySequence_OutputIterator* operator - (ptrdiff_t n) const throw (stop_iteration) + { + return copy()->advance(-n); + } + + ptrdiff_t operator - (const PySequence_OutputIterator& x) const + { + return x.distance(*this); + } + + static swig_type_info* desc() { + static swig_type_info* desc = SWIG_TypeQuery("swig::PySequence_OutputIterator *"); + return desc; + } + }; + } + } + #endif //SWIG_EXPORT_ITERATOR_METHODS + %fragment("PySequence_Cont","header", fragment="StdTraits", *************** *** 124,138 **** { #include <iterator> namespace swig { ! template <class T> struct PySequence_Ref { ! PySequence_Ref(PyObject* seq, int index) : _seq(seq), _index(index) { } ! ! operator T () const { swig::PyObject_var item = PySequence_GetItem(_seq, _index); --- 242,351 ---- { #include <iterator> + namespace swig { ! #if defined(SWIG_EXPORT_ITERATOR_METHODS) ! template<typename OutIterator> ! class PySequence_OutputIterator_T : public PySequence_OutputIterator ! { ! public: ! typedef OutIterator out_iterator; ! typedef typename std::iterator_traits<out_iterator>::value_type value_type; ! ! typedef PySequence_OutputIterator_T<out_iterator> self_type; ! ! PySequence_OutputIterator_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) ! : PySequence_OutputIterator(seq), current(curr), begin(first), end(last) ! { ! } ! ! PyObject *value() const throw (stop_iteration) { ! if (current == end) { ! throw stop_iteration(); ! } else { ! return swig::from((const value_type&)*(current)); ! } ! } ! ! ! PySequence_OutputIterator_T *copy() const ! { ! return new self_type(*this); ! } ! ! PySequence_OutputIterator_T *incr(size_t n = 1) throw (stop_iteration) ! { ! while (n--) { ! if (current == end) { ! throw stop_iteration(); ! } else { ! ++current; ! } ! } ! return this; ! } ! ! PySequence_OutputIterator_T *decr(size_t n = 1) throw (stop_iteration) ! { ! while (n--) { ! if (current == begin) { ! throw stop_iteration(); ! } else { ! --current; ! } ! } ! return this; ! } ! ! ! bool equal (const PySequence_OutputIterator &iter) const throw (std::invalid_argument) ! { ! 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 PySequence_OutputIterator &iter) const throw (std::invalid_argument) ! { ! 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"); ! } ! } ! ! const out_iterator& get_current() const ! { ! return current; ! } ! ! private: ! out_iterator current; ! out_iterator begin; ! out_iterator end; ! }; ! ! template<typename OutIter> ! inline PySequence_OutputIterator* ! make_output_iterator(const OutIter& current, const OutIter& begin = OutIter(), ! const OutIter& end = OutIter(), PyObject *seq = 0) ! { ! return new PySequence_OutputIterator_T<OutIter>(current, begin, end, seq); ! } ! #endif //SWIG_EXPORT_ITERATOR_METHODS ! ! template <class T> struct PySequence_Ref { ! PySequence_Ref(PyObject* seq, int index) : _seq(seq), _index(index) { } ! ! operator T () const { swig::PyObject_var item = PySequence_GetItem(_seq, _index); *************** *** 150,160 **** } } ! ! PySequence_Ref& operator=(const T& v) { PySequence_SetItem(_seq, _index, swig::from<T>(v)); return *this; } ! private: PyObject* _seq; --- 363,373 ---- } } ! ! PySequence_Ref& operator=(const T& v) { PySequence_SetItem(_seq, _index, swig::from<T>(v)); return *this; } ! private: PyObject* _seq; *************** *** 162,167 **** }; ! template <class T> ! struct PySequence_ArrowProxy { PySequence_ArrowProxy(const T& x): m_value(x) {} --- 375,380 ---- }; ! template <class T> ! struct PySequence_ArrowProxy { PySequence_ArrowProxy(const T& x): m_value(x) {} *************** *** 169,178 **** operator const T*() const { return &m_value; } T m_value; ! }; ! template <class T, class Reference > ! struct PySequence_Iter { ! typedef PySequence_Iter<T, Reference > self; typedef std::random_access_iterator_tag iterator_category; --- 382,391 ---- operator const T*() const { return &m_value; } T m_value; ! }; ! template <class T, class Reference > ! struct PySequence_InputIterator { ! typedef PySequence_InputIterator<T, Reference > self; typedef std::random_access_iterator_tag iterator_category; *************** *** 182,190 **** typedef int difference_type; ! PySequence_Iter() { } ! PySequence_Iter(PyObject* seq, int index) : _seq(seq), _index(index) { --- 395,403 ---- typedef int difference_type; ! PySequence_InputIterator() { } ! PySequence_InputIterator(PyObject* seq, int index) : _seq(seq), _index(index) { *************** *** 192,196 **** reference operator*() const ! { return reference(_seq, _index); } --- 405,409 ---- reference operator*() const ! { return reference(_seq, _index); } *************** *** 201,217 **** } ! bool operator==(const self& ri) const ! { return (_index == ri._index) && (_seq == ri._seq); } ! bool operator!=(const self& ri) const { return !(operator==(ri)); ! } self& operator ++ () { ! ++_index; return *this; } --- 414,430 ---- } ! bool operator==(const self& ri) const ! { return (_index == ri._index) && (_seq == ri._seq); } ! bool operator!=(const self& ri) const { return !(operator==(ri)); ! } self& operator ++ () { ! ++_index; return *this; } *************** *** 223,227 **** } ! self& operator += (difference_type n) { _index += n; --- 436,440 ---- } ! self& operator += (difference_type n) { _index += n; *************** *** 234,238 **** } ! self& operator -= (difference_type n) { _index -= n; --- 447,451 ---- } ! self& operator -= (difference_type n) { _index -= n; *************** *** 243,247 **** { return self(_seq, _index - n); ! } difference_type operator - (const self& ri) const --- 456,460 ---- { return self(_seq, _index - n); ! } difference_type operator - (const self& ri) const *************** *** 250,256 **** } ! reference ! operator[](difference_type n) const ! { return reference(_seq, _index + n); } --- 463,469 ---- } ! reference ! operator[](difference_type n) const ! { return reference(_seq, _index + n); } *************** *** 259,265 **** PyObject* _seq; int _index; ! }; ! template <class T> struct PySequence_Cont { --- 472,478 ---- PyObject* _seq; int _index; ! }; ! template <class T> struct PySequence_Cont { *************** *** 271,276 **** typedef int size_type; typedef const pointer const_pointer; ! typedef PySequence_Iter<T, reference> iterator; ! typedef PySequence_Iter<T, const_reference> const_iterator; PySequence_Cont(PyObject* seq) : _seq(0) --- 484,489 ---- typedef int size_type; typedef const pointer const_pointer; ! typedef PySequence_InputIterator<T, reference> iterator; ! typedef PySequence_InputIterator<T, const_reference> const_iterator; PySequence_Cont(PyObject* seq) : _seq(0) *************** *** 283,287 **** } ! ~PySequence_Cont() { if (_seq) Py_DECREF(_seq); --- 496,500 ---- } ! ~PySequence_Cont() { if (_seq) Py_DECREF(_seq); *************** *** 296,300 **** { return size() == 0; ! } iterator begin() --- 509,513 ---- { return size() == 0; ! } iterator begin() *************** *** 307,328 **** return const_iterator(_seq, 0); } ! iterator end() { return iterator(_seq, size()); } ! const_iterator end() const { return const_iterator(_seq, size()); ! } ! reference operator[](difference_type n) ! { return reference(_seq, n); } const_reference operator[](difference_type n) const ! { return const_reference(_seq, n); } --- 520,541 ---- return const_iterator(_seq, 0); } ! iterator end() { return iterator(_seq, size()); } ! const_iterator end() const { return const_iterator(_seq, size()); ! } ! reference operator[](difference_type n) ! { return reference(_seq, n); } const_reference operator[](difference_type n) const ! { return const_reference(_seq, n); } *************** *** 342,346 **** } } ! return true; } --- 555,559 ---- } } ! return true; } *************** *** 352,355 **** --- 565,642 ---- } + %define %swig_sequence_iterator(Sequence...) + #if defined(SWIG_EXPORT_ITERATOR_METHODS) + class iterator; + class reverse_iterator; + class const_iterator; + class const_reverse_iterator; + + %typemap(out,noblock=1,fragment="PySequence_Cont") + iterator, reverse_iterator, const_iterator, const_reverse_iterator { + $result = SWIG_NewPointerObj(swig::make_output_iterator((const $type &)$1), + swig::PySequence_OutputIterator::desc(),SWIG_POINTER_OWN); + } + %typemap(out,noblock=1,fragment="PySequence_Cont") + std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> { + $result = PyTuple_New(2); + PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + swig::PySequence_OutputIterator::desc(),SWIG_POINTER_OWN)); + PyTuple_SetItem($result,1,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), + swig::PySequence_OutputIterator::desc(),SWIG_POINTER_OWN)); + } + + %fragment("PyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="PySequence_Cont") {} + + %typemap(out,noblock=1,fragment="PyPairBoolOutputIterator") + std::pair<iterator, bool>, std::pair<const_iterator, bool> { + $result = PyTuple_New(2); + PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + swig::PySequence_OutputIterator::desc(),SWIG_POINTER_OWN)); + PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second)); + } + + %typemap(in,noblock=1,fragment="PySequence_Cont") + iterator(swig::PySequence_OutputIterator *iter), + reverse_iterator(swig::PySequence_OutputIterator *iter), + const_iterator(swig::PySequence_OutputIterator *iter), + const_reverse_iterator(swig::PySequence_OutputIterator *iter) { + if (SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::PySequence_OutputIterator::desc(), 0) != SWIG_OK) { + %argument_fail(SWIG_TypeError, "$type", $argnum); + } + if (iter) { + swig::PySequence_OutputIterator_T<$type > *iter_t + = dynamic_cast<swig::PySequence_OutputIterator_T<$type > *>(iter); + $1 = iter_t->get_current(); + } else { + %argument_fail(SWIG_TypeError, "$type", $argnum); + } + } + + %typecheck(%checkcode(ITERATOR),noblock=1,fragment="PySequence_Cont") + iterator, reverse_iterator, const_iterator, const_reverse_iterator { + swig::PySequence_OutputIterator *iter = 0; + $1 = ((SWIG_ConvertPtr($input, %as_voidptrptr(&iter), + swig::PySequence_OutputIterator::desc(), 0) == SWIG_OK) + && iter + && (dynamic_cast<swig::PySequence_OutputIterator_T<$type > *>(iter) != 0)); + } + + %fragment("PySequence_Cont"); + + %newobject output_iterator(PyObject *seq); + %extend { + swig::PySequence_OutputIterator* output_iterator(PyObject *seq) { + return swig::make_output_iterator(self->begin(), self->begin(), self->end(), seq); + } + + %pythoncode { + def __iter__(self): + i = self.output_iterator(self) + return i + } + } + #endif //SWIG_EXPORT_ITERATOR_METHODS + %enddef + /**** The python container methods ****/ *************** *** 372,376 **** --- 659,665 ---- %define %swig_sequence_methods_common(Sequence...) + %swig_sequence_iterator(%arg(Sequence)) %swig_container_methods(%arg(Sequence)) + %fragment("PySequence_Base"); *************** *** 388,392 **** } ! void __setslice__(difference_type i, difference_type j, const Sequence& v) throw (std::out_of_range, std::invalid_argument) { swig::setslice(self, i, j, v); } --- 677,682 ---- } ! void __setslice__(difference_type i, difference_type j, const Sequence& v) ! throw (std::out_of_range, std::invalid_argument) { swig::setslice(self, i, j, v); } *************** *** 437,440 **** --- 727,732 ---- + + // // Common fragments *************** *** 446,450 **** { namespace swig { ! template <class PySeq, class Seq> inline void assign(const PySeq& pyseq, Seq* seq) { --- 738,742 ---- { namespace swig { ! template <class PySeq, class Seq> inline void assign(const PySeq& pyseq, Seq* seq) { *************** *** 464,468 **** typedef Seq sequence; typedef T value_type; ! static int asptr(PyObject *obj, sequence **seq) { if (PySequence_Check(obj)) { --- 756,760 ---- typedef Seq sequence; typedef T value_type; ! static int asptr(PyObject *obj, sequence **seq) { if (PySequence_Check(obj)) { *************** *** 493,500 **** } if (seq) { ! PyErr_Format(PyExc_TypeError, "a %s is expected", swig::type_name<sequence>()); } ! return 0; } }; --- 785,792 ---- } if (seq) { ! PyErr_Format(PyExc_TypeError, "a %s is expected", swig::type_name<sequence>()); } ! return 0; } }; Index: std_set.i =================================================================== RCS file: /cvsroot/swig/SWIG/Lib/python/std_set.i,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** std_set.i 27 Jul 2005 20:09:41 -0000 1.13 --- std_set.i 31 Oct 2005 09:56:13 -0000 1.14 *************** *** 37,55 **** %define %swig_set_methods(set...) %swig_container_methods(set); %extend { ! void append(value_type x) { ! self->insert(x); ! } ! bool __contains__(value_type x) { ! return self->find(x) != self->end(); ! } ! value_type __getitem__(difference_type i) const throw (std::out_of_range) { ! return *(swig::cgetpos(self, i)); ! } ! }; %enddef --- 37,57 ---- %define %swig_set_methods(set...) + %swig_sequence_iterator(set); %swig_container_methods(set); %extend { ! void append(value_type x) { ! self->insert(x); ! } ! bool __contains__(value_type x) { ! return self->find(x) != self->end(); ! } ! value_type __getitem__(difference_type i) const throw (std::out_of_range) { ! return *(swig::cgetpos(self, i)); ! } ! ! }; %enddef Index: std_map.i =================================================================== RCS file: /cvsroot/swig/SWIG/Lib/python/std_map.i,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** std_map.i 27 Jul 2005 20:09:41 -0000 1.15 --- std_map.i 31 Oct 2005 09:56:13 -0000 1.16 *************** *** 59,62 **** --- 59,63 ---- %define %swig_map_methods(Map...) + %swig_sequence_iterator(Map); %swig_container_methods(Map) *************** *** 140,143 **** --- 141,145 ---- } + #if !defined(SWIG_EXPORT_ITERATOR_METHODS) || defined(SWIG_USE_OLD_MAP_ITERATOR) PyObject* __iter__() { Map::size_type size = self->size(); *************** *** 161,164 **** --- 163,167 ---- %#endif } + #endif } %enddef |