fix vector<bool> problems

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5831 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-04-05 23:24:39 +00:00
commit 5ddf147312
2 changed files with 63 additions and 46 deletions

View file

@ -17,15 +17,17 @@
#if PY_VERSION_HEX < 0x02000000 #if PY_VERSION_HEX < 0x02000000
#define PySequence_Size PySequence_Length #define PySequence_Size PySequence_Length
#endif #endif
#include <stdexcept>
%} %}
%fragment("PySequence_Base","header") %fragment("PySequence_Base","header")
%{ %{
namespace swigpy { namespace swigpy {
inline size_t inline size_t
sequence_index(ptrdiff_t i, size_t size) { check_index(ptrdiff_t i, size_t size) {
if ( i < 0 ) { if ( i < 0 ) {
if ((size_t) (-i) <= size) return (size_t) (i + size); if ((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;
} }
@ -42,6 +44,22 @@ namespace swigpy {
} }
} }
template <class Sequence, class Difference>
inline typename Sequence::iterator
getpos(Sequence* self, Difference i) {
typename Sequence::iterator pos = self->begin();
std::advance(pos, swigpy::check_index(i, self->size()));
return pos;
}
template <class Sequence, class Difference>
inline typename Sequence::const_iterator
getpos(const Sequence* self, Difference i) {
typename Sequence::const_iterator pos = self->begin();
std::advance(pos, swigpy::check_index(i, self->size()));
return pos;
}
template <class Sequence, class Difference> template <class Sequence, class Difference>
inline Sequence* inline Sequence*
getslice(const Sequence* self, Difference i, Difference j) { getslice(const Sequence* self, Difference i, Difference j) {
@ -49,11 +67,7 @@ namespace swigpy {
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::slice_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) {
typename Sequence::const_iterator beg = self->begin(); return new Sequence(getpos(self, ii), getpos(self, jj));
std::advance(beg, ii);
typename Sequence::const_iterator end = self->begin();
std::advance(end, jj);
return new Sequence(beg, end);
} else { } else {
return new Sequence(); return new Sequence();
} }
@ -66,11 +80,8 @@ namespace swigpy {
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::slice_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) jj = ii; if (jj < ii) jj = ii;
typename Sequence::iterator beg = self->begin(); typename InputSeq::const_iterator vmid = getpos(&v, jj - ii);
std::advance(beg,ii); self->insert(std::copy(v.begin(), vmid, getpos(self,ii)), vmid, v.end());
typename InputSeq::const_iterator vmid = v.begin();
std::advance(vmid, jj - ii);
self->insert(std::copy(v.begin(), vmid, beg), vmid, v.end());
} }
template <class Sequence, class Difference> template <class Sequence, class Difference>
@ -80,37 +91,9 @@ namespace swigpy {
typename Sequence::size_type ii = swigpy::slice_index(i, size); typename Sequence::size_type ii = swigpy::slice_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) {
typename Sequence::iterator beg = self->begin(); self->erase(getpos(self,ii), getpos(self,jj));
std::advance(beg, ii);
typename Sequence::iterator end = self->begin();
std::advance(end, jj);
self->erase(beg, end);
} }
} }
template <class Sequence, class Difference>
inline void
delitem(Sequence* self, Difference i) {
typename Sequence::iterator pos = self->begin();
std::advance(pos, swigpy::sequence_index(i, self->size()));
self->erase(pos);
}
template <class Sequence, class Difference>
inline const typename Sequence::value_type&
getitem(const Sequence* self, Difference i) {
typename Sequence::const_iterator pos = self->begin();
std::advance(pos, swigpy::sequence_index(i, self->size()));
return *(pos);
}
template <class Sequence, class Difference, class Value>
inline void
setitem(Sequence* self, Difference i, const Value& x) {
typename Sequence::iterator pos = self->begin();
std::advance(pos, swigpy::sequence_index(i, self->size()));
*(pos) = x;
}
} }
%} %}
@ -424,7 +407,7 @@ namespace swigpy
} }
void __delitem__(difference_type i) { void __delitem__(difference_type i) {
swigpy::delitem(self,i); self->erase(swigpy::getpos(self,i));
} }
} }
%enddef %enddef
@ -433,11 +416,11 @@ namespace swigpy
%pysequence_methods_common(SWIG_arg(Sequence)) %pysequence_methods_common(SWIG_arg(Sequence))
%extend { %extend {
const value_type& __getitem__(difference_type i) const { const value_type& __getitem__(difference_type i) const {
return swigpy::getitem(self, i); return *(swigpy::getpos(self, i));
} }
void __setitem__(difference_type i, const value_type& x) { void __setitem__(difference_type i, const value_type& x) {
swigpy::setitem(self, i, x); *(swigpy::getpos(self,i)) = x;
} }
void append(const value_type& x) { void append(const value_type& x) {
@ -450,11 +433,11 @@ namespace swigpy
%pysequence_methods_common(SWIG_arg(Sequence)) %pysequence_methods_common(SWIG_arg(Sequence))
%extend { %extend {
value_type __getitem__(difference_type i) { value_type __getitem__(difference_type i) {
return swigpy::getitem(self, i); return *(swigpy::getpos(self, i));
} }
void __setitem__(difference_type i, value_type x) { void __setitem__(difference_type i, value_type x) {
swigpy::setitem(self, i, x); *(swigpy::getpos(self,i)) = x;
} }
void append(value_type x) { void append(value_type x) {

View file

@ -153,6 +153,40 @@ namespace std {
%std_vector_methods_val(vector); %std_vector_methods_val(vector);
%pysequence_methods_val(std::vector<T* >); %pysequence_methods_val(std::vector<T* >);
}; };
// ***
// ***
template<class T > class vector<bool> {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef bool value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type reference;
typedef value_type const_reference;
%traits_swigtype(bool);
%fragment(SWIG_Traits_frag(std::vector<bool>), "header",
fragment=SWIG_Traits_frag(bool),
fragment="StdVectorTraits") {
namespace swigpy {
template <> struct traits<std::vector<bool> > {
typedef value_category category;
static const char* type_name() {
return "std::vector<bool>";
}
};
}
}
%typemap_traits_ptr(SWIG_CCode(VECTOR), std::vector<bool>);
%std_vector_methods_val(vector<bool>);
%pysequence_methods_val(std::vector<bool>);
};
} }
%define %std_vector_ptypen(...) %define %std_vector_ptypen(...)