map iterators now use the native PySwigIterator, which is very very good for large maps, since no more temporals key/value tuples are needed
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8311 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
bed09b373e
commit
2bde7c2c3b
3 changed files with 134 additions and 57 deletions
|
|
@ -62,6 +62,73 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct from_key_oper
|
||||
{
|
||||
typedef const ValueType& argument_type;
|
||||
typedef PyObject *result_type;
|
||||
result_type operator()(argument_type v) const
|
||||
{
|
||||
return swig::from(v.first);
|
||||
}
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct from_value_oper
|
||||
{
|
||||
typedef const ValueType& argument_type;
|
||||
typedef PyObject *result_type;
|
||||
result_type operator()(argument_type v) const
|
||||
{
|
||||
return swig::from(v.second);
|
||||
}
|
||||
};
|
||||
|
||||
template<class OutIterator, class FromOper, class ValueType = typename OutIterator::value_type>
|
||||
struct PyMapIterator_T : PySwigIteratorClosed_T<OutIterator, ValueType, FromOper>
|
||||
{
|
||||
PyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
|
||||
: PySwigIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class OutIterator,
|
||||
class FromOper = from_key_oper<typename OutIterator::value_type> >
|
||||
struct PyMapKeyIterator_T : PyMapIterator_T<OutIterator, FromOper>
|
||||
{
|
||||
PyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
|
||||
: PyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename OutIter>
|
||||
inline PySwigIterator*
|
||||
make_output_key_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
|
||||
{
|
||||
return new PyMapKeyIterator_T<OutIter>(current, begin, end, seq);
|
||||
}
|
||||
|
||||
template<class OutIterator,
|
||||
class FromOper = from_value_oper<typename OutIterator::value_type> >
|
||||
struct PyMapValueIterator_T : PyMapIterator_T<OutIterator, FromOper>
|
||||
{
|
||||
PyMapValueIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
|
||||
: PyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename OutIter>
|
||||
inline PySwigIterator*
|
||||
make_output_value_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
|
||||
{
|
||||
return new PyMapValueIterator_T<OutIter>(current, begin, end, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,53 +221,16 @@
|
|||
return self->find(key) != self->end();
|
||||
}
|
||||
|
||||
PyObject* key_iterator() {
|
||||
Map::size_type size = self->size();
|
||||
int pysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
|
||||
if (pysize < 0) {
|
||||
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"map size not valid in python");
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return NULL;
|
||||
}
|
||||
PyObject* keyTuple = PyTuple_New(pysize);
|
||||
Map::const_iterator i = self->begin();
|
||||
for (int j = 0; j < pysize; ++i, ++j) {
|
||||
PyTuple_SET_ITEM(keyTuple, j, swig::from(i->first));
|
||||
}
|
||||
%#if PY_VERSION_HEX >= 0x02020000
|
||||
PyObject* iter = PyObject_GetIter(keyTuple);
|
||||
Py_DECREF(keyTuple);
|
||||
return iter;
|
||||
%#else
|
||||
return keyTuple;
|
||||
%#endif
|
||||
%newobject key_iterator(PyObject **PYTHON_SELF);
|
||||
swig::PySwigIterator* key_iterator(PyObject **PYTHON_SELF) {
|
||||
return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
|
||||
}
|
||||
PyObject* value_iterator() {
|
||||
Map::size_type size = self->size();
|
||||
int pysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
|
||||
if (pysize < 0) {
|
||||
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"map size not valid in python");
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return NULL;
|
||||
}
|
||||
PyObject* keyTuple = PyTuple_New(pysize);
|
||||
Map::const_iterator i = self->begin();
|
||||
for (int j = 0; j < pysize; ++i, ++j) {
|
||||
PyTuple_SET_ITEM(keyTuple, j, swig::from(i->second));
|
||||
}
|
||||
%#if PY_VERSION_HEX >= 0x02020000
|
||||
PyObject* iter = PyObject_GetIter(keyTuple);
|
||||
Py_DECREF(keyTuple);
|
||||
return iter;
|
||||
%#else
|
||||
return keyTuple;
|
||||
%#endif
|
||||
|
||||
%newobject value_iterator(PyObject **PYTHON_SELF);
|
||||
swig::PySwigIterator* value_iterator(PyObject **PYTHON_SELF) {
|
||||
return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
|
||||
}
|
||||
#if !defined(SWIG_USE_STD_MAP_ITERATOR)
|
||||
|
||||
%pythoncode {
|
||||
def __iter__(self):
|
||||
return self.key_iterator()
|
||||
|
|
@ -214,7 +244,6 @@
|
|||
def iteritems(self):
|
||||
return self.iterator()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue