fix vector slice/del problems

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6338 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-10-06 02:31:31 +00:00
commit 5fc322f0b6
3 changed files with 141 additions and 22 deletions

View file

@ -52,3 +52,40 @@ if ArrInt_getitem(vi[0],0) != ArrInt_getitem(vi[1],2):
a = halfs([10,8,4,3]) a = halfs([10,8,4,3])
v = IntVector()
v[0:2] = [1,2]
if v[0] != 1 or v[1] != 2:
raise RuntimeError,"bad setslice"
if v[0:-1][0] != 1:
raise RuntimeError,"bad getslice"
if v[0:-2].size() != 0:
raise RuntimeError,"bad getslice"
v[0:1] = [2]
if v[0] != 2:
raise RuntimeError,"bad setslice"
v[1:] = [3]
if v[1] != 3:
raise RuntimeError,"bad setslice"
v[2:] = [3]
if v[2] != 3:
raise RuntimeError,"bad setslice"
if v[0:][0] != v[0]:
raise RuntimeError,"bad getslice"
del v[:]
if v.size() != 0:
raise RuntimeError,"bad getslice"
del v[:]
if v.size() != 0:
raise RuntimeError,"bad getslice"

View file

@ -340,6 +340,16 @@ static void SWIG_exception(int code, const char *msg) {
SWIG_exception(SWIG_SystemError, e.what() ); SWIG_exception(SWIG_SystemError, e.what() );
} }
%enddef %enddef
%define SWIG_CATCH_UNKNOWN
catch (std::exception& e) {
SWIG_exception(SWIG_SystemError, e.what() );
}
catch (...) {
SWIG_exception(SWIG_UnknownError, "unknown exception");
}
%enddef
#endif // __cplusplus #endif // __cplusplus
/* exception.i ends here */ /* exception.i ends here */

View file

