~ubuntu-branches/ubuntu/quantal/swig2.0/quantal

« back to all changes in this revision

Viewing changes to Lib/python/pycontainer.swg

  • Committer: Package Import Robot
  • Author(s): Stefano Rivera
  • Date: 2012-06-01 17:05:17 UTC
  • mfrom: (1.1.6) (10.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120601170517-q0ik32ij61i4r6f0
Tags: 2.0.7-2ubuntu1
* Merge from Debian unstable (LP: #1006387). Remaining changes:
  - Drop libchicken-dev from the build-depends (in universe).

Show diffs side-by-side

added added

removed removed

Lines of Context:
104
104
105
105
}
106
106
 
107
 
%fragment("SwigPySequence_Base","header")
 
107
%fragment("SwigPySequence_Base","header",fragment="<stddef.h>")
108
108
{
109
109
%#include <functional>
110
110
 
188
188
}
189
189
 
190
190
namespace swig {
 
191
  template <class Difference>
191
192
  inline size_t
192
 
  check_index(ptrdiff_t i, size_t size, bool insert = false) {
 
193
  check_index(Difference i, size_t size, bool insert = false) {
193
194
    if ( i < 0 ) {
194
195
      if ((size_t) (-i) <= size)
195
196
        return (size_t) (i + size);
198
199
    } else if (insert && ((size_t) i == size)) {
199
200
      return size;
200
201
    }
201
 
    
202
202
    throw std::out_of_range("index out of range");
203
203
  }
204
204
 
205
 
  inline size_t
206
 
  slice_index(ptrdiff_t i, size_t size) {
207
 
    if ( i < 0 ) {
208
 
      if ((size_t) (-i) <= size) {
209
 
        return (size_t) (i + size);
 
205
  template <class Difference>
 
206
  void
 
207
  slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) {
 
208
    if (step == 0) {
 
209
      throw std::invalid_argument("slice step cannot be zero");
 
210
    } else if (step > 0) {
 
211
      // Required range: 0 <= i < size, 0 <= j < size
 
212
      if (i < 0) {
 
213
        ii = 0;
 
214
      } else if (i < (Difference)size) {
 
215
        ii = i;
 
216
      } else if (insert && (i >= (Difference)size)) {
 
217
        ii = (Difference)size;
 
218
      }
 
219
      if ( j < 0 ) {
 
220
        jj = 0;
210
221
      } else {
211
 
        throw std::out_of_range("index out of range");
 
222
        jj = (j < (Difference)size) ? j : (Difference)size;
212
223
      }
213
224
    } else {
214
 
      return ( (size_t) i < size ) ? ((size_t) i) : size;
 
225
      // Required range: -1 <= i < size-1, -1 <= j < size-1
 
226
      if (i < -1) {
 
227
        ii = -1;
 
228
      } else if (i < (Difference) size) {
 
229
        ii = i;
 
230
      } else if (i >= (Difference)(size-1)) {
 
231
        ii = (Difference)(size-1);
 
232
      }
 
233
      if (j < -1) {
 
234
        jj = -1;
 
235
      } else {
 
236
        jj = (j < (Difference)size ) ? j : (Difference)(size-1);
 
237
      }
215
238
    }
216
239
  }
217
240
 
233
256
 
234
257
  template <class Sequence, class Difference>
235
258
  inline Sequence*
236
 
  getslice(const Sequence* self, Difference i, Difference j) {
 
259
  getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
237
260
    typename Sequence::size_type size = self->size();
238
 
    typename Sequence::size_type ii = swig::check_index(i, size);
239
 
    typename Sequence::size_type jj = swig::slice_index(j, size);
 
261
    Difference ii = 0;
 
262
    Difference jj = 0;
 
263
    swig::slice_adjust(i, j, step, size, ii, jj);
240
264
 
241
 
    if (jj > ii) {
242
 
      typename Sequence::const_iterator vb = self->begin();
243
 
      typename Sequence::const_iterator ve = self->begin();
244
 
      std::advance(vb,ii);
245
 
      std::advance(ve,jj);
246
 
      return new Sequence(vb, ve);
 
265
    if (step > 0) {
 
266
      typename Sequence::const_iterator sb = self->begin();
 
267
      typename Sequence::const_iterator se = self->begin();
 
268
      std::advance(sb,ii);
 
269
      std::advance(se,jj);
 
270
      if (step == 1) {
 
271
        return new Sequence(sb, se);
 
272
      } else {
 
273
        Sequence *sequence = new Sequence();
 
274
        typename Sequence::const_iterator it = sb;
 
275
        while (it!=se) {
 
276
          sequence->push_back(*it);
 
277
          for (Py_ssize_t c=0; c<step && it!=se; ++c)
 
278
            it++;
 
279
        }
 
280
        return sequence;
 
281
      } 
247
282
    } else {
248
 
      return new Sequence();
 
283
      Sequence *sequence = new Sequence();
 
284
      if (ii > jj) {
 
285
        typename Sequence::const_reverse_iterator sb = self->rbegin();
 
286
        typename Sequence::const_reverse_iterator se = self->rbegin();
 
287
        std::advance(sb,size-ii-1);
 
288
        std::advance(se,size-jj-1);
 
289
        typename Sequence::const_reverse_iterator it = sb;
 
290
        while (it!=se) {
 
291
          sequence->push_back(*it);
 
292
          for (Py_ssize_t c=0; c<-step && it!=se; ++c)
 
293
            it++;
 
294
        }
 
295
      }
 
296
      return sequence;
249
297
    }
250
298
  }
251
299
 
252
300
  template <class Sequence, class Difference, class InputSeq>
253
301
  inline void
254
 
  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v = InputSeq()) {
 
302
  setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) {
255
303
    typename Sequence::size_type size = self->size();
256
 
    typename Sequence::size_type ii = swig::check_index(i, size, true);
257
 
    typename Sequence::size_type jj = swig::slice_index(j, size);
258
 
    if (jj < ii) jj = ii;
259
 
    size_t ssize = jj - ii;
260
 
    if (ssize <= v.size()) {
261
 
      typename Sequence::iterator sb = self->begin();
262
 
      typename InputSeq::const_iterator vmid = v.begin();
263
 
      std::advance(sb,ii);
264
 
      std::advance(vmid, jj - ii);
265
 
      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
 
304
    Difference ii = 0;
 
305
    Difference jj = 0;
 
306
    swig::slice_adjust(i, j, step, size, ii, jj, true);
 
307
    if (step > 0) {
 
308
      if (jj < ii)
 
309
        jj = ii;
 
310
      if (step == 1) {
 
311
        size_t ssize = jj - ii;
 
312
        if (ssize <= is.size()) {
 
313
          // expanding/staying the same size
 
314
          typename Sequence::iterator sb = self->begin();
 
315
          typename InputSeq::const_iterator isit = is.begin();
 
316
          std::advance(sb,ii);
 
317
          std::advance(isit, jj - ii);
 
318
          self->insert(std::copy(is.begin(), isit, sb), isit, is.end());
 
319
        } else {
 
320
          // shrinking
 
321
          typename Sequence::iterator sb = self->begin();
 
322
          typename Sequence::iterator se = self->begin();
 
323
          std::advance(sb,ii);
 
324
          std::advance(se,jj);
 
325
          self->erase(sb,se);
 
326
          sb = self->begin();
 
327
          std::advance(sb,ii);
 
328
          self->insert(sb, is.begin(), is.end());
 
329
        }
 
330
      } else {
 
331
        size_t replacecount = (jj - ii + step - 1) / step;
 
332
        if (is.size() != replacecount) {
 
333
          char msg[1024];
 
334
          sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
 
335
          throw std::invalid_argument(msg);
 
336
        }
 
337
        typename Sequence::const_iterator isit = is.begin();
 
338
        typename Sequence::iterator it = self->begin();
 
339
        std::advance(it,ii);
 
340
        for (size_t rc=0; rc<replacecount; ++rc) {
 
341
          *it++ = *isit++;
 
342
          for (Py_ssize_t c=0; c<(step-1); ++c)
 
343
            it++;
 
344
        }
 
345
      }
266
346
    } else {
267
 
      typename Sequence::iterator sb = self->begin();
268
 
      typename Sequence::iterator se = self->begin();
269
 
      std::advance(sb,ii);
270
 
      std::advance(se,jj);
271
 
      self->erase(sb,se);
272
 
      self->insert(sb, v.begin(), v.end());
 
347
      if (jj > ii)
 
348
        jj = ii;
 
349
      size_t replacecount = (ii - jj - step - 1) / -step;
 
350
      if (is.size() != replacecount) {
 
351
        char msg[1024];
 
352
        sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
 
353
        throw std::invalid_argument(msg);
 
354
      }
 
355
      typename Sequence::const_iterator isit = is.begin();
 
356
      typename Sequence::reverse_iterator it = self->rbegin();
 
357
      std::advance(it,size-ii-1);
 
358
      for (size_t rc=0; rc<replacecount; ++rc) {
 
359
        *it++ = *isit++;
 
360
        for (Py_ssize_t c=0; c<(-step-1); ++c)
 
361
          it++;
 
362
      }
273
363
    }
274
364
  }
275
365
 
276
366
  template <class Sequence, class Difference>
277
367
  inline void
278
 
  delslice(Sequence* self, Difference i, Difference j) {
 
368
  delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) {
279
369
    typename Sequence::size_type size = self->size();
280
 
    typename Sequence::size_type ii = swig::check_index(i, size, true);
281
 
    typename Sequence::size_type jj = swig::slice_index(j, size);
282
 
    if (jj > ii) {
283
 
      typename Sequence::iterator sb = self->begin();
284
 
      typename Sequence::iterator se = self->begin();
285
 
      std::advance(sb,ii);
286
 
      std::advance(se,jj);
287
 
      self->erase(sb,se);
 
370
    Difference ii = 0;
 
371
    Difference jj = 0;
 
372
    swig::slice_adjust(i, j, step, size, ii, jj, true);
 
373
    if (step > 0) {
 
374
      if (jj > ii) {
 
375
        typename Sequence::iterator sb = self->begin();
 
376
        std::advance(sb,ii);
 
377
        if (step == 1) {
 
378
          typename Sequence::iterator se = self->begin();
 
379
          std::advance(se,jj);
 
380
          self->erase(sb,se);
 
381
        } else {
 
382
          typename Sequence::iterator it = sb;
 
383
          size_t delcount = (jj - ii + step - 1) / step;
 
384
          while (delcount) {
 
385
            it = self->erase(it);
 
386
            if (it==self->end())
 
387
              break;
 
388
            for (Py_ssize_t c=0; c<(step-1); ++c)
 
389
              it++;
 
390
            delcount--;
 
391
          }
 
392
        }
 
393
      }
 
394
    } else {
 
395
      if (ii > jj) {
 
396
        typename Sequence::reverse_iterator sb = self->rbegin();
 
397
        std::advance(sb,size-ii-1);
 
398
        typename Sequence::reverse_iterator it = sb;
 
399
        size_t delcount = (ii - jj - step - 1) / -step;
 
400
        while (delcount) {
 
401
          self->erase((++it).base());
 
402
          if (it==self->rend())
 
403
            break;
 
404
          for (Py_ssize_t c=0; c<(-step-1); ++c)
 
405
            it++;
 
406
          delcount--;
 
407
        }
 
408
      }
288
409
    }
289
410
  }
290
411
}
607
728
 
608
729
%define %swig_container_methods(Container...)
609
730
 
 
731
/* deprecated in Python 2 */
 
732
#if 1
610
733
  %newobject __getslice__;
 
734
#endif
 
735
  %newobject __getitem__(PySliceObject *slice);
611
736
 
612
737
#if defined(SWIGPYTHON_BUILTIN)
613
738
  %feature("python:slot", "nb_nonzero", functype="inquiry") __nonzero__;
668
793
      $1 = PySlice_Check($input);
669
794
    }
670
795
 
671
 
    Sequence* __getslice__(difference_type i, difference_type j) throw (std::out_of_range) {
672
 
      return swig::getslice(self, i, j);
673
 
    }
674
 
 
675
 
    void __setslice__(difference_type i, difference_type j, const Sequence& v = Sequence()) 
676
 
      throw (std::out_of_range, std::invalid_argument) {
677
 
      swig::setslice(self, i, j, v);
678
 
    }
679
 
 
680
 
    void __delslice__(difference_type i, difference_type j) throw (std::out_of_range) {
681
 
      swig::delslice(self, i, j);
682
 
    }
 
796
/* deprecated in Python 2 */
 
797
#if 1
 
798
    Sequence* __getslice__(difference_type i, difference_type j) throw (std::out_of_range, std::invalid_argument) {
 
799
      return swig::getslice(self, i, j, 1);
 
800
    }
 
801
 
 
802
    void __setslice__(difference_type i, difference_type j, const Sequence& v = Sequence()) throw (std::out_of_range, std::invalid_argument) {
 
803
      swig::setslice(self, i, j, 1, v);
 
804
    }
 
805
 
 
806
    void __delslice__(difference_type i, difference_type j) throw (std::out_of_range, std::invalid_argument) {
 
807
      swig::delslice(self, i, j, 1);
 
808
    }
 
809
#endif
683
810
 
684
811
    void __delitem__(difference_type i) throw (std::out_of_range) {
685
812
      self->erase(swig::getpos(self,i));
689
816
    /* Overloaded methods for Python 3 compatibility 
690
817
     * (Also useful in Python 2.x)
691
818
     */
692
 
    Sequence* __getitem__(PySliceObject *slice) throw (std::out_of_range) {
 
819
    Sequence* __getitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
693
820
      Py_ssize_t i, j, step;
694
821
      if( !PySlice_Check(slice) ) {
695
822
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
696
823
        return NULL;
697
824
      }
698
 
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), self->size(), &i, &j, &step);
699
 
      return swig::getslice(self, i, j);
700
 
    }
701
 
 
702
 
    void __setitem__(PySliceObject *slice, const Sequence& v)
703
 
      throw (std::out_of_range, std::invalid_argument) {
704
 
      Py_ssize_t i, j, step;
705
 
      if( !PySlice_Check(slice) ) {
706
 
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
707
 
        return;
708
 
      }
709
 
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), self->size(), &i, &j, &step);
710
 
      swig::setslice(self, i, j, v);
711
 
    }
712
 
 
713
 
    void __setitem__(PySliceObject *slice)
714
 
      throw (std::out_of_range) {
715
 
      Py_ssize_t i, j, step;
716
 
      if( !PySlice_Check(slice) ) {
717
 
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
718
 
        return;
719
 
      }
720
 
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), self->size(), &i, &j, &step);
721
 
      swig::delslice(self, i,j);
722
 
    }
