1 2 // 3 // Common fragments 4 // 5 6 7 /**** The python container methods ****/ 8 9 10 11 %fragment("StdSequenceTraits","header",fragment="<stddef.h>") 12 { 13 %#include <functional> 14 namespace swig { 15 inline size_t 16 check_index(ptrdiff_t i, size_t size, bool insert = false) { 17 if ( i < 0 ) { 18 if ((size_t) (-i) <= size) 19 return (size_t) (i + size); 20 } else if ( (size_t) i < size ) { 21 return (size_t) i; 22 } else if (insert && ((size_t) i == size)) { 23 return size; 24 } 25 26 throw std::out_of_range("index out of range"); 27 } 28 29 inline size_t 30 slice_index(ptrdiff_t i, size_t size) { 31 if ( i < 0 ) { 32 if ((size_t) (-i) <= size) { 33 return (size_t) (i + size); 34 } else { 35 throw std::out_of_range("index out of range"); 36 } 37 } else { 38 return ( (size_t) i < size ) ? ((size_t) i) : size; 39 } 40 } 41 42 template <class Sequence, class Difference> 43 inline typename Sequence::iterator 44 getpos(Sequence* self, Difference i) { 45 typename Sequence::iterator pos = self->begin(); 46 std::advance(pos, check_index(i,self->size())); 47 return pos; 48 } 49 50 template <class Sequence, class Difference> 51 inline typename Sequence::const_iterator 52 cgetpos(const Sequence* self, Difference i) { 53 typename Sequence::const_iterator pos = self->begin(); 54 std::advance(pos, check_index(i,self->size())); 55 return pos; 56 } 57 58 template <class Sequence, class Difference> 59 inline Sequence* 60 getslice(const Sequence* self, Difference i, Difference j) { 61 typename Sequence::size_type size = self->size(); 62 typename Sequence::size_type ii = swig::check_index(i, size); 63 typename Sequence::size_type jj = swig::slice_index(j, size); 64 65 if (jj > ii) { 66 typename Sequence::const_iterator vb = self->begin(); 67 typename Sequence::const_iterator ve = self->begin(); 68 std::advance(vb,ii); 69 std::advance(ve,jj); 70 return new Sequence(vb, ve); 71 } else { 72 return new Sequence(); 73 } 74 } 75 76 template <class Sequence, class Difference, class InputSeq> 77 inline void 78 setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { 79 typename Sequence::size_type size = self->size(); 80 typename Sequence::size_type ii = swig::check_index(i, size, true); 81 typename Sequence::size_type jj = swig::slice_index(j, size); 82 if (jj < ii) jj = ii; 83 size_t ssize = jj - ii; 84 if (ssize <= v.size()) { 85 typename Sequence::iterator sb = self->begin(); 86 typename InputSeq::const_iterator vmid = v.begin(); 87 std::advance(sb,ii); 88 std::advance(vmid, jj - ii); 89 self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); 90 } else { 91 typename Sequence::iterator sb = self->begin(); 92 typename Sequence::iterator se = self->begin(); 93 std::advance(sb,ii); 94 std::advance(se,jj); 95 self->erase(sb,se); 96 self->insert(sb, v.begin(), v.end()); 97 } 98 } 99 100 template <class Sequence, class Difference> 101 inline void 102 delslice(Sequence* self, Difference i, Difference j) { 103 typename Sequence::size_type size = self->size(); 104 typename Sequence::size_type ii = swig::check_index(i, size, true); 105 typename Sequence::size_type jj = swig::slice_index(j, size); 106 if (jj > ii) { 107 typename Sequence::iterator sb = self->begin(); 108 typename Sequence::iterator se = self->begin(); 109 std::advance(sb,ii); 110 std::advance(se,jj); 111 self->erase(sb,se); 112 } 113 } 114 } 115 } 116 117 %define %swig_container_methods(Container...) 118 119 %newobject __getslice__; 120 121 %extend { 122 bool __nonzero__() const { 123 return !(self->empty()); 124 } 125 126 size_type __len__() const { 127 return self->size(); 128 } 129 } 130 %enddef 131 132 %define %swig_sequence_methods_common(Sequence...) 133 // %swig_sequence_iterator(%arg(Sequence)) 134 %swig_container_methods(%arg(Sequence)) 135 136 %fragment("StdSequenceTraits"); 137 138 %extend { 139 value_type pop() throw (std::out_of_range) { 140 if (self->size() == 0) 141 throw std::out_of_range("pop from empty container"); 142 Sequence::value_type x = self->back(); 143 self->pop_back(); 144 return x; 145 } 146 147 Sequence* __getslice__(difference_type i, difference_type j) throw (std::out_of_range) { 148 return swig::getslice(self, i, j); 149 } 150 151 void __setslice__(difference_type i, difference_type j, const Sequence& v) 152 throw (std::out_of_range, std::invalid_argument) { 153 swig::setslice(self, i, j, v); 154 } 155 156 void __delslice__(difference_type i, difference_type j) throw (std::out_of_range) { 157 swig::delslice(self, i, j); 158 } 159 160 void __delitem__(difference_type i) throw (std::out_of_range) { 161 self->erase(swig::getpos(self,i)); 162 } 163 } 164 %enddef 165 166 %define %swig_sequence_methods(Sequence...) 167 %swig_sequence_methods_common(%arg(Sequence)) 168 %extend { 169 const value_type& __getitem__(difference_type i) const throw (std::out_of_range) { 170 return *(swig::cgetpos(self, i)); 171 } 172 173 void __setitem__(difference_type i, const value_type& x) throw (std::out_of_range) { 174 *(swig::getpos(self,i)) = x; 175 } 176 177 void append(const value_type& x) { 178 self->push_back(x); 179 } 180 } 181 %enddef 182 183 %define %swig_sequence_methods_val(Sequence...) 184 %swig_sequence_methods_common(%arg(Sequence)) 185 %extend { 186 value_type __getitem__(difference_type i) throw (std::out_of_range) { 187 return *(swig::cgetpos(self, i)); 188 } 189 190 void __setitem__(difference_type i, value_type x) throw (std::out_of_range) { 191 *(swig::getpos(self,i)) = x; 192 } 193 194 void append(value_type x) { 195 self->push_back(x); 196 } 197 } 198 %enddef 199