@ -9,7 +9,9 @@
// since we will use this wrapper with the STL containers, that should // since we will use this wrapper with the STL containers, that should
// be the case. // be the case.
// //
%{
#include <iostream>
%}
/**** The PySequence C++ Wrap ***/ /**** The PySequence C++ Wrap ***/
@ -24,23 +26,29 @@
%{ %{
namespace swigpy { namespace swigpy {
inline size_t inline size_t
check_index(ptrdiff_t i, size_t size) { check_index(ptrdiff_t i, size_t size, bool insert = false) {
if ( i < 0 ) { if ( i < 0 ) {
if ((size_t) (-i) <= size) if ((size_t) (-i) <= size)
return (size_t) (i + size); return (size_t) (i + size);
} else if ( (size_t) i < size ) { } else if ( (size_t) i < size ) {
return (size_t) i; return (size_t) i;
} if (insert) {
if (i == size) return i;
} }
throw std::out_of_range("index out of range"); throw std::out_of_range("index out of range");
} }
inline size_t inline size_t
slice_index(ptrdiff_t i, size_t size) { slice_index(ptrdiff_t i, size_t size) {
if ( i < 0 ) { if ( i < 0 ) {
return ((size_t) (-i) <= size) ? (size_t) (i + size) : 0; if ((size_t) (-i) <= size) {
return (size_t) (i + size);
} else { } else {
return ( (size_t) i < size ) ? ((size_t) i) throw std::out_of_range("index out of range");
: (size ? (size_t)(size - 1) : 0); }
} else {
return ( (size_t) i < size ) ? ((size_t) i) : size;
} }
} }
@ -48,7 +56,7 @@ namespace swigpy {
inline typename Sequence::iterator inline typename Sequence::iterator
getpos(Sequence* self, Difference i) { getpos(Sequence* self, Difference i) {
typename Sequence::iterator pos = self->begin(); typename Sequence::iterator pos = self->begin();
std::advance(pos, swigpy::check_index(i, self->size())); std::advance(pos, check_index(i,self->size()));
return pos; return pos;
} }
@ -56,7 +64,7 @@ namespace swigpy {
inline typename Sequence::const_iterator inline typename Sequence::const_iterator
cgetpos(const Sequence* self, Difference i) { cgetpos(const Sequence* self, Difference i) {
typename Sequence::const_iterator pos = self->begin(); typename Sequence::const_iterator pos = self->begin();
std::advance(pos, swigpy::check_index(i, self->size())); std::advance(pos, check_index(i,self->size()));
return pos; return pos;
} }
@ -64,10 +72,15 @@ namespace swigpy {
inline Sequence* inline Sequence*
getslice(const Sequence* self, Difference i, Difference j) { getslice(const Sequence* self, Difference i, Difference j) {
typename Sequence::size_type size = self->size(); typename Sequence::size_type size = self->size();
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::check_index(i, size);
typename Sequence::size_type jj = swigpy::slice_index(j, size); typename Sequence::size_type jj = swigpy::slice_index(j, size);
if (jj > ii) { if (jj > ii) {
return new Sequence(cgetpos(self, ii), cgetpos(self, jj)); typename Sequence::const_iterator vb = self->begin();
typename Sequence::const_iterator ve = self->begin();
std::advance(vb,ii);
std::advance(ve,jj);
return new Sequence(vb, ve);
} else { } else {
return new Sequence(); return new Sequence();
} }
@ -77,21 +90,28 @@ namespace swigpy {
inline void inline void
setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
typename Sequence::size_type size = self->size(); typename Sequence::size_type size = self->size();
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::check_index(i, size, true);
typename Sequence::size_type jj = swigpy::slice_index(j, size); typename Sequence::size_type jj = swigpy::slice_index(j, size);
if (jj < ii) jj = ii; if (jj < ii) jj = ii;
typename InputSeq::const_iterator vmid = cgetpos(&v, jj - ii); typename Sequence::iterator sb = self->begin();
self->insert(std::copy(v.begin(), vmid, getpos(self,ii)), vmid, v.end()); typename InputSeq::const_iterator vmid = v.begin();
std::advance(sb,ii);
std::advance(vmid, jj - ii);
self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
} }
template <class Sequence, class Difference> template <class Sequence, class Difference>
inline void inline void
delslice(Sequence* self, Difference i, Difference j) { delslice(Sequence* self, Difference i, Difference j) {
typename Sequence::size_type size = self->size(); typename Sequence::size_type size = self->size();
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::check_index(i, size, true);
typename Sequence::size_type jj = swigpy::slice_index(j, size); typename Sequence::size_type jj = swigpy::slice_index(j, size);
if (jj > ii) { if (jj > ii) {
self->erase(getpos(self,ii), getpos(self,jj)); typename Sequence::iterator sb = self->begin();
typename Sequence::iterator se = self->begin();
std::advance(sb,ii);
std::advance(se,jj);
self->erase(sb,se);
} }
} }
} }
@ -341,42 +361,94 @@ namespace swigpy
%exception __getitem__ { %exception __getitem__ {
try { $action } try { $action }
catch (std::out_of_range& e) { catch (std::out_of_range& e) {
if (!PyErr_Occurred()) if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
} }
} }
SWIG_CATCH_UNKNOWN
}
%exception __setitem__ { %exception __setitem__ {
try { $action } try { $action }
catch (std::out_of_range& e) { catch (std::out_of_range& e) {
if (!PyErr_Occurred()) if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
} }
} }
SWIG_CATCH_UNKNOWN
}
%exception __getslice__ {
try { $action }
catch (std::out_of_range& e) {
if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
}
}
SWIG_CATCH_UNKNOWN
}
%exception __setslice__ { %exception __setslice__ {
try { $action } try { $action }
catch (std::invalid_argument& e) { catch (std::out_of_range& e) {
if (!PyErr_Occurred()) if (!PyErr_Occurred()) {
SWIG_exception(SWIG_TypeError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
} }
} }
catch (std::invalid_argument& e) {
if (!PyErr_Occurred()) {
SWIG_exception(SWIG_TypeError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
}
}
SWIG_CATCH_UNKNOWN
}
%exception __delslice__ {
try { $action }
catch (std::out_of_range& e) {
if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
}
}
SWIG_CATCH_UNKNOWN
}
%exception __delitem__ { %exception __delitem__ {
try { $action } try { $action }
catch (std::out_of_range& e) { catch (std::out_of_range& e) {
if (!PyErr_Occurred()) if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
} }
} }
SWIG_CATCH_UNKNOWN
}
%exception pop { %exception pop {
try { $action } try { $action }
catch (std::out_of_range& e) { catch (std::out_of_range& e) {
if (!PyErr_Occurred()) if (!PyErr_Occurred()) {
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what())); SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
} else {
SWIG_fail;
} }
} }
SWIG_CATCH_UNKNOWN
}
%newobject __getslice__; %newobject __getslice__;