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") { 40namespace 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") { 73namespace 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 109namespace 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_PyObject, 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_PyObject, 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 157namespace 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 188namespace 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{ 296namespace 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,const $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(%static_cast($1,const $type &).first), 545 swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); 546 PyTuple_SetItem($result,1,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), 547 swig::SwigPyIterator::descriptor(),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(%static_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 &).second)); 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::descriptor(), 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::SwigPyIterator::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_range) { 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_range) { 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{ 745namespace 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 always 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} 825