OLD | NEW |
(Empty) | |
| 1 /* ----------------------------------------------------------------------------- |
| 2 * See the LICENSE file for information on copyright, usage and redistribution |
| 3 * of SWIG, and the README file for authors - http://www.swig.org/release.html. |
| 4 * |
| 5 * pycontainer.swg |
| 6 * |
| 7 * Python sequence <-> C++ container wrapper |
| 8 * |
| 9 * This wrapper, and its iterator, allows a general use (and reuse) of |
| 10 * the the mapping between C++ and Python, thanks to the C++ |
| 11 * templates. |
| 12 * |
| 13 * Of course, it needs the C++ compiler to support templates, but |
| 14 * since we will use this wrapper with the STL containers, that should |
| 15 * be the case. |
| 16 * -----------------------------------------------------------------------------
*/ |
| 17 |
| 18 %{ |
| 19 #include <iostream> |
| 20 %} |
| 21 |
| 22 |
| 23 #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS) |
| 24 # if !defined(SWIG_EXPORT_ITERATOR_METHODS) |
| 25 # define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS |
| 26 # endif |
| 27 #endif |
| 28 |
| 29 %include <pyiterators.swg> |
| 30 |
| 31 /**** The PySequence C++ Wrap ***/ |
| 32 |
| 33 %insert(header) %{ |
| 34 #include <stdexcept> |
| 35 %} |
| 36 |
| 37 %include <std_except.i> |
| 38 |
| 39 %fragment(SWIG_Traits_frag(swig::SwigPtr_PyObject),"header",fragment="StdTraits"
) { |
| 40 namespace swig { |
| 41 template <> struct traits<SwigPtr_PyObject > { |
| 42 typedef value_category category; |
| 43 static const char* type_name() { return "SwigPtr_PyObject"; } |
| 44 }; |
| 45 |
| 46 template <> struct traits_from<SwigPtr_PyObject> { |
| 47 typedef SwigPtr_PyObject value_type; |
| 48 static PyObject *from(const value_type& val) { |
| 49 PyObject *obj = static_cast<PyObject *>(val); |
| 50 Py_XINCREF(obj); |
| 51 return obj; |
| 52 } |
| 53 }; |
| 54 |
| 55 template <> |
| 56 struct traits_check<SwigPtr_PyObject, value_category> { |
| 57 static bool check(SwigPtr_PyObject) { |
| 58 return true; |
| 59 } |
| 60 }; |
| 61 |
| 62 template <> struct traits_asval<SwigPtr_PyObject > { |
| 63 typedef SwigPtr_PyObject value_type; |
| 64 static int asval(PyObject *obj, value_type *val) { |
| 65 if (val) *val = obj; |
| 66 return SWIG_OK; |
| 67 } |
| 68 }; |
| 69 } |
| 70 } |
| 71 |
| 72 %fragment(SWIG_Traits_frag(swig::SwigVar_PyObject),"header",fragment="StdTraits"
) { |
| 73 namespace swig { |
| 74 template <> struct traits<SwigVar_PyObject > { |
| 75 typedef value_category category; |
| 76 static const char* type_name() { return "SwigVar_PyObject"; } |
| 77 }; |
| 78 |
| 79 template <> struct traits_from<SwigVar_PyObject> { |
| 80 typedef SwigVar_PyObject value_type; |
| 81 static PyObject *from(const value_type& val) { |
| 82 PyObject *obj = static_cast<PyObject *>(val); |
| 83 Py_XINCREF(obj); |
| 84 return obj; |
| 85 } |
| 86 }; |
| 87 |
| 88 template <> |
| 89 struct traits_check<SwigVar_PyObject, value_category> { |
| 90 static bool check(SwigVar_PyObject) { |
| 91 return true; |
| 92 } |
| 93 }; |
| 94 |
| 95 template <> struct traits_asval<SwigVar_PyObject > { |
| 96 typedef SwigVar_PyObject value_type; |
| 97 static int asval(PyObject *obj, value_type *val) { |
| 98 if (val) *val = obj; |
| 99 return SWIG_OK; |
| 100 } |
| 101 }; |
| 102 } |
| 103 } |
| 104 |
| 105 %fragment("SwigPySequence_Base","header") |
| 106 { |
| 107 %#include <functional> |
| 108 |
| 109 namespace std { |
| 110 template <> |
| 111 struct less <PyObject *>: public binary_function<PyObject *, PyObject *, bool> |
| 112 { |
| 113 bool |
| 114 operator()(PyObject * v, PyObject *w) const |
| 115 { |
| 116 bool res; |
| 117 SWIG_PYTHON_THREAD_BEGIN_BLOCK; |
| 118 res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false; |
| 119 /* This may fall into a case of inconsistent |
| 120 eg. ObjA > ObjX > ObjB |
| 121 but ObjA < ObjB |
| 122 */ |
| 123 if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) ) |
| 124 { |
| 125 /* Objects can't be compared, this mostly occurred in Python 3.0 */ |
| 126 /* Compare their ptr directly for a workaround */ |
| 127 res = (v < w); |
| 128 PyErr_Clear(); |
| 129 } |
| 130 SWIG_PYTHON_THREAD_END_BLOCK; |
| 131 return res; |
| 132 } |
| 133 }; |
| 134 |
| 135 template <> |
| 136 struct less <swig::SwigPtr_PyObject>: public binary_function<swig::SwigPtr_PyO
bject, swig::SwigPtr_PyObject, bool> |
| 137 { |
| 138 bool |
| 139 operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w)
const |
| 140 { |
| 141 return std::less<PyObject *>()(v, w); |
| 142 } |
| 143 }; |
| 144 |
| 145 template <> |
| 146 struct less <swig::SwigVar_PyObject>: public binary_function<swig::SwigVar_PyO
bject, swig::SwigVar_PyObject, bool> |
| 147 { |
| 148 bool |
| 149 operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w)
const |
| 150 { |
| 151 return std::less<PyObject *>()(v, w); |
| 152 } |
| 153 }; |
| 154 |
| 155 } |
| 156 |
| 157 namespace swig { |
| 158 template <> struct traits<PyObject *> { |
| 159 typedef value_category category; |
| 160 static const char* type_name() { return "PyObject *"; } |
| 161 }; |
| 162 |
| 163 template <> struct traits_asval<PyObject * > { |
| 164 typedef PyObject * value_type; |
| 165 static int asval(PyObject *obj, value_type *val) { |
| 166 if (val) *val = obj; |
| 167 return SWIG_OK; |
| 168 } |
| 169 }; |
| 170 |
| 171 template <> |
| 172 struct traits_check<PyObject *, value_category> { |
| 173 static bool check(PyObject *) { |
| 174 return true; |
| 175 } |
| 176 }; |
| 177 |
| 178 template <> struct traits_from<PyObject *> { |
| 179 typedef PyObject * value_type; |
| 180 static PyObject *from(const value_type& val) { |
| 181 Py_XINCREF(val); |
| 182 return val; |
| 183 } |
| 184 }; |
| 185 |
| 186 } |
| 187 |
| 188 namespace swig { |
| 189 inline size_t |
| 190 check_index(ptrdiff_t i, size_t size, bool insert = false) { |
| 191 if ( i < 0 ) { |
| 192 if ((size_t) (-i) <= size) |
| 193 return (size_t) (i + size); |
| 194 } else if ( (size_t) i < size ) { |
| 195 return (size_t) i; |
| 196 } else if (insert && ((size_t) i == size)) { |
| 197 return size; |
| 198 } |
| 199 |
| 200 throw std::out_of_range("index out of range"); |
| 201 } |
| 202 |
| 203 inline size_t |
| 204 slice_index(ptrdiff_t i, size_t size) { |
| 205 if ( i < 0 ) { |
| 206 if ((size_t) (-i) <= size) { |
| 207 return (size_t) (i + size); |
| 208 } else { |
| 209 throw std::out_of_range("index out of range"); |
| 210 } |
| 211 } else { |
| 212 return ( (size_t) i < size ) ? ((size_t) i) : size; |
| 213 } |
| 214 } |
| 215 |
| 216 template <class Sequence, class Difference> |
| 217 inline typename Sequence::iterator |
| 218 getpos(Sequence* self, Difference i) { |
| 219 typename Sequence::iterator pos = self->begin(); |
| 220 std::advance(pos, check_index(i,self->size())); |
| 221 return pos; |
| 222 } |
| 223 |
| 224 template <class Sequence, class Difference> |
| 225 inline typename Sequence::const_iterator |
| 226 cgetpos(const Sequence* self, Difference i) { |
| 227 typename Sequence::const_iterator pos = self->begin(); |
| 228 std::advance(pos, check_index(i,self->size())); |
| 229 return pos; |
| 230 } |
| 231 |
| 232 template <class Sequence, class Difference> |
| 233 inline Sequence* |
| 234 getslice(const Sequence* self, Difference i, Difference j) { |
| 235 typename Sequence::size_type size = self->size(); |
| 236 typename Sequence::size_type ii = swig::check_index(i, size); |
| 237 typename Sequence::size_type jj = swig::slice_index(j, size); |
| 238 |
| 239 if (jj > ii) { |
| 240 typename Sequence::const_iterator vb = self->begin(); |
| 241 typename Sequence::const_iterator ve = self->begin(); |
| 242 std::advance(vb,ii); |
| 243 std::advance(ve,jj); |
| 244 return new Sequence(vb, ve); |
| 245 } else { |
| 246 return new Sequence(); |
| 247 } |
| 248 } |
| 249 |
| 250 template <class Sequence, class Difference, class InputSeq> |
| 251 inline void |
| 252 setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { |
| 253 typename Sequence::size_type size = self->size(); |
| 254 typename Sequence::size_type ii = swig::check_index(i, size, true); |
| 255 typename Sequence::size_type jj = swig::slice_index(j, size); |
| 256 if (jj < ii) jj = ii; |
| 257 size_t ssize = jj - ii; |
| 258 if (ssize <= v.size()) { |
| 259 typename Sequence::iterator sb = self->begin(); |
| 260 typename InputSeq::const_iterator vmid = v.begin(); |
| 261 std::advance(sb,ii); |
| 262 std::advance(vmid, jj - ii); |
| 263 self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); |
| 264 } else { |
| 265 typename Sequence::iterator sb = self->begin(); |
| 266 typename Sequence::iterator se = self->begin(); |
| 267 std::advance(sb,ii); |
| 268 std::advance(se,jj); |
| 269 self->erase(sb,se); |
| 270 self->insert(sb, v.begin(), v.end()); |
| 271 } |
| 272 } |
| 273 |
| 274 template <class Sequence, class Difference> |
| 275 inline void |
| 276 delslice(Sequence* self, Difference i, Difference j) { |
| 277 typename Sequence::size_type size = self->size(); |
| 278 typename Sequence::size_type ii = swig::check_index(i, size, true); |
| 279 typename Sequence::size_type jj = swig::slice_index(j, size); |
| 280 if (jj > ii) { |
| 281 typename Sequence::iterator sb = self->begin(); |
| 282 typename Sequence::iterator se = self->begin(); |
| 283 std::advance(sb,ii); |
| 284 std::advance(se,jj); |
| 285 self->erase(sb,se); |
| 286 } |
| 287 } |
| 288 } |
| 289 } |
| 290 |
| 291 %fragment("SwigPySequence_Cont","header", |
| 292 fragment="StdTraits", |
| 293 fragment="SwigPySequence_Base", |
| 294 fragment="SwigPyIterator_T") |
| 295 { |
| 296 namespace swig |
| 297 { |
| 298 template <class T> |
| 299 struct SwigPySequence_Ref |
| 300 { |
| 301 SwigPySequence_Ref(PyObject* seq, int index) |
| 302 : _seq(seq), _index(index) |
| 303 { |
| 304 } |
| 305 |
| 306 operator T () const |
| 307 { |
| 308 swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index); |
| 309 try { |
| 310 return swig::as<T>(item, true); |
| 311 } catch (std::exception& e) { |
| 312 char msg[1024]; |
| 313 sprintf(msg, "in sequence element %d ", _index); |
| 314 if (!PyErr_Occurred()) { |
| 315 ::%type_error(swig::type_name<T>()); |
| 316 } |
| 317 SWIG_Python_AddErrorMsg(msg); |
| 318 SWIG_Python_AddErrorMsg(e.what()); |
| 319 throw; |
| 320 } |
| 321 } |
| 322 |
| 323 SwigPySequence_Ref& operator=(const T& v) |
| 324 { |
| 325 PySequence_SetItem(_seq, _index, swig::from<T>(v)); |
| 326 return *this; |
| 327 } |
| 328 |
| 329 private: |
| 330 PyObject* _seq; |
| 331 int _index; |
| 332 }; |
| 333 |
| 334 template <class T> |
| 335 struct SwigPySequence_ArrowProxy |
| 336 { |
| 337 SwigPySequence_ArrowProxy(const T& x): m_value(x) {} |
| 338 const T* operator->() const { return &m_value; } |
| 339 operator const T*() const { return &m_value; } |
| 340 T m_value; |
| 341 }; |
| 342 |
| 343 template <class T, class Reference > |
| 344 struct SwigPySequence_InputIterator |
| 345 { |
| 346 typedef SwigPySequence_InputIterator<T, Reference > self; |
| 347 |
| 348 typedef std::random_access_iterator_tag iterator_category; |
| 349 typedef Reference reference; |
| 350 typedef T value_type; |
| 351 typedef T* pointer; |
| 352 typedef int difference_type; |
| 353 |
| 354 SwigPySequence_InputIterator() |
| 355 { |
| 356 } |
| 357 |
| 358 SwigPySequence_InputIterator(PyObject* seq, int index) |
| 359 : _seq(seq), _index(index) |
| 360 { |
| 361 } |
| 362 |
| 363 reference operator*() const |
| 364 { |
| 365 return reference(_seq, _index); |
| 366 } |
| 367 |
| 368 SwigPySequence_ArrowProxy<T> |
| 369 operator->() const { |
| 370 return SwigPySequence_ArrowProxy<T>(operator*()); |
| 371 } |
| 372 |
| 373 bool operator==(const self& ri) const |
| 374 { |
| 375 return (_index == ri._index) && (_seq == ri._seq); |
| 376 } |
| 377 |
| 378 bool operator!=(const self& ri) const |
| 379 { |
| 380 return !(operator==(ri)); |
| 381 } |
| 382 |
| 383 self& operator ++ () |
| 384 { |
| 385 ++_index; |
| 386 return *this; |
| 387 } |
| 388 |
| 389 self& operator -- () |
| 390 { |
| 391 --_index; |
| 392 return *this; |
| 393 } |
| 394 |
| 395 self& operator += (difference_type n) |
| 396 { |
| 397 _index += n; |
| 398 return *this; |
| 399 } |
| 400 |
| 401 self operator +(difference_type n) const |
| 402 { |
| 403 return self(_seq, _index + n); |
| 404 } |
| 405 |
| 406 self& operator -= (difference_type n) |
| 407 { |
| 408 _index -= n; |
| 409 return *this; |
| 410 } |
| 411 |
| 412 self operator -(difference_type n) const |
| 413 { |
| 414 return self(_seq, _index - n); |
| 415 } |
| 416 |
| 417 difference_type operator - (const self& ri) const |
| 418 { |
| 419 return _index - ri._index; |
| 420 } |
| 421 |
| 422 bool operator < (const self& ri) const |
| 423 { |
| 424 return _index < ri._index; |
| 425 } |
| 426 |
| 427 reference |
| 428 operator[](difference_type n) const |
| 429 { |
| 430 return reference(_seq, _index + n); |
| 431 } |
| 432 |
| 433 private: |
| 434 PyObject* _seq; |
| 435 difference_type _index; |
| 436 }; |
| 437 |
| 438 template <class T> |
| 439 struct SwigPySequence_Cont |
| 440 { |
| 441 typedef SwigPySequence_Ref<T> reference; |
| 442 typedef const SwigPySequence_Ref<T> const_reference; |
| 443 typedef T value_type; |
| 444 typedef T* pointer; |
| 445 typedef int difference_type; |
| 446 typedef int size_type; |
| 447 typedef const pointer const_pointer; |
| 448 typedef SwigPySequence_InputIterator<T, reference> iterator; |
| 449 typedef SwigPySequence_InputIterator<T, const_reference> const_iterator; |
| 450 |
| 451 SwigPySequence_Cont(PyObject* seq) : _seq(0) |
| 452 { |
| 453 if (!PySequence_Check(seq)) { |
| 454 throw std::invalid_argument("a sequence is expected"); |
| 455 } |
| 456 _seq = seq; |
| 457 Py_INCREF(_seq); |
| 458 } |
| 459 |
| 460 ~SwigPySequence_Cont() |
| 461 { |
| 462 Py_XDECREF(_seq); |
| 463 } |
| 464 |
| 465 size_type size() const |
| 466 { |
| 467 return static_cast<size_type>(PySequence_Size(_seq)); |
| 468 } |
| 469 |
| 470 bool empty() const |
| 471 { |
| 472 return size() == 0; |
| 473 } |
| 474 |
| 475 iterator begin() |
| 476 { |
| 477 return iterator(_seq, 0); |
| 478 } |
| 479 |
| 480 const_iterator begin() const |
| 481 { |
| 482 return const_iterator(_seq, 0); |
| 483 } |
| 484 |
| 485 iterator end() |
| 486 { |
| 487 return iterator(_seq, size()); |
| 488 } |
| 489 |
| 490 const_iterator end() const |
| 491 { |
| 492 return const_iterator(_seq, size()); |
| 493 } |
| 494 |
| 495 reference operator[](difference_type n) |
| 496 { |
| 497 return reference(_seq, n); |
| 498 } |
| 499 |
| 500 const_reference operator[](difference_type n) const |
| 501 { |
| 502 return const_reference(_seq, n); |
| 503 } |
| 504 |
| 505 bool check(bool set_err = true) const |
| 506 { |
| 507 int s = size(); |
| 508 for (int i = 0; i < s; ++i) { |
| 509 swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i); |
| 510 if (!swig::check<value_type>(item)) { |
| 511 if (set_err) { |
| 512 char msg[1024]; |
| 513 sprintf(msg, "in sequence element %d", i); |
| 514 SWIG_Error(SWIG_RuntimeError, msg); |
| 515 } |
| 516 return false; |
| 517 } |
| 518 } |
| 519 return true; |
| 520 } |
| 521 |
| 522 private: |
| 523 PyObject* _seq; |
| 524 }; |
| 525 |
| 526 } |
| 527 } |
| 528 |
| 529 %define %swig_sequence_iterator(Sequence...) |
| 530 #if defined(SWIG_EXPORT_ITERATOR_METHODS) |
| 531 class iterator; |
| 532 class reverse_iterator; |
| 533 class const_iterator; |
| 534 class const_reverse_iterator; |
| 535 |
| 536 %typemap(out,noblock=1,fragment="SwigPySequence_Cont") |
| 537 iterator, reverse_iterator, const_iterator, const_reverse_iterator { |
| 538 $result = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,cons
t $type &)), |
| 539 swig::SwigPyIterator::descriptor(),SWIG_POINTER
_OWN); |
| 540 } |
| 541 %typemap(out,noblock=1,fragment="SwigPySequence_Cont") |
| 542 std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> { |
| 543 $result = PyTuple_New(2); |
| 544 PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%sta
tic_cast($1,const $type &).first), |
| 545 swig::SwigPyIterator::descripto
r(),SWIG_POINTER_OWN)); |
| 546 PyTuple_SetItem($result,1,SWIG_NewPointerObj(swig::make_output_iterator(%sta
tic_cast($1,const $type &).second), |
| 547 swig::SwigPyIterator::descripto
r(),SWIG_POINTER_OWN)); |
| 548 } |
| 549 |
| 550 %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool
),fragment="SwigPySequence_Cont") {} |
| 551 |
| 552 %typemap(out,noblock=1,fragment="SwigPyPairBoolOutputIterator") |
| 553 std::pair<iterator, bool>, std::pair<const_iterator, bool> { |
| 554 $result = PyTuple_New(2); |
| 555 PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%sta
tic_cast($1,const $type &).first), |
| 556 swig::SwigPyIterator::descriptor(
),SWIG_POINTER_OWN)); |
| 557 PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).sec
ond)); |
| 558 } |
| 559 |
| 560 %typemap(in,noblock=1,fragment="SwigPySequence_Cont") |
| 561 iterator(swig::SwigPyIterator *iter = 0, int res), |
| 562 reverse_iterator(swig::SwigPyIterator *iter = 0, int res), |
| 563 const_iterator(swig::SwigPyIterator *iter = 0, int res), |
| 564 const_reverse_iterator(swig::SwigPyIterator *iter = 0, int res) { |
| 565 res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterator::d
escriptor(), 0); |
| 566 if (!SWIG_IsOK(res) || !iter) { |
| 567 %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); |
| 568 } else { |
| 569 swig::SwigPyIterator_T<$type > *iter_t = dynamic_cast<swig::SwigPyIterator
_T<$type > *>(iter); |
| 570 if (iter_t) { |
| 571 $1 = iter_t->get_current(); |
| 572 } else { |
| 573 %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); |
| 574 } |
| 575 } |
| 576 } |
| 577 |
| 578 %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPySequence_Cont") |
| 579 iterator, reverse_iterator, const_iterator, const_reverse_iterator { |
| 580 swig::SwigPyIterator *iter = 0; |
| 581 int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterato
r::descriptor(), 0); |
| 582 $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<$type >
*>(iter) != 0)); |
| 583 } |
| 584 |
| 585 %fragment("SwigPySequence_Cont"); |
| 586 |
| 587 %newobject iterator(PyObject **PYTHON_SELF); |
| 588 %extend { |
| 589 swig::SwigPyIterator* iterator(PyObject **PYTHON_SELF) { |
| 590 return swig::make_output_iterator(self->begin(), self->begin(), self->end(
), *PYTHON_SELF); |
| 591 } |
| 592 |
| 593 %pythoncode {def __iter__(self): return self.iterator()} |
| 594 } |
| 595 #endif //SWIG_EXPORT_ITERATOR_METHODS |
| 596 %enddef |
| 597 |
| 598 |
| 599 /**** The python container methods ****/ |
| 600 |
| 601 |
| 602 %define %swig_container_methods(Container...) |
| 603 |
| 604 %newobject __getslice__; |
| 605 |
| 606 %extend { |
| 607 bool __nonzero__() const { |
| 608 return !(self->empty()); |
| 609 } |
| 610 |
| 611 /* Alias for Python 3 compatibility */ |
| 612 bool __bool__() const { |
| 613 return !(self->empty()); |
| 614 } |
| 615 |
| 616 size_type __len__() const { |
| 617 return self->size(); |
| 618 } |
| 619 } |
| 620 %enddef |
| 621 |
| 622 %define %swig_sequence_methods_common(Sequence...) |
| 623 %swig_sequence_iterator(%arg(Sequence)) |
| 624 %swig_container_methods(%arg(Sequence)) |
| 625 |
| 626 %fragment("SwigPySequence_Base"); |
| 627 |
| 628 %extend { |
| 629 value_type pop() throw (std::out_of_range) { |
| 630 if (self->size() == 0) |
| 631 throw std::out_of_range("pop from empty container"); |
| 632 Sequence::value_type x = self->back(); |
| 633 self->pop_back(); |
| 634 return x; |
| 635 } |
| 636 |
| 637 /* typemap for slice object support */ |
| 638 %typemap(in) PySliceObject* { |
| 639 $1 = (PySliceObject *) $input; |
| 640 } |
| 641 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) PySliceObject* { |
| 642 $1 = PySlice_Check($input); |
| 643 } |
| 644 |
| 645 Sequence* __getslice__(difference_type i, difference_type j) throw (std::out
_of_range) { |
| 646 return swig::getslice(self, i, j); |
| 647 } |
| 648 |
| 649 void __setslice__(difference_type i, difference_type j, const Sequence& v) |
| 650 throw (std::out_of_range, std::invalid_argument) { |
| 651 swig::setslice(self, i, j, v); |
| 652 } |
| 653 |
| 654 void __delslice__(difference_type i, difference_type j) throw (std::out_of_r
ange) { |
| 655 swig::delslice(self, i, j); |
| 656 } |
| 657 |
| 658 void __delitem__(difference_type i) throw (std::out_of_range) { |
| 659 self->erase(swig::getpos(self,i)); |
| 660 } |
| 661 |
| 662 |
| 663 /* Overloaded methods for Python 3 compatibility |
| 664 * (Also useful in Python 2.x) |
| 665 */ |
| 666 Sequence* __getitem__(PySliceObject *slice) throw (std::out_of_range) { |
| 667 Py_ssize_t i, j, step; |
| 668 if( !PySlice_Check(slice) ) { |
| 669 SWIG_Error(SWIG_TypeError, "Slice object expected."); |
| 670 return NULL; |
| 671 } |
| 672 PySlice_GetIndices(slice, self->size(), &i, &j, &step); |
| 673 return swig::getslice(self, i, j); |
| 674 } |
| 675 |
| 676 void __setitem__(PySliceObject *slice, const Sequence& v) |
| 677 throw (std::out_of_range, std::invalid_argument) { |
| 678 Py_ssize_t i, j, step; |
| 679 if( !PySlice_Check(slice) ) { |
| 680 SWIG_Error(SWIG_TypeError, "Slice object expected."); |
| 681 return; |
| 682 } |
| 683 PySlice_GetIndices(slice, self->size(), &i, &j, &step); |
| 684 swig::setslice(self, i, j, v); |
| 685 } |
| 686 |
| 687 void __delitem__(PySliceObject *slice) |
| 688 throw (std::out_of_range) { |
| 689 Py_ssize_t i, j, step; |
| 690 if( !PySlice_Check(slice) ) { |
| 691 SWIG_Error(SWIG_TypeError, "Slice object expected."); |
| 692 return; |
| 693 } |
| 694 PySlice_GetIndices(slice, self->size(), &i, &j, &step); |
| 695 swig::delslice(self, i,j); |
| 696 } |
| 697 |
| 698 } |
| 699 %enddef |
| 700 |
| 701 %define %swig_sequence_methods(Sequence...) |
| 702 %swig_sequence_methods_common(%arg(Sequence)) |
| 703 %extend { |
| 704 const value_type& __getitem__(difference_type i) const throw (std::out_of_ra
nge) { |
| 705 return *(swig::cgetpos(self, i)); |
| 706 } |
| 707 |
| 708 void __setitem__(difference_type i, const value_type& x) throw (std::out_of_
range) { |
| 709 *(swig::getpos(self,i)) = x; |
| 710 } |
| 711 |
| 712 void append(const value_type& x) { |
| 713 self->push_back(x); |
| 714 } |
| 715 } |
| 716 %enddef |
| 717 |
| 718 %define %swig_sequence_methods_val(Sequence...) |
| 719 %swig_sequence_methods_common(%arg(Sequence)) |
| 720 %extend { |
| 721 value_type __getitem__(difference_type i) throw (std::out_of_range) { |
| 722 return *(swig::cgetpos(self, i)); |
| 723 } |
| 724 |
| 725 void __setitem__(difference_type i, value_type x) throw (std::out_of_range)
{ |
| 726 *(swig::getpos(self,i)) = x; |
| 727 } |
| 728 |
| 729 void append(value_type x) { |
| 730 self->push_back(x); |
| 731 } |
| 732 } |
| 733 %enddef |
| 734 |
| 735 |
| 736 |
| 737 // |
| 738 // Common fragments |
| 739 // |
| 740 |
| 741 %fragment("StdSequenceTraits","header", |
| 742 fragment="StdTraits", |
| 743 fragment="SwigPySequence_Cont") |
| 744 { |
| 745 namespace swig { |
| 746 template <class SwigPySeq, class Seq> |
| 747 inline void |
| 748 assign(const SwigPySeq& swigpyseq, Seq* seq) { |
| 749 // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not alway
s implemented |
| 750 typedef typename SwigPySeq::value_type value_type; |
| 751 typename SwigPySeq::const_iterator it = swigpyseq.begin(); |
| 752 for (;it != swigpyseq.end(); ++it) { |
| 753 seq->insert(seq->end(),(value_type)(*it)); |
| 754 } |
| 755 } |
| 756 |
| 757 template <class Seq, class T = typename Seq::value_type > |
| 758 struct traits_asptr_stdseq { |
| 759 typedef Seq sequence; |
| 760 typedef T value_type; |
| 761 |
| 762 static int asptr(PyObject *obj, sequence **seq) { |
| 763 if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) { |
| 764 sequence *p; |
| 765 if (::SWIG_ConvertPtr(obj,(void**)&p, |
| 766 swig::type_info<sequence>(),0) == SWIG_OK) { |
| 767 if (seq) *seq = p; |
| 768 return SWIG_OLDOBJ; |
| 769 } |
| 770 } else if (PySequence_Check(obj)) { |
| 771 try { |
| 772 SwigPySequence_Cont<value_type> swigpyseq(obj); |
| 773 if (seq) { |
| 774 sequence *pseq = new sequence(); |
| 775 assign(swigpyseq, pseq); |
| 776 *seq = pseq; |
| 777 return SWIG_NEWOBJ; |
| 778 } else { |
| 779 return swigpyseq.check() ? SWIG_OK : SWIG_ERROR; |
| 780 } |
| 781 } catch (std::exception& e) { |
| 782 if (seq) { |
| 783 if (!PyErr_Occurred()) { |
| 784 PyErr_SetString(PyExc_TypeError, e.what()); |
| 785 } |
| 786 } |
| 787 return SWIG_ERROR; |
| 788 } |
| 789 } |
| 790 return SWIG_ERROR; |
| 791 } |
| 792 }; |
| 793 |
| 794 template <class Seq, class T = typename Seq::value_type > |
| 795 struct traits_from_stdseq { |
| 796 typedef Seq sequence; |
| 797 typedef T value_type; |
| 798 typedef typename Seq::size_type size_type; |
| 799 typedef typename sequence::const_iterator const_iterator; |
| 800 |
| 801 static PyObject *from(const sequence& seq) { |
| 802 %#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS |
| 803 swig_type_info *desc = swig::type_info<sequence>(); |
| 804 if (desc && desc->clientdata) { |
| 805 return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN); |
| 806 } |
| 807 %#endif |
| 808 size_type size = seq.size(); |
| 809 if (size <= (size_type)INT_MAX) { |
| 810 PyObject *obj = PyTuple_New((int)size); |
| 811 int i = 0; |
| 812 for (const_iterator it = seq.begin(); |
| 813 it != seq.end(); ++it, ++i) { |
| 814 PyTuple_SetItem(obj,i,swig::from<value_type>(*it)); |
| 815 } |
| 816 return obj; |
| 817 } else { |
| 818 PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python")
; |
| 819 return NULL; |
| 820 } |
| 821 } |
| 822 }; |
| 823 } |
| 824 } |
OLD | NEW |