PageRenderTime 32ms CodeModel.GetById 23ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Lib/r/rcontainer.swg

#
Unknown | 198 lines | 167 code | 31 blank | 0 comment | 0 complexity | 0562d2df05211e2db8f8630cc5e375d7 MD5 | raw file
  1
  2//
  3// Common fragments
  4//
  5
  6
  7/**** The python container methods  ****/
  8
  9
 10
 11%fragment("RSequence_Base","header",fragment="<stddef.h>")
 12{
 13%#include <functional>
 14namespace 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("RSequence_Base");
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