summaryrefslogtreecommitdiff
path: root/Lib/python/pycontainer.swg
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/python/pycontainer.swg')
-rw-r--r--Lib/python/pycontainer.swg315
1 files changed, 52 insertions, 263 deletions
diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg
index 4910fecc0..ceee27f5d 100644
--- a/Lib/python/pycontainer.swg
+++ b/Lib/python/pycontainer.swg
@@ -456,239 +456,6 @@ namespace swig {
}
}
-%fragment("SwigPySequence_Cont","header",
- fragment="StdTraits",
- fragment="SwigPySequence_Base",
- fragment="SwigPyIterator_T")
-{
-namespace swig
-{
- template <class T>
- struct SwigPySequence_Ref
- {
- SwigPySequence_Ref(PyObject* seq, Py_ssize_t index)
- : _seq(seq), _index(index)
- {
- }
-
- operator T () const
- {
- swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
- try {
- return swig::as<T>(item);
- } catch (const std::invalid_argument& e) {
- char msg[1024];
- PyOS_snprintf(msg, sizeof(msg), "in sequence element %d ", (int)_index);
- if (!PyErr_Occurred()) {
- ::%type_error(swig::type_name<T>());
- }
- SWIG_Python_AddErrorMsg(msg);
- SWIG_Python_AddErrorMsg(e.what());
- throw;
- }
- }
-
- SwigPySequence_Ref& operator=(const T& v)
- {
- PySequence_SetItem(_seq, _index, swig::from<T>(v));
- return *this;
- }
-
- private:
- PyObject* _seq;
- Py_ssize_t _index;
- };
-
- template <class T>
- struct SwigPySequence_ArrowProxy
- {
- SwigPySequence_ArrowProxy(const T& x): m_value(x) {}
- const T* operator->() const { return &m_value; }
- operator const T*() const { return &m_value; }
- T m_value;
- };
-
- template <class T, class Reference >
- struct SwigPySequence_InputIterator
- {
- typedef SwigPySequence_InputIterator<T, Reference > self;
-
- typedef std::random_access_iterator_tag iterator_category;
- typedef Reference reference;
- typedef T value_type;
- typedef T* pointer;
- typedef Py_ssize_t difference_type;
-
- SwigPySequence_InputIterator()
- {
- }
-
- SwigPySequence_InputIterator(PyObject* seq, Py_ssize_t index)
- : _seq(seq), _index(index)
- {
- }
-
- reference operator*() const
- {
- return reference(_seq, _index);
- }
-
- SwigPySequence_ArrowProxy<T>
- operator->() const {
- return SwigPySequence_ArrowProxy<T>(operator*());
- }
-
- 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;
- }
-
- self& operator -- ()
- {
- --_index;
- return *this;
- }
-
- self& operator += (difference_type n)
- {
- _index += n;
- return *this;
- }
-
- self operator +(difference_type n) const
- {
- return self(_seq, _index + n);
- }
-
- self& operator -= (difference_type n)
- {
- _index -= n;
- return *this;
- }
-
- self operator -(difference_type n) const
- {
- return self(_seq, _index - n);
- }
-
- difference_type operator - (const self& ri) const
- {
- return _index - ri._index;
- }
-
- bool operator < (const self& ri) const
- {
- return _index < ri._index;
- }
-
- reference
- operator[](difference_type n) const
- {
- return reference(_seq, _index + n);
- }
-
- private:
- PyObject* _seq;
- difference_type _index;
- };
-
- // STL container wrapper around a Python sequence
- template <class T>
- struct SwigPySequence_Cont
- {
- typedef SwigPySequence_Ref<T> reference;
- typedef const SwigPySequence_Ref<T> const_reference;
- typedef T value_type;
- typedef T* pointer;
- typedef Py_ssize_t difference_type;
- typedef size_t size_type;
- typedef const pointer const_pointer;
- typedef SwigPySequence_InputIterator<T, reference> iterator;
- typedef SwigPySequence_InputIterator<T, const_reference> const_iterator;
-
- SwigPySequence_Cont(PyObject* seq) : _seq(0)
- {
- if (!PySequence_Check(seq)) {
- throw std::invalid_argument("a sequence is expected");
- }
- _seq = seq;
- Py_INCREF(_seq);
- }
-
- ~SwigPySequence_Cont()
- {
- Py_XDECREF(_seq);
- }
-
- size_type size() const
- {
- return static_cast<size_type>(PySequence_Size(_seq));
- }
-
- bool empty() const
- {
- return size() == 0;
- }
-
- iterator begin()
- {
- return iterator(_seq, 0);
- }
-
- const_iterator begin() const
- {
- 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);
- }
-
- bool check() const
- {
- Py_ssize_t s = size();
- for (Py_ssize_t i = 0; i < s; ++i) {
- swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
- if (!swig::check<value_type>(item))
- return false;
- }
- return true;
- }
-
- private:
- PyObject* _seq;
- };
-
-}
-}
-
%define %swig_sequence_iterator(Sequence...)
%swig_sequence_iterator_with_making_function(swig::make_output_iterator,Sequence...)
%enddef
@@ -704,12 +471,12 @@ namespace swig
class const_iterator;
class const_reverse_iterator;
- %typemap(out,noblock=1,fragment="SwigPySequence_Cont")
+ %typemap(out,noblock=1,fragment="SwigPyIterator_T")
iterator, reverse_iterator, const_iterator, const_reverse_iterator {
$result = SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &)),
swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
}
- %typemap(out,noblock=1,fragment="SwigPySequence_Cont")
+ %typemap(out,noblock=1,fragment="SwigPyIterator_T")
std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> {
$result = PyTuple_New(2);
PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first),
@@ -718,7 +485,7 @@ namespace swig
swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN));
}
- %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="SwigPySequence_Cont") {}
+ %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="SwigPyIterator_T") {}
%typemap(out,noblock=1,fragment="SwigPyPairBoolOutputIterator")
std::pair<iterator, bool>, std::pair<const_iterator, bool> {
@@ -728,7 +495,7 @@ namespace swig
PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second));
}
- %typemap(in,noblock=1,fragment="SwigPySequence_Cont")
+ %typemap(in,noblock=1,fragment="SwigPyIterator_T")
iterator(swig::SwigPyIterator *iter = 0, int res),
reverse_iterator(swig::SwigPyIterator *iter = 0, int res),
const_iterator(swig::SwigPyIterator *iter = 0, int res),
@@ -746,14 +513,14 @@ namespace swig
}
}
- %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPySequence_Cont")
+ %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPyIterator_T")
iterator, reverse_iterator, const_iterator, const_reverse_iterator {
swig::SwigPyIterator *iter = 0;
int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
$1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<$type > *>(iter) != 0));
}
- %fragment("SwigPySequence_Cont");
+ %fragment("SwigPyIterator_T");
%newobject iterator(PyObject **PYTHON_SELF);
%extend {
@@ -999,26 +766,50 @@ namespace swig
%fragment("StdSequenceTraits","header",
fragment="StdTraits",
- fragment="SwigPySequence_Cont")
+ fragment="SwigPySequence_Base")
{
namespace swig {
- template <class SwigPySeq, class Seq>
- inline void
- assign(const SwigPySeq& swigpyseq, Seq* seq) {
- // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
- typedef typename SwigPySeq::value_type value_type;
- typename SwigPySeq::const_iterator it = swigpyseq.begin();
- for (;it != swigpyseq.end(); ++it) {
- seq->insert(seq->end(),(value_type)(*it));
+ template <class Seq, class T = typename Seq::value_type >
+ struct IteratorProtocol {
+ static void assign(PyObject *obj, Seq *seq) {
+ SwigVar_PyObject iter = PyObject_GetIter(obj);
+ if (iter) {
+ SwigVar_PyObject item = PyIter_Next(iter);
+ while (item) {
+ seq->insert(seq->end(), swig::as<T>(item));
+ item = PyIter_Next(iter);
+ }
+ }
}
- }
+
+ static bool check(PyObject *obj) {
+ int ret = false;
+ SwigVar_PyObject iter = PyObject_GetIter(obj);
+ if (iter) {
+ SwigVar_PyObject item = PyIter_Next(iter);
+ ret = true;
+ while (item) {
+ ret = swig::check<T>(item);
+ item = ret ? PyIter_Next(iter) : 0;
+ }
+ }
+ return ret;
+ }
+ };
template <class Seq, class T = typename Seq::value_type >
struct traits_asptr_stdseq {
typedef Seq sequence;
typedef T value_type;
+ static bool is_iterable(PyObject *obj) {
+ SwigVar_PyObject iter = PyObject_GetIter(obj);
+ PyErr_Clear();
+ return iter != 0;
+ }
+
static int asptr(PyObject *obj, sequence **seq) {
+ int ret = SWIG_ERROR;
if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) {
sequence *p;
swig_type_info *descriptor = swig::type_info<sequence>();
@@ -1026,27 +817,25 @@ namespace swig {
if (seq) *seq = p;
return SWIG_OLDOBJ;
}
- } else if (PySequence_Check(obj)) {
+ } else if (is_iterable(obj)) {
try {
- SwigPySequence_Cont<value_type> swigpyseq(obj);
if (seq) {
- sequence *pseq = new sequence();
- assign(swigpyseq, pseq);
- *seq = pseq;
- return SWIG_NEWOBJ;
+ *seq = new sequence();
+ IteratorProtocol<Seq, T>::assign(obj, *seq);
+ if (!PyErr_Occurred())
+ return SWIG_NEWOBJ;
} else {
- return swigpyseq.check() ? SWIG_OK : SWIG_ERROR;
+ return IteratorProtocol<Seq, T>::check(obj) ? SWIG_OK : SWIG_ERROR;
}
} catch (std::exception& e) {
- if (seq) {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, e.what());
- }
- }
- return SWIG_ERROR;
+ if (seq && !PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError, e.what());
}
+ if (seq)
+ delete *seq;
+ return SWIG_ERROR;
}
- return SWIG_ERROR;
+ return ret;
}
};