723
 
 
724
 
    void __delitem__(PySliceObject *slice)
725
 
      throw (std::out_of_range) {
726
 
      Py_ssize_t i, j, step;
727
 
      if( !PySlice_Check(slice) ) {
728
 
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
729
 
        return;
730
 
      }
731
 
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), self->size(), &i, &j, &step);
732
 
      swig::delslice(self, i,j);
 
825
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
 
826
      Sequence::difference_type id = i;
 
827
      Sequence::difference_type jd = j;
 
828
      return swig::getslice(self, id, jd, step);
 
829
    }
 
830
 
 
831
    void __setitem__(PySliceObject *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) {
 
832
      Py_ssize_t i, j, step;
 
833
      if( !PySlice_Check(slice) ) {
 
834
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
 
835
        return;
 
836
      }
 
837
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
 
838
      Sequence::difference_type id = i;
 
839
      Sequence::difference_type jd = j;
 
840
      swig::setslice(self, id, jd, step, v);
 
841
    }
 
842
 
 
843
    void __setitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
 
844
      Py_ssize_t i, j, step;
 
845
      if( !PySlice_Check(slice) ) {
 
846
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
 
847
        return;
 
848
      }
 
849
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
 
850
      Sequence::difference_type id = i;
 
851
      Sequence::difference_type jd = j;
 
852
      swig::delslice(self, id, jd, step);
 
853
    }
 
854
 
 
855
    void __delitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
 
856
      Py_ssize_t i, j, step;
 
857
      if( !PySlice_Check(slice) ) {
 
858
        SWIG_Error(SWIG_TypeError, "Slice object expected.");
 
859
        return;
 
860
      }
 
861
      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
 
862
      Sequence::difference_type id = i;
 
863
      Sequence::difference_type jd = j;
 
864
      swig::delslice(self, id, jd, step);
733
865
    }
734
866
     
735
867
  }