Objects.h
1//---------------------------------------------------------------------------//
2// Copyright 1998 The Regents of the University of California.
3// All rights reserved. See LEGAL.LLNL for full text and disclaimer.
4//---------------------------------------------------------------------------//
5
6#ifndef __CXX_Objects__h
7#define __CXX_Objects__h
8
9// Prevent warnings
10#if defined(_XOPEN_SOURCE)
11#undef _XOPEN_SOURCE
12#endif
13
14#include "Python.h"
15#include "Config.h"
16#include "Exception.h"
17
18
19#include <iostream>
20#include <sstream>
21#include <string>
22#include <iterator>
23#include <utility>
24#include <typeinfo>
25
26namespace Py
27 {
28 typedef int sequence_index_type; // type of an index into a sequence
29
30 // Forward declarations
31 class Object;
32 class Type;
33 template<typename T> class SeqBase;
34 class String;
35 class List;
36 template<typename T> class MapBase;
37
38 // new_reference_to also overloaded below on Object
39 inline PyObject* new_reference_to(PyObject* p)
40 {
41 Py::_XINCREF(p);
42 return p;
43 }
44
45 // returning Null() from an extension method triggers a
46 // Python exception
47 inline PyObject* Null()
48 {
49 return (static_cast<PyObject*>(0));
50 }
51
52 //===========================================================================//
53 // class Object
54 // The purpose of this class is to serve as the most general kind of
55 // Python object, for the purpose of writing C++ extensions in Python
56 // Objects hold a PyObject* which they own. This pointer is always a
57 // valid pointer to a Python object. In children we must maintain this behavior.
58 //
59 // Instructions on how to make your own class MyType descended from Object:
60 // (0) Pick a base class, either Object or perhaps SeqBase<T> or MapBase<T>.
61 // This example assumes Object.
62
63 // (1) Write a routine int MyType_Check (PyObject *) modeled after PyInt_Check,
64 // PyFloat_Check, etc.
65
66 // (2) Add method accepts:
67 // virtual bool accepts (PyObject *pyob) const {
68 // return pyob && MyType_Check (pyob);
69 // }
70
71 // (3) Include the following constructor and copy constructor
72 //
73 /*
74 explicit MyType (PyObject *pyob): Object(pyob) {
75 validate();
76 }
77
78 MyType(const Object& other): Object(other.ptr()) {
79 validate();
80 }
81 */
82
83 // Alernate version for the constructor to allow for construction from owned pointers:
84 /*
85 explicit MyType (PyObject *pyob): Object(pyob) {
86 validate();
87 }
88 */
89
90 // You may wish to add other constructors; see the classes below for examples.
91 // Each constructor must use "set" to set the pointer
92 // and end by validating the pointer you have created.
93
94 // (4) Each class needs at least these two assignment operators:
95 /*
96 MyType& operator= (const Object& rhs) {
97 return (*this = *rhs);
98 }
99
100 Mytype& operator= (PyObject* rhsp) {
101 if(ptr() == rhsp) return *this;
102 set(rhsp);
103 return *this;
104 }
105 */
106 // Note on accepts: constructors call the base class
107 // version of a virtual when calling the base class constructor,
108 // so the test has to be done explicitly in a descendent.
109
110 // If you are inheriting from PythonExtension<T> to define an object
111 // note that it contains PythonExtension<T>::check
112 // which you can use in accepts when writing a wrapper class.
113 // See Demo/range.h and Demo/range.cpp for an example.
114
115 class Object
116 {
117 private:
118 // the pointer to the Python object
119 // Only Object sets this directly.
120 // The default constructor for Object sets it to Py_None and
121 // child classes must use "set" to set it
122 //
123 PyObject* p;
124
125 protected:
126
127 void set (PyObject* pyob, bool owned = false)
128 {
129 release();
130 p = pyob;
131 if (!owned)
132 {
133 Py::_XINCREF (p);
134 }
135 validate();
136 }
137
138 void release ()
139 {
140 Py::_XDECREF (p);
141 p = 0;
142 }
143
144 void validate()
145 {
146 // release pointer if not the right type
147 if (! accepts (p))
148 {
149 release ();
150 if(PyErr_Occurred())
151 { // Error message already set
152 throw Exception();
153 }
154 // Better error message if RTTI available
155#if defined( _CPPRTTI )
156 std::string s("Error creating object of type ");
157 s += (typeid (*this)).name();
158 throw TypeError (s);
159#else
160 throw TypeError ("CXX: type error.");
161#endif
162 }
163 }
164
165 public:
166 // Constructor acquires new ownership of pointer unless explicitly told not to.
167 explicit Object (PyObject* pyob=Py::_None(), bool owned = false): p (pyob)
168 {
169 if(!owned)
170 {
171 Py::_XINCREF (p);
172 }
173 validate();
174 }
175
176 // Copy constructor acquires new ownership of pointer
177 Object (const Object& ob): p(ob.p)
178 {
179 Py::_XINCREF (p);
180 validate();
181 }
182
183 // Assignment acquires new ownership of pointer
184 Object& operator= (const Object& rhs)
185 {
186 set(rhs.p);
187 return *this;
188 }
189
190 Object& operator= (PyObject* rhsp)
191 {
192 if(ptr() == rhsp) return *this;
193 set (rhsp);
194 return *this;
195 }
196
197 // Destructor
198 virtual ~Object ()
199 {
200 release ();
201 }
202
203 // Loaning the pointer to others, retain ownership
204 PyObject* operator* () const
205 {
206 return p;
207 }
208
209 // Explicit reference_counting changes
210 void increment_reference_count()
211 {
212 Py::_XINCREF(p);
213 }
214
215 void decrement_reference_count()
216 {
217 // not allowed to commit suicide, however
218 if(reference_count() == 1)
219 throw RuntimeError("Object::decrement_reference_count error.");
220 Py::_XDECREF(p);
221 }
222 // Would like to call this pointer() but messes up STL in SeqBase<T>
223 PyObject* ptr () const
224 {
225 return p;
226 }
227
228 //
229 // Queries
230 //
231
232 // Can pyob be used in this object's constructor?
233 virtual bool accepts (PyObject *pyob) const
234 {
235 return (pyob != 0);
236 }
237
238 int reference_count () const
239 { // the reference count
240 return p ? p->ob_refcnt : 0;
241 }
242
243 Type type () const; // the type object associated with this one
244
245 String str () const; // the str() representation
246
247 std::string as_string() const;
248
249 String repr () const; // the repr () representation
250
251 List dir () const; // the dir() list
252
253 bool hasAttr (const std::string& s) const
254 {
255 return PyObject_HasAttrString (p, const_cast<char*>(s.c_str())) ? true: false;
256 }
257
258 Object getAttr (const std::string& s) const
259 {
260 return Object (PyObject_GetAttrString (p, const_cast<char*>(s.c_str())), true);
261 }
262
263 Object getItem (const Object& key) const
264 {
265 return Object (PyObject_GetItem(p, *key), true);
266 }
267
268 long hashValue () const
269 {
270 return PyObject_Hash (p);
271 }
272
273 //
274 // int print (FILE* fp, int flags=Py_Print_RAW)
275 // {
276 // return PyObject_Print (p, fp, flags);
277 // }
278 //
279 bool is(PyObject *pother) const
280 { // identity test
281 return p == pother;
282 }
283
284 bool is(const Object& other) const
285 { // identity test
286 return p == other.p;
287 }
288
289 bool isCallable () const
290 {
291 return PyCallable_Check (p) != 0;
292 }
293
294 bool isInstance () const
295 {
296 return PyInstance_Check (p) != 0;
297 }
298
299 bool isDict () const
300 {
301 return Py::_Dict_Check (p);
302 }
303
304 bool isList () const
305 {
306 return Py::_List_Check (p);
307 }
308
309 bool isMapping () const
310 {
311 return PyMapping_Check (p) != 0;
312 }
313
314 bool isNumeric () const
315 {
316 return PyNumber_Check (p) != 0;
317 }
318
319 bool isSequence () const
320 {
321 return PySequence_Check (p) != 0;
322 }
323
324 bool isTrue () const
325 {
326 return PyObject_IsTrue (p) != 0;
327 }
328
329 bool isType (const Type& t) const;
330
331 bool isTuple() const
332 {
333 return Py::_Tuple_Check(p);
334 }
335
336 bool isString() const
337 {
338 return Py::_String_Check(p) || Py::_Unicode_Check(p);
339 }
340
341 bool isUnicode() const
342 {
343 return Py::_Unicode_Check(p);
344 }
345
346 // Commands
347 void setAttr (const std::string& s, const Object& value)
348 {
349 if(PyObject_SetAttrString (p, const_cast<char*>(s.c_str()), *value) == -1)
350 throw AttributeError ("getAttr failed.");
351 }
352
353 void delAttr (const std::string& s)
354 {
355 if(PyObject_DelAttrString (p, const_cast<char*>(s.c_str())) == -1)
356 throw AttributeError ("delAttr failed.");
357 }
358
359 // PyObject_SetItem is too weird to be using from C++
360 // so it is intentionally omitted.
361
362 void delItem (const Object& /*key*/)
363 {
364 //if(PyObject_DelItem(p, *key) == -1)
365 // failed to link on Windows?
366 throw KeyError("delItem failed.");
367 }
368 // Equality and comparison use PyObject_Compare
369
370 bool operator==(const Object& o2) const
371 {
372 int k = PyObject_Compare (p, *o2);
373 if (PyErr_Occurred()) throw Exception();
374 return k == 0;
375 }
376
377 bool operator!=(const Object& o2) const
378 {
379 int k = PyObject_Compare (p, *o2);
380 if (PyErr_Occurred()) throw Exception();
381 return k != 0;
382
383 }
384
385 bool operator>=(const Object& o2) const
386 {
387 int k = PyObject_Compare (p, *o2);
388 if (PyErr_Occurred()) throw Exception();
389 return k >= 0;
390 }
391
392 bool operator<=(const Object& o2) const
393 {
394 int k = PyObject_Compare (p, *o2);
395 if (PyErr_Occurred()) throw Exception();
396 return k <= 0;
397 }
398
399 bool operator<(const Object& o2) const
400 {
401 int k = PyObject_Compare (p, *o2);
402 if (PyErr_Occurred()) throw Exception();
403 return k < 0;
404 }
405
406 bool operator>(const Object& o2) const
407 {
408 int k = PyObject_Compare (p, *o2);
409 if (PyErr_Occurred()) throw Exception();
410 return k > 0;
411 }
412 };
413 // End of class Object
414 inline PyObject* new_reference_to(const Object& g)
415 {
416 PyObject* p = g.ptr();
417 Py::_XINCREF(p);
418 return p;
419 }
420
421 // Nothing() is what an extension method returns if
422 // there is no other return value.
423 inline Object Nothing()
424 {
425 return Object(Py::_None());
426 }
427
428 // Python special None value
429 inline Object None()
430 {
431 return Object(Py::_None());
432 }
433
434 // TMM: 31May'01 - Added the #ifndef so I can exlude iostreams.
435#ifndef CXX_NO_IOSTREAMS
436 std::ostream& operator<< (std::ostream& os, const Object& ob);
437#endif
438
439 // Class Type
440 class Type: public Object
441 {
442 public:
443 explicit Type (PyObject* pyob, bool owned = false): Object(pyob, owned)
444 {
445 validate();
446 }
447
448 Type (const Object& ob): Object(*ob)
449 {
450 validate();
451 }
452
453 Type(const Type& t): Object(t)
454 {
455 validate();
456 }
457
458 Type& operator= (const Object& rhs)
459 {
460 return (*this = *rhs);
461 }
462
463 Type& operator= (PyObject* rhsp)
464 {
465 if(ptr() == rhsp) return *this;
466 set (rhsp);
467 return *this;
468 }
469 virtual bool accepts (PyObject *pyob) const
470 {
471 return pyob && Py::_Type_Check (pyob);
472 }
473 };
474
475
476 //
477 // Convert an owned Python pointer into a CXX Object
478 //
479 inline Object asObject (PyObject *p)
480 {
481 return Object(p, true);
482 }
483
484
485
486
487 // ===============================================
488 // class Int
489 class Int: public Object
490 {
491 public:
492 // Constructor
493 explicit Int (PyObject *pyob, bool owned = false): Object (pyob, owned)
494 {
495 validate();
496 }
497
498 Int (const Int& ob): Object(*ob)
499 {
500 validate();
501 }
502
503 // create from long
504 explicit Int (long v = 0L): Object(PyInt_FromLong(v), true)
505 {
506 validate();
507 }
508
509 // create from int
510 explicit Int (int v)
511 {
512 long w = v;
513 set(PyInt_FromLong(w), true);
514 validate();
515 }
516
517 Int (const Object& ob)
518 {
519 set(PyNumber_Int(*ob), true);
520 validate();
521 }
522
523 // Assignment acquires new ownership of pointer
524
525 Int& operator= (const Object& rhs)
526 {
527 return (*this = *rhs);
528 }
529
530 Int& operator= (PyObject* rhsp)
531 {
532 if(ptr() == rhsp) return *this;
533 set (PyNumber_Int(rhsp), true);
534 return *this;
535 }
536 // Membership
537 virtual bool accepts (PyObject *pyob) const
538 {
539 return pyob && Py::_Int_Check (pyob);
540 }
541 // convert to long
542 operator long() const
543 {
544 return PyInt_AsLong (ptr());
545 }
546 // assign from an int
547 Int& operator= (int v)
548 {
549 set (PyInt_FromLong (long(v)), true);
550 return *this;
551 }
552 // assign from long
553 Int& operator= (long v)
554 {
555 set (PyInt_FromLong (v), true);
556 return *this;
557 }
558 };
559
560 // ===============================================
561 // class Long
562 class Long: public Object
563 {
564 public:
565 // Constructor
566 explicit Long (PyObject *pyob, bool owned = false): Object (pyob, owned)
567 {
568 validate();
569 }
570
571 Long (const Long& ob): Object(ob.ptr())
572 {
573 validate();
574 }
575
576 // create from long
577 explicit Long (long v = 0L)
578 : Object(PyLong_FromLong(v), true)
579 {
580 validate();
581 }
582 // create from int
583 explicit Long (int v)
584 : Object(PyLong_FromLong(static_cast<long>(v)), true)
585 {
586 validate();
587 }
588
589 // create from unsigned long
590 explicit Long (unsigned long v)
591 : Object(PyLong_FromUnsignedLong(v), true)
592 {
593 validate();
594 }
595
596 // try to create from any object
597 Long (const Object& ob)
598 : Object(PyNumber_Long(*ob), true)
599 {
600 validate();
601 }
602
603 // Assignment acquires new ownership of pointer
604
605 Long& operator= (const Object& rhs)
606 {
607 return (*this = *rhs);
608 }
609
610 Long& operator= (PyObject* rhsp)
611 {
612 if(ptr() == rhsp) return *this;
613 set (PyNumber_Long(rhsp), true);
614 return *this;
615 }
616 // Membership
617 virtual bool accepts (PyObject *pyob) const
618 {
619 return pyob && Py::_Long_Check (pyob);
620 }
621 // convert to long
622 operator long() const
623 {
624 return PyLong_AsLong (ptr());
625 }
626 operator double() const
627 {
628 return PyLong_AsDouble (ptr());
629 }
630 operator unsigned long() const
631 {
632 return PyLong_AsUnsignedLong (ptr());
633 }
634 // assign from an int
635 Long& operator= (int v)
636 {
637 set(PyLong_FromLong (long(v)), true);
638 return *this;
639 }
640 // assign from long
641 Long& operator= (long v)
642 {
643 set(PyLong_FromLong (v), true);
644 return *this;
645 }
646 // assign from unsigned long
647 Long& operator= (unsigned long v)
648 {
649 set(PyLong_FromUnsignedLong (v), true);
650 return *this;
651 }
652 };
653
654 // ===============================================
655 // class Float
656 //
657 class Float: public Object
658 {
659 public:
660 // Constructor
661 explicit Float (PyObject *pyob, bool owned = false): Object(pyob, owned)
662 {
663 validate();
664 }
665
666 Float (const Float& f): Object(f)
667 {
668 validate();
669 }
670
671 // make from double
672 explicit Float (double v=0.0)
673 : Object(PyFloat_FromDouble (v), true)
674 {
675 validate();
676 }
677
678 // try to make from any object
679 Float (const Object& ob)
680 : Object(PyNumber_Float(*ob), true)
681 {
682 validate();
683 }
684
685 Float& operator= (const Object& rhs)
686 {
687 return (*this = *rhs);
688 }
689
690 Float& operator= (PyObject* rhsp)
691 {
692 if(ptr() == rhsp) return *this;
693 set (PyNumber_Float(rhsp), true);
694 return *this;
695 }
696 // Membership
697 virtual bool accepts (PyObject *pyob) const
698 {
699 return pyob && Py::_Float_Check (pyob);
700 }
701 // convert to double
702 operator double () const
703 {
704 return PyFloat_AsDouble (ptr());
705 }
706 // assign from a double
707 Float& operator= (double v)
708 {
709 set(PyFloat_FromDouble (v), true);
710 return *this;
711 }
712 // assign from an int
713 Float& operator= (int v)
714 {
715 set(PyFloat_FromDouble (double(v)), true);
716 return *this;
717 }
718 // assign from long
719 Float& operator= (long v)
720 {
721 set(PyFloat_FromDouble (double(v)), true);
722 return *this;
723 }
724 // assign from an Int
725 Float& operator= (const Int& iob)
726 {
727 set(PyFloat_FromDouble (double(long(iob))), true);
728 return *this;
729 }
730 };
731
732 // ===============================================
733 // class Complex
734 class Complex: public Object
735 {
736 public:
737 // Constructor
738 explicit Complex (PyObject *pyob, bool owned = false): Object(pyob, owned)
739 {
740 validate();
741 }
742
743 Complex (const Complex& f): Object(f)
744 {
745 validate();
746 }
747
748 // make from double
749 explicit Complex (double v=0.0, double w=0.0)
750 :Object(PyComplex_FromDoubles (v, w), true)
751 {
752 validate();
753 }
754
755 Complex& operator= (const Object& rhs)
756 {
757 return (*this = *rhs);
758 }
759
760 Complex& operator= (PyObject* rhsp)
761 {
762 if(ptr() == rhsp) return *this;
763 set (rhsp);
764 return *this;
765 }
766 // Membership
767 virtual bool accepts (PyObject *pyob) const
768 {
769 return pyob && Py::_Complex_Check (pyob);
770 }
771 // convert to Py_complex
772 operator Py_complex () const
773 {
774 return PyComplex_AsCComplex (ptr());
775 }
776 // assign from a Py_complex
777 Complex& operator= (const Py_complex& v)
778 {
779 set(PyComplex_FromCComplex (v), true);
780 return *this;
781 }
782 // assign from a double
783 Complex& operator= (double v)
784 {
785 set(PyComplex_FromDoubles (v, 0.0), true);
786 return *this;
787 }
788 // assign from an int
789 Complex& operator= (int v)
790 {
791 set(PyComplex_FromDoubles (double(v), 0.0), true);
792 return *this;
793 }
794 // assign from long
795 Complex& operator= (long v)
796 {
797 set(PyComplex_FromDoubles (double(v), 0.0), true);
798 return *this;
799 }
800 // assign from an Int
801 Complex& operator= (const Int& iob)
802 {
803 set(PyComplex_FromDoubles (double(long(iob)), 0.0), true);
804 return *this;
805 }
806
807 double real() const
808 {
809 return PyComplex_RealAsDouble(ptr());
810 }
811
812 double imag() const
813 {
814 return PyComplex_ImagAsDouble(ptr());
815 }
816 };
817 // Sequences
818 // Sequences are here represented as sequences of items of type T.
819 // The base class SeqBase<T> represents that.
820 // In basic Python T is always "Object".
821
822 // seqref<T> is what you get if you get elements from a non-const SeqBase<T>.
823 // Note: seqref<T> could probably be a nested class in SeqBase<T> but that might stress
824 // some compilers needlessly. Simlarly for mapref later.
825
826 // While this class is not intended for enduser use, it needs some public
827 // constructors for the benefit of the STL.
828
829 // See Scott Meyer's More Essential C++ for a description of proxies.
830 // This application is even more complicated. We are doing an unusual thing
831 // in having a double proxy. If we want the STL to work
832 // properly we have to compromise by storing the rvalue inside. The
833 // entire Object API is repeated so that things like s[i].isList() will
834 // work properly.
835
836 // Still, once in a while a weird compiler message may occur using expressions like x[i]
837 // Changing them to Object(x[i]) helps the compiler to understand that the
838 // conversion of a seqref to an Object is wanted.
839
840 template<typename T>
841 class seqref
842 {
843 protected:
844 SeqBase<T>& s; // the sequence
845 int offset; // item number
846 T the_item; // lvalue
847 public:
848
849 seqref (SeqBase<T>& seq, sequence_index_type j)
850 : s(seq), offset(j), the_item (s.getItem(j))
851 {}
852
853 seqref (const seqref<T>& range)
854 : s(range.s), offset(range.offset), the_item(range.the_item)
855 {}
856
857 // TMM: added this seqref ctor for use with STL algorithms
858 seqref (Object& obj)
859 : s(dynamic_cast< SeqBase<T>&>(obj))
860 , offset( NULL )
861 , the_item(s.getItem(offset))
862 {}
863 ~seqref()
864 {}
865
866 operator T() const
867 { // rvalue
868 return the_item;
869 }
870
871 seqref<T>& operator=(const seqref<T>& rhs)
872 { //used as lvalue
873 the_item = rhs.the_item;
874 s.setItem(offset, the_item);
875 return *this;
876 }
877
878 seqref<T>& operator=(const T& ob)
879 { // used as lvalue
880 the_item = ob;
881 s.setItem(offset, ob);
882 return *this;
883 }
884
885 // forward everything else to the item
886 PyObject* ptr () const
887 {
888 return the_item.ptr();
889 }
890
891 int reference_count () const
892 { // the reference count
893 return the_item.reference_count();
894 }
895
896 Type type () const
897 {
898 return the_item.type();
899 }
900
901 String str () const;
902
903 String repr () const;
904
905 bool hasAttr (const std::string& attr_name) const
906 {
907 return the_item.hasAttr(attr_name);
908 }
909
910 Object getAttr (const std::string& attr_name) const
911 {
912 return the_item.getAttr(attr_name);
913 }
914
915 Object getItem (const Object& key) const
916 {
917 return the_item.getItem(key);
918 }
919
920 long hashValue () const
921 {
922 return the_item.hashValue();
923 }
924
925 bool isCallable () const
926 {
927 return the_item.isCallable();
928 }
929
930 bool isInstance () const
931 {
932 return the_item.isInstance();
933 }
934
935 bool isDict () const
936 {
937 return the_item.isDict();
938 }
939
940 bool isList () const
941 {
942 return the_item.isList();
943 }
944
945 bool isMapping () const
946 {
947 return the_item.isMapping();
948 }
949
950 bool isNumeric () const
951 {
952 return the_item.isNumeric();
953 }
954
955 bool isSequence () const
956 {
957 return the_item.isSequence();
958 }
959
960 bool isTrue () const
961 {
962 return the_item.isTrue();
963 }
964
965 bool isType (const Type& t) const
966 {
967 return the_item.isType (t);
968 }
969
970 bool isTuple() const
971 {
972 return the_item.isTuple();
973 }
974
975 bool isString() const
976 {
977 return the_item.isString();
978 }
979 // Commands
980 void setAttr (const std::string& attr_name, const Object& value)
981 {
982 the_item.setAttr(attr_name, value);
983 }
984
985 void delAttr (const std::string& attr_name)
986 {
987 the_item.delAttr(attr_name);
988 }
989
990 void delItem (const Object& key)
991 {
992 the_item.delItem(key);
993 }
994
995 bool operator==(const Object& o2) const
996 {
997 return the_item == o2;
998 }
999
1000 bool operator!=(const Object& o2) const
1001 {
1002 return the_item != o2;
1003 }
1004
1005 bool operator>=(const Object& o2) const
1006 {
1007 return the_item >= o2;
1008 }
1009
1010 bool operator<=(const Object& o2) const
1011 {
1012 return the_item <= o2;
1013 }
1014
1015 bool operator<(const Object& o2) const
1016 {
1017 return the_item < o2;
1018 }
1019
1020 bool operator>(const Object& o2) const
1021 {
1022 return the_item > o2;
1023 }
1024 }; // end of seqref
1025
1026
1027 // class SeqBase<T>
1028 // ...the base class for all sequence types
1029
1030 template<typename T>
1031 class SeqBase: public Object
1032 {
1033 public:
1034 // STL definitions
1035 typedef size_t size_type;
1036 typedef seqref<T> reference;
1037 typedef T const_reference;
1038 typedef seqref<T>* pointer;
1039 typedef int difference_type;
1040 typedef T value_type; // TMM: 26Jun'01
1041
1042 virtual size_type max_size() const
1043 {
1044 return std::string::npos; // ?
1045 }
1046
1047 virtual size_type capacity() const
1048 {
1049 return size();
1050 }
1051
1052 virtual void swap(SeqBase<T>& c)
1053 {
1054 SeqBase<T> temp = c;
1055 c = ptr();
1056 set(temp.ptr());
1057 }
1058
1059 virtual size_type size () const
1060 {
1061 return PySequence_Length (ptr());
1062 }
1063
1064 explicit SeqBase<T> ()
1065 :Object(PyTuple_New(0), true)
1066 {
1067 validate();
1068 }
1069
1070 explicit SeqBase<T> (PyObject* pyob, bool owned=false)
1071 : Object(pyob, owned)
1072 {
1073 validate();
1074 }
1075
1076 SeqBase<T> (const Object& ob): Object(ob)
1077 {
1078 validate();
1079 }
1080
1081 // Assignment acquires new ownership of pointer
1082
1083 SeqBase<T>& operator= (const Object& rhs)
1084 {
1085 return (*this = *rhs);
1086 }
1087
1088 SeqBase<T>& operator= (PyObject* rhsp)
1089 {
1090 if(ptr() == rhsp) return *this;
1091 set (rhsp);
1092 return *this;
1093 }
1094
1095 virtual bool accepts (PyObject *pyob) const
1096 {
1097 return pyob && PySequence_Check (pyob);
1098 }
1099
1100 size_type length () const
1101 {
1102 return PySequence_Length (ptr());
1103 }
1104
1105 // Element access
1106 const T operator[](sequence_index_type index) const
1107 {
1108 return getItem(index);
1109 }
1110
1111 seqref<T> operator[](sequence_index_type index)
1112 {
1113 return seqref<T>(*this, index);
1114 }
1115
1116 virtual T getItem (sequence_index_type i) const
1117 {
1118 return T(asObject(PySequence_GetItem (ptr(), i)));
1119 }
1120
1121 virtual void setItem (sequence_index_type i, const T& ob)
1122 {
1123 if (PySequence_SetItem (ptr(), i, *ob) == -1)
1124 {
1125 throw Exception();
1126 }
1127 }
1128
1129 SeqBase<T> repeat (int count) const
1130 {
1131 return SeqBase<T> (PySequence_Repeat (ptr(), count), true);
1132 }
1133
1134 SeqBase<T> concat (const SeqBase<T>& other) const
1135 {
1136 return SeqBase<T> (PySequence_Concat(ptr(), *other), true);
1137 }
1138
1139 // more STL compatability
1140 const T front () const
1141 {
1142 return getItem(0);
1143 }
1144
1145 seqref<T> front()
1146 {
1147 return seqref<T>(this, 0);
1148 }
1149
1150 const T back () const
1151 {
1152 return getItem(size()-1);
1153 }
1154
1155 seqref<T> back()
1156 {
1157 return seqref<T>(this, size()-1);
1158 }
1159
1160 void verify_length(size_type required_size) const
1161 {
1162 if (size() != required_size)
1163 throw IndexError ("Unexpected SeqBase<T> length.");
1164 }
1165
1166 void verify_length(size_type min_size, size_type max_size) const
1167 {
1168 size_type n = size();
1169 if (n < min_size || n > max_size)
1170 throw IndexError ("Unexpected SeqBase<T> length.");
1171 }
1172
1173 class iterator
1174 : public random_access_iterator_parent(seqref<T>)
1175 {
1176 protected:
1177 friend class SeqBase<T>;
1178 SeqBase<T>* seq;
1179 int count;
1180
1181 public:
1182 ~iterator ()
1183 {}
1184
1185 iterator ()
1186 : seq( 0 )
1187 , count( 0 )
1188 {}
1189
1190 iterator (SeqBase<T>* s, int where)
1191 : seq( s )
1192 , count( where )
1193 {}
1194
1195 iterator (const iterator& other)
1196 : seq( other.seq )
1197 , count( other.count )
1198 {}
1199
1200 bool eql (const iterator& other) const
1201 {
1202 return (*seq == *other.seq) && (count == other.count);
1203 }
1204
1205 bool neq (const iterator& other) const
1206 {
1207 return (*seq != *other.seq) || (count != other.count);
1208 }
1209
1210 bool lss (const iterator& other) const
1211 {
1212 return (count < other.count);
1213 }
1214
1215 bool gtr (const iterator& other) const
1216 {
1217 return (count > other.count);
1218 }
1219
1220 bool leq (const iterator& other) const
1221 {
1222 return (count <= other.count);
1223 }
1224
1225 bool geq (const iterator& other) const
1226 {
1227 return (count >= other.count);
1228 }
1229
1230 seqref<T> operator*()
1231 {
1232 return seqref<T>(*seq, count);
1233 }
1234
1235 seqref<T> operator[] (sequence_index_type i)
1236 {
1237 return seqref<T>(*seq, count + i);
1238 }
1239
1240 iterator& operator=(const iterator& other)
1241 {
1242 if (this == &other) return *this;
1243 seq = other.seq;
1244 count = other.count;
1245 return *this;
1246 }
1247
1248 iterator operator+(int n) const
1249 {
1250 return iterator(seq, count + n);
1251 }
1252
1253 iterator operator-(int n) const
1254 {
1255 return iterator(seq, count - n);
1256 }
1257
1258 iterator& operator+=(int n)
1259 {
1260 count = count + n;
1261 return *this;
1262 }
1263
1264 iterator& operator-=(int n)
1265 {
1266 count = count - n;
1267 return *this;
1268 }
1269
1270 int operator-(const iterator& other) const
1271 {
1272 if (*seq != *other.seq)
1273 throw RuntimeError ("SeqBase<T>::iterator comparison error");
1274 return count - other.count;
1275 }
1276
1277 // prefix ++
1278 iterator& operator++ ()
1279 { count++; return *this;}
1280 // postfix ++
1281 iterator operator++ (int)
1282 { return iterator(seq, count++);}
1283 // prefix --
1284 iterator& operator-- ()
1285 { count--; return *this;}
1286 // postfix --
1287 iterator operator-- (int)
1288 { return iterator(seq, count--);}
1289
1290 std::string diagnose() const
1291 {
1292 std::ostringstream oss;
1293 oss << "iterator diagnosis " << seq << ", " << count << std::ends;
1294 return std::string(oss.str());
1295 }
1296 }; // end of class SeqBase<T>::iterator
1297
1298 iterator begin ()
1299 {
1300 return iterator(this, 0);
1301 }
1302
1303 iterator end ()
1304 {
1305 return iterator(this, length());
1306 }
1307
1308 class const_iterator
1309 : public random_access_iterator_parent(const Object)
1310 {
1311 protected:
1312 friend class SeqBase<T>;
1313 const SeqBase<T>* seq;
1314 sequence_index_type count;
1315
1316 public:
1317 ~const_iterator ()
1318 {}
1319
1320 const_iterator ()
1321 : seq( 0 )
1322 , count( 0 )
1323 {}
1324
1325 const_iterator (const SeqBase<T>* s, int where)
1326 : seq( s )
1327 , count( where )
1328 {}
1329
1330 const_iterator(const const_iterator& other)
1331 : seq( other.seq )
1332 , count( other.count )
1333 {}
1334
1335 const T operator*() const
1336 {
1337 return seq->getItem(count);
1338 }
1339
1340 const T operator[] (sequence_index_type i) const
1341 {
1342 return seq->getItem(count + i);
1343 }
1344
1345 const_iterator& operator=(const const_iterator& other)
1346 {
1347 if (this == &other) return *this;
1348 seq = other.seq;
1349 count = other.count;
1350 return *this;
1351 }
1352
1353 const_iterator operator+(int n) const
1354 {
1355 return const_iterator(seq, count + n);
1356 }
1357
1358 bool eql (const const_iterator& other) const
1359 {
1360 return (*seq == *other.seq) && (count == other.count);
1361 }
1362
1363 bool neq (const const_iterator& other) const
1364 {
1365 return (*seq != *other.seq) || (count != other.count);
1366 }
1367
1368 bool lss (const const_iterator& other) const
1369 {
1370 return (count < other.count);
1371 }
1372
1373 bool gtr (const const_iterator& other) const
1374 {
1375 return (count > other.count);
1376 }
1377
1378 bool leq (const const_iterator& other) const
1379 {
1380 return (count <= other.count);
1381 }
1382
1383 bool geq (const const_iterator& other) const
1384 {
1385 return (count >= other.count);
1386 }
1387
1388 const_iterator operator-(int n)
1389 {
1390 return const_iterator(seq, count - n);
1391 }
1392
1393 const_iterator& operator+=(int n)
1394 {
1395 count = count + n;
1396 return *this;
1397 }
1398
1399 const_iterator& operator-=(int n)
1400 {
1401 count = count - n;
1402 return *this;
1403 }
1404
1405 int operator-(const const_iterator& other) const
1406 {
1407 if (*seq != *other.seq)
1408 throw RuntimeError ("SeqBase<T>::const_iterator::- error");
1409 return count - other.count;
1410 }
1411 // prefix ++
1412 const_iterator& operator++ ()
1413 { count++; return *this;}
1414 // postfix ++
1415 const_iterator operator++ (int)
1416 { return const_iterator(seq, count++);}
1417 // prefix --
1418 const_iterator& operator-- ()
1419 { count--; return *this;}
1420 // postfix --
1421 const_iterator operator-- (int)
1422 { return const_iterator(seq, count--);}
1423 }; // end of class SeqBase<T>::const_iterator
1424
1425 const_iterator begin () const
1426 {
1427 return const_iterator(this, 0);
1428 }
1429
1430 const_iterator end () const
1431 {
1432 return const_iterator(this, length());
1433 }
1434 };
1435
1436 // Here's an important typedef you might miss if reading too fast...
1437 typedef SeqBase<Object> Sequence;
1438
1439 template <typename T> bool operator==(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1440 template <typename T> bool operator!=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1441 template <typename T> bool operator< (const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1442 template <typename T> bool operator> (const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1443 template <typename T> bool operator<=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1444 template <typename T> bool operator>=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right);
1445
1446 template <typename T> bool operator==(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1447 template <typename T> bool operator!=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1448 template <typename T> bool operator< (const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1449 template <typename T> bool operator> (const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1450 template <typename T> bool operator<=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1451 template <typename T> bool operator>=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right);
1452
1453
1454 extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right);
1455 extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right);
1456 extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right);
1457 extern bool operator> (const Sequence::iterator& left, const Sequence::iterator& right);
1458 extern bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right);
1459 extern bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right);
1460
1461 extern bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1462 extern bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1463 extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1464 extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1465 extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1466 extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1467
1468 // ==================================================
1469 // class Char
1470 // Python strings return strings as individual elements.
1471 // I'll try having a class Char which is a String of length 1
1472 //
1473 typedef std::basic_string<Py_UNICODE> unicodestring;
1474 extern Py_UNICODE unicode_null_string[1];
1475
1476 class Char: public Object
1477 {
1478 public:
1479 explicit Char (PyObject *pyob, bool owned = false): Object(pyob, owned)
1480 {
1481 validate();
1482 }
1483
1484 Char (const Object& ob): Object(ob)
1485 {
1486 validate();
1487 }
1488
1489 Char (const std::string& v = "")
1490 :Object(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true)
1491 {
1492 validate();
1493 }
1494
1495 Char (char v)
1496 : Object(PyString_FromStringAndSize (&v, 1), true)
1497 {
1498 validate();
1499 }
1500
1501 Char (Py_UNICODE v)
1502 : Object(PyUnicode_FromUnicode (&v, 1), true)
1503 {
1504 validate();
1505 }
1506 // Assignment acquires new ownership of pointer
1507 Char& operator= (const Object& rhs)
1508 {
1509 return (*this = *rhs);
1510 }
1511
1512 Char& operator= (PyObject* rhsp)
1513 {
1514 if(ptr() == rhsp) return *this;
1515 set (rhsp);
1516 return *this;
1517 }
1518
1519 // Membership
1520 virtual bool accepts (PyObject *pyob) const
1521 {
1522 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob)) && PySequence_Length (pyob) == 1;
1523 }
1524
1525 // Assignment from C string
1526 Char& operator= (const std::string& v)
1527 {
1528 set(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true);
1529 return *this;
1530 }
1531
1532 Char& operator= (char v)
1533 {
1534 set(PyString_FromStringAndSize (&v, 1), true);
1535 return *this;
1536 }
1537
1538 Char& operator= (const unicodestring& v)
1539 {
1540 set(PyUnicode_FromUnicode (const_cast<Py_UNICODE*>(v.data()),1), true);
1541 return *this;
1542 }
1543
1544 Char& operator= (Py_UNICODE v)
1545 {
1546 set(PyUnicode_FromUnicode (&v, 1), true);
1547 return *this;
1548 }
1549
1550 // Conversion
1551 operator String() const;
1552
1553 operator std::string () const
1554 {
1555 return std::string(PyString_AsString (ptr()));
1556 }
1557 };
1558
1559 class String: public SeqBase<Char>
1560 {
1561 public:
1562 virtual size_type capacity() const
1563 {
1564 return max_size();
1565 }
1566
1567 explicit String (PyObject *pyob, bool owned = false): SeqBase<Char>(pyob, owned)
1568 {
1569 validate();
1570 }
1571
1572 String (const Object& ob): SeqBase<Char>(ob)
1573 {
1574 validate();
1575 }
1576
1577 String()
1578 : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
1579 {
1580 validate();
1581 }
1582
1583 String( const std::string& v )
1584 : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()),
1585 static_cast<int>( v.length() ) ), true )
1586 {
1587 validate();
1588 }
1589
1590 String( const char *s, const char *encoding, const char *error="strict" )
1591 : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true )
1592 {
1593 validate();
1594 }
1595
1596 String( const char *s, int len, const char *encoding, const char *error="strict" )
1597 : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true )
1598 {
1599 validate();
1600 }
1601
1602 String( const std::string &s, const char *encoding, const char *error="strict" )
1603 : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true )
1604 {
1605 validate();
1606 }
1607
1608 String( const std::string& v, std::string::size_type vsize )
1609 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v.data()),
1610 static_cast<int>( vsize ) ), true)
1611 {
1612 validate();
1613 }
1614
1615 String( const char *v, int vsize )
1616 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
1617 {
1618 validate();
1619 }
1620
1621 String( const char* v )
1622 : SeqBase<Char>( PyString_FromString( v ), true )
1623 {
1624 validate();
1625 }
1626
1627 // Assignment acquires new ownership of pointer
1628 String& operator= ( const Object& rhs )
1629 {
1630 return *this = *rhs;
1631 }
1632
1633 String& operator= (PyObject* rhsp)
1634 {
1635 if( ptr() == rhsp )
1636 return *this;
1637 set (rhsp);
1638 return *this;
1639 }
1640 // Membership
1641 virtual bool accepts (PyObject *pyob) const
1642 {
1643 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob));
1644 }
1645
1646 // Assignment from C string
1647 String& operator= (const std::string& v)
1648 {
1649 set( PyString_FromStringAndSize( const_cast<char*>( v.data() ),
1650 static_cast<int>( v.length() ) ), true );
1651 return *this;
1652 }
1653 String& operator= (const unicodestring& v)
1654 {
1655 set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ),
1656 static_cast<int>( v.length() ) ), true );
1657 return *this;
1658 }
1659
1660
1661 // Encode
1662 String encode( const char *encoding, const char *error="strict" )
1663 {
1664 if( isUnicode() )
1665 {
1666 return String( PyUnicode_AsEncodedString( ptr(), encoding, error ) );
1667 }
1668 else
1669 {
1670 return String( PyString_AsEncodedObject( ptr(), encoding, error ) );
1671 }
1672 }
1673
1674 String decode( const char *encoding, const char *error="strict" )
1675 {
1676 return Object( PyString_AsDecodedObject( ptr(), encoding, error ) );
1677 }
1678
1679 // Queries
1680 virtual size_type size () const
1681 {
1682 if( isUnicode() )
1683 {
1684 return static_cast<size_type>( PyUnicode_GET_SIZE (ptr()) );
1685 }
1686 else
1687 {
1688 return static_cast<size_type>( PyString_Size (ptr()) );
1689 }
1690 }
1691
1692 operator std::string () const
1693 {
1694 return as_std_string();
1695 }
1696
1697 std::string as_std_string() const
1698 {
1699 if( isUnicode() )
1700 {
1701 throw TypeError("cannot return std::string from Unicode object");
1702 }
1703 else
1704 {
1705 return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
1706 }
1707 }
1708
1709 unicodestring as_unicodestring() const
1710 {
1711 if( isUnicode() )
1712 {
1713 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
1714 static_cast<size_type>( PyUnicode_GET_SIZE( ptr() ) ) );
1715 }
1716 else
1717 {
1718 throw TypeError("can only return unicodestring from Unicode object");
1719 }
1720 }
1721 };
1722
1723 // ==================================================
1724 // class Tuple
1725 class Tuple: public Sequence
1726 {
1727 public:
1728 virtual void setItem (sequence_index_type offset, const Object&ob)
1729 {
1730 // note PyTuple_SetItem is a thief...
1731 if(PyTuple_SetItem (ptr(), offset, new_reference_to(ob)) == -1)
1732 {
1733 throw Exception();
1734 }
1735 }
1736
1737 // Constructor
1738 explicit Tuple (PyObject *pyob, bool owned = false): Sequence (pyob, owned)
1739 {
1740 validate();
1741 }
1742
1743 Tuple (const Object& ob): Sequence(ob)
1744 {
1745 validate();
1746 }
1747
1748 // New tuple of a given size
1749 explicit Tuple (int size = 0)
1750 {
1751 set(PyTuple_New (size), true);
1752 validate ();
1753 for (sequence_index_type i=0; i < size; i++)
1754 {
1755 if(PyTuple_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
1756 {
1757 throw Exception();
1758 }
1759 }
1760 }
1761 // Tuple from any sequence
1762 explicit Tuple (const Sequence& s)
1763 {
1764 sequence_index_type limit( sequence_index_type( s.length() ) );
1765
1766 set(PyTuple_New (limit), true);
1767 validate();
1768
1769 for(sequence_index_type i=0; i < limit; i++)
1770 {
1771 if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
1772 {
1773 throw Exception();
1774 }
1775 }
1776 }
1777 // Assignment acquires new ownership of pointer
1778
1779 Tuple& operator= (const Object& rhs)
1780 {
1781 return (*this = *rhs);
1782 }
1783
1784 Tuple& operator= (PyObject* rhsp)
1785 {
1786 if(ptr() == rhsp) return *this;
1787 set (rhsp);
1788 return *this;
1789 }
1790 // Membership
1791 virtual bool accepts (PyObject *pyob) const
1792 {
1793 return pyob && Py::_Tuple_Check (pyob);
1794 }
1795
1796 Tuple getSlice (int i, int j) const
1797 {
1798 return Tuple (PySequence_GetSlice (ptr(), i, j), true);
1799 }
1800
1801 };
1802
1803 // ==================================================
1804 // class List
1805
1806 class List: public Sequence
1807 {
1808 public:
1809 // Constructor
1810 explicit List (PyObject *pyob, bool owned = false): Sequence(pyob, owned)
1811 {
1812 validate();
1813 }
1814 List (const Object& ob): Sequence(ob)
1815 {
1816 validate();
1817 }
1818 // Creation at a fixed size
1819 List (int size = 0)
1820 {
1821 set(PyList_New (size), true);
1822 validate();
1823 for (sequence_index_type i=0; i < size; i++)
1824 {
1825 if(PyList_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
1826 {
1827 throw Exception();
1828 }
1829 }
1830 }
1831
1832 // List from a sequence
1833 List (const Sequence& s): Sequence()
1834 {
1835 int n = s.length();
1836 set(PyList_New (n), true);
1837 validate();
1838 for (sequence_index_type i=0; i < n; i++)
1839 {
1840 if(PyList_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
1841 {
1842 throw Exception();
1843 }
1844 }
1845 }
1846
1847 virtual size_type capacity() const
1848 {
1849 return max_size();
1850 }
1851 // Assignment acquires new ownership of pointer
1852
1853 List& operator= (const Object& rhs)
1854 {
1855 return (*this = *rhs);
1856 }
1857
1858 List& operator= (PyObject* rhsp)
1859 {
1860 if(ptr() == rhsp) return *this;
1861 set (rhsp);
1862 return *this;
1863 }
1864 // Membership
1865 virtual bool accepts (PyObject *pyob) const
1866 {
1867 return pyob && Py::_List_Check (pyob);
1868 }
1869
1870 List getSlice (int i, int j) const
1871 {
1872 return List (PyList_GetSlice (ptr(), i, j), true);
1873 }
1874
1875 void setSlice (int i, int j, const Object& v)
1876 {
1877 if(PyList_SetSlice (ptr(), i, j, *v) == -1)
1878 {
1879 throw Exception();
1880 }
1881 }
1882
1883 void append (const Object& ob)
1884 {
1885 if(PyList_Append (ptr(), *ob) == -1)
1886 {
1887 throw Exception();
1888 }
1889 }
1890
1891 void insert (int i, const Object& ob)
1892 {
1893 if(PyList_Insert (ptr(), i, *ob) == -1)
1894 {
1895 throw Exception();
1896 }
1897 }
1898
1899 void sort ()
1900 {
1901 if(PyList_Sort(ptr()) == -1)
1902 {
1903 throw Exception();
1904 }
1905 }
1906
1907 void reverse ()
1908 {
1909 if(PyList_Reverse(ptr()) == -1)
1910 {
1911 throw Exception();
1912 }
1913 }
1914 };
1915
1916
1917 // Mappings
1918 // ==================================================
1919 template<typename T>
1920 class mapref
1921 {
1922 protected:
1923 MapBase<T>& s; // the map
1924 Object key; // item key
1925 T the_item;
1926
1927 public:
1928 mapref<T> (MapBase<T>& map, const std::string& k)
1929 : s(map), the_item()
1930 {
1931 key = String(k);
1932 if(map.hasKey(key)) the_item = map.getItem(key);
1933 };
1934
1935 mapref<T> (MapBase<T>& map, const Object& k)
1936 : s(map), key(k), the_item()
1937 {
1938 if(map.hasKey(key)) the_item = map.getItem(key);
1939 };
1940
1941 ~mapref()
1942 {}
1943
1944 // MapBase<T> stuff
1945 // lvalue
1946 mapref<T>& operator=(const mapref<T>& other)
1947 {
1948 if(this == &other) return *this;
1949 the_item = other.the_item;
1950 s.setItem(key, other.the_item);
1951 return *this;
1952 };
1953
1954 mapref<T>& operator= (const T& ob)
1955 {
1956 the_item = ob;
1957 s.setItem (key, ob);
1958 return *this;
1959 }
1960
1961 // rvalue
1962 operator T() const
1963 {
1964 return the_item;
1965 }
1966
1967 // forward everything else to the_item
1968 PyObject* ptr () const
1969 {
1970 return the_item.ptr();
1971 }
1972
1973 int reference_count () const
1974 { // the mapref count
1975 return the_item.reference_count();
1976 }
1977
1978 Type type () const
1979 {
1980 return the_item.type();
1981 }
1982
1983 String str () const
1984 {
1985 return the_item.str();
1986 }
1987
1988 String repr () const
1989 {
1990 return the_item.repr();
1991 }
1992
1993 bool hasAttr (const std::string& attr_name) const
1994 {
1995 return the_item.hasAttr(attr_name);
1996 }
1997
1998 Object getAttr (const std::string& attr_name) const
1999 {
2000 return the_item.getAttr(attr_name);
2001 }
2002
2003 Object getItem (const Object& k) const
2004 {
2005 return the_item.getItem(k);
2006 }
2007
2008 long hashValue () const
2009 {
2010 return the_item.hashValue();
2011 }
2012
2013 bool isCallable () const
2014 {
2015 return the_item.isCallable();
2016 }
2017
2018 bool isList () const
2019 {
2020 return the_item.isList();
2021 }
2022
2023 bool isMapping () const
2024 {
2025 return the_item.isMapping();
2026 }
2027
2028 bool isNumeric () const
2029 {
2030 return the_item.isNumeric();
2031 }
2032
2033 bool isSequence () const
2034 {
2035 return the_item.isSequence();
2036 }
2037
2038 bool isTrue () const
2039 {
2040 return the_item.isTrue();
2041 }
2042
2043 bool isType (const Type& t) const
2044 {
2045 return the_item.isType (t);
2046 }
2047
2048 bool isTuple() const
2049 {
2050 return the_item.isTuple();
2051 }
2052
2053 bool isString() const
2054 {
2055 return the_item.isString();
2056 }
2057
2058 // Commands
2059 void setAttr (const std::string& attr_name, const Object& value)
2060 {
2061 the_item.setAttr(attr_name, value);
2062 }
2063
2064 void delAttr (const std::string& attr_name)
2065 {
2066 the_item.delAttr(attr_name);
2067 }
2068
2069 void delItem (const Object& k)
2070 {
2071 the_item.delItem(k);
2072 }
2073 }; // end of mapref
2074
2075 // TMM: now for mapref<T>
2076 template< class T >
2077 bool operator==(const mapref<T>& left, const mapref<T>& right)
2078 {
2079 return true; // NOT completed.
2080 }
2081
2082 template< class T >
2083 bool operator!=(const mapref<T>& left, const mapref<T>& right)
2084 {
2085 return true; // not completed.
2086 }
2087
2088 template<typename T>
2089 class MapBase: public Object
2090 {
2091 protected:
2092 explicit MapBase<T>()
2093 {}
2094 public:
2095 // reference: proxy class for implementing []
2096 // TMM: 26Jun'01 - the types
2097 // If you assume that Python mapping is a hash_map...
2098 // hash_map::value_type is not assignable, but
2099 // (*it).second = data must be a valid expression
2100 typedef size_t size_type;
2101 typedef Object key_type;
2102 typedef mapref<T> data_type;
2103 typedef std::pair< const T, T > value_type;
2104 typedef std::pair< const T, mapref<T> > reference;
2105 typedef const std::pair< const T, const T > const_reference;
2106 typedef std::pair< const T, mapref<T> > pointer;
2107
2108 // Constructor
2109 explicit MapBase<T> (PyObject *pyob, bool owned = false): Object(pyob, owned)
2110 {
2111 validate();
2112 }
2113
2114 // TMM: 02Jul'01 - changed MapBase<T> to Object in next line
2115 MapBase<T> (const Object& ob): Object(ob)
2116 {
2117 validate();
2118 }
2119
2120 // Assignment acquires new ownership of pointer
2121 MapBase<T>& operator= (const Object& rhs)
2122 {
2123 return (*this = *rhs);
2124 }
2125
2126 MapBase<T>& operator= (PyObject* rhsp)
2127 {
2128 if(ptr() == rhsp) return *this;
2129 set (rhsp);
2130 return *this;
2131 }
2132 // Membership
2133 virtual bool accepts (PyObject *pyob) const
2134 {
2135 return pyob && PyMapping_Check(pyob);
2136 }
2137
2138 // Clear -- PyMapping Clear is missing
2139 //
2140
2141 void clear ()
2142 {
2143 List k = keys();
2144 for(List::iterator i = k.begin(); i != k.end(); i++)
2145 {
2146 delItem(*i);
2147 }
2148 }
2149
2150 virtual size_type size() const
2151 {
2152 return PyMapping_Length (ptr());
2153 }
2154
2155 // Element Access
2156 T operator[](const std::string& key) const
2157 {
2158 return getItem(key);
2159 }
2160
2161 T operator[](const Object& key) const
2162 {
2163 return getItem(key);
2164 }
2165
2166 mapref<T> operator[](const std::string& key)
2167 {
2168 return mapref<T>(*this, key);
2169 }
2170
2171 mapref<T> operator[](const Object& key)
2172 {
2173 return mapref<T>(*this, key);
2174 }
2175
2176 int length () const
2177 {
2178 return PyMapping_Length (ptr());
2179 }
2180
2181 bool hasKey (const std::string& s) const
2182 {
2183 return PyMapping_HasKeyString (ptr(),const_cast<char*>(s.c_str())) != 0;
2184 }
2185
2186 bool hasKey (const Object& s) const
2187 {
2188 return PyMapping_HasKey (ptr(), s.ptr()) != 0;
2189 }
2190
2191 T getItem (const std::string& s) const
2192 {
2193 return T(
2194 asObject(PyMapping_GetItemString (ptr(),const_cast<char*>(s.c_str())))
2195 );
2196 }
2197
2198 T getItem (const Object& s) const
2199 {
2200 return T(
2201 asObject(PyObject_GetItem (ptr(), s.ptr()))
2202 );
2203 }
2204
2205 virtual void setItem (const char *s, const Object& ob)
2206 {
2207 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s), *ob) == -1)
2208 {
2209 throw Exception();
2210 }
2211 }
2212
2213 virtual void setItem (const std::string& s, const Object& ob)
2214 {
2215 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s.c_str()), *ob) == -1)
2216 {
2217 throw Exception();
2218 }
2219 }
2220
2221 virtual void setItem (const Object& s, const Object& ob)
2222 {
2223 if (PyObject_SetItem (ptr(), s.ptr(), ob.ptr()) == -1)
2224 {
2225 throw Exception();
2226 }
2227 }
2228
2229 void delItem (const std::string& s)
2230 {
2231 if (PyMapping_DelItemString (ptr(), const_cast<char*>(s.c_str())) == -1)
2232 {
2233 throw Exception();
2234 }
2235 }
2236
2237 void delItem (const Object& s)
2238 {
2239 if (PyMapping_DelItem (ptr(), *s) == -1)
2240 {
2241 throw Exception();
2242 }
2243 }
2244 // Queries
2245 List keys () const
2246 {
2247 return List(PyMapping_Keys(ptr()), true);
2248 }
2249
2250 List values () const
2251 { // each returned item is a (key, value) pair
2252 return List(PyMapping_Values(ptr()), true);
2253 }
2254
2255 List items () const
2256 {
2257 return List(PyMapping_Items(ptr()), true);
2258 }
2259
2260 // iterators for MapBase<T>
2261 // Added by TMM: 2Jul'01 - NOT COMPLETED
2262 // There is still a bug. I decided to stop, before fixing the bug, because
2263 // this can't be halfway efficient until Python gets built-in iterators.
2264 // My current soln is to iterate over the map by getting a copy of its keys
2265 // and iterating over that. Not a good solution.
2266
2267 // The iterator holds a MapBase<T>* rather than a MapBase<T> because that's
2268 // how the sequence iterator is implemented and it works. But it does seem
2269 // odd to me - we are iterating over the map object, not the reference.
2270
2271#if 0 // here is the test code with which I found the (still existing) bug
2272 typedef cxx::Dict d_t;
2273 d_t d;
2274 cxx::String s1("blah");
2275 cxx::String s2("gorf");
2276 d[ "one" ] = s1;
2277 d[ "two" ] = s1;
2278 d[ "three" ] = s2;
2279 d[ "four" ] = s2;
2280
2281 d_t::iterator it;
2282 it = d.begin(); // this (using the assignment operator) is causing
2283 // a problem; if I just use the copy ctor it works fine.
2284 for( ; it != d.end(); ++it )
2285 {
2286 d_t::value_type vt( *it );
2287 cxx::String rs = vt.second.repr();
2288 std::string ls = rs.operator std::string();
2289 fprintf( stderr, "%s\n", ls );
2290 }
2291#endif // 0
2292
2293 class iterator
2294 {
2295 // : public forward_iterator_parent( std::pair<const T,T> ) {
2296 protected:
2297 typedef std::forward_iterator_tag iterator_category;
2298 typedef std::pair< const T, T > value_type;
2299 typedef int difference_type;
2300 typedef std::pair< const T, mapref<T> > pointer;
2301 typedef std::pair< const T, mapref<T> > reference;
2302
2303 friend class MapBase<T>;
2304 //
2305 MapBase<T>* map;
2306 List keys; // for iterating over the map
2307 List::iterator pos; // index into the keys
2308
2309 public:
2310 ~iterator ()
2311 {}
2312
2313 iterator ()
2314 : map( 0 )
2315 , keys()
2316 , pos()
2317 {}
2318
2319 iterator (MapBase<T>* m, bool end = false )
2320 : map( m )
2321 , keys( m->keys() )
2322 , pos( end ? keys.end() : keys.begin() )
2323 {}
2324
2325 iterator (const iterator& other)
2326 : map( other.map )
2327 , keys( other.keys )
2328 , pos( other.pos )
2329 {}
2330
2331 reference operator*()
2332 {
2333 Object key = *pos;
2334 return std::make_pair(key, mapref<T>(*map,key));
2335 }
2336
2337 iterator& operator=(const iterator& other)
2338 {
2339 if (this == &other)
2340 return *this;
2341 map = other.map;
2342 keys = other.keys;
2343 pos = other.pos;
2344 return *this;
2345 }
2346
2347 bool eql(const iterator& right) const
2348 {
2349 return *map == *right.map && pos == right.pos;
2350 }
2351 bool neq( const iterator& right ) const
2352 {
2353 return *map != *right.map || pos != right.pos;
2354 }
2355
2356 // pointer operator->() {
2357 // return ;
2358 // }
2359
2360 // prefix ++
2361 iterator& operator++ ()
2362 { pos++; return *this;}
2363 // postfix ++
2364 iterator operator++ (int)
2365 { return iterator(map, keys, pos++);}
2366 // prefix --
2367 iterator& operator-- ()
2368 { pos--; return *this;}
2369 // postfix --
2370 iterator operator-- (int)
2371 { return iterator(map, keys, pos--);}
2372
2373 std::string diagnose() const
2374 {
2375 std::ostringstream oss;
2376 oss << "iterator diagnosis " << map << ", " << pos << std::ends;
2377 return std::string(oss.str());
2378 }
2379 }; // end of class MapBase<T>::iterator
2380
2381 iterator begin ()
2382 {
2383 return iterator(this);
2384 }
2385
2386 iterator end ()
2387 {
2388 return iterator(this, true);
2389 }
2390
2391 class const_iterator
2392 {
2393 protected:
2394 typedef std::forward_iterator_tag iterator_category;
2395 typedef const std::pair< const T, T > value_type;
2396 typedef int difference_type;
2397 typedef const std::pair< const T, T > pointer;
2398 typedef const std::pair< const T, T > reference;
2399
2400 friend class MapBase<T>;
2401 const MapBase<T>* map;
2402 List keys; // for iterating over the map
2403 List::iterator pos; // index into the keys
2404
2405 public:
2406 ~const_iterator ()
2407 {}
2408
2409 const_iterator ()
2410 : map( 0 )
2411 , keys()
2412 , pos()
2413 {}
2414
2415 const_iterator (const MapBase<T>* m, List k, List::iterator p )
2416 : map( m )
2417 , keys( k )
2418 , pos( p )
2419 {}
2420
2421 const_iterator(const const_iterator& other)
2422 : map( other.map )
2423 , keys( other.keys )
2424 , pos( other.pos )
2425 {}
2426
2427 bool eql(const const_iterator& right) const
2428 {
2429 return *map == *right.map && pos == right.pos;
2430 }
2431 bool neq( const const_iterator& right ) const
2432 {
2433 return *map != *right.map || pos != right.pos;
2434 }
2435
2436
2437 // const_reference operator*() {
2438 // Object key = *pos;
2439 // return std::make_pair( key, map->[key] );
2440 // GCC < 3 barfes on this line at the '['.
2441 // }
2442
2443 const_iterator& operator=(const const_iterator& other)
2444 {
2445 if (this == &other) return *this;
2446 map = other.map;
2447 keys = other.keys;
2448 pos = other.pos;
2449 return *this;
2450 }
2451
2452 // prefix ++
2453 const_iterator& operator++ ()
2454 { pos++; return *this;}
2455 // postfix ++
2456 const_iterator operator++ (int)
2457 { return const_iterator(map, keys, pos++);}
2458 // prefix --
2459 const_iterator& operator-- ()
2460 { pos--; return *this;}
2461 // postfix --
2462 const_iterator operator-- (int)
2463 { return const_iterator(map, keys, pos--);}
2464 }; // end of class MapBase<T>::const_iterator
2465
2466 const_iterator begin () const
2467 {
2468 return const_iterator(this, 0);
2469 }
2470
2471 const_iterator end () const
2472 {
2473 return const_iterator(this, length());
2474 }
2475
2476 }; // end of MapBase<T>
2477
2478 typedef MapBase<Object> Mapping;
2479
2480 template <typename T> bool operator==(const typename MapBase<T>::iterator& left, const typename MapBase<T>::iterator& right);
2481 template <typename T> bool operator!=(const typename MapBase<T>::iterator& left, const typename MapBase<T>::iterator& right);
2482 template <typename T> bool operator==(const typename MapBase<T>::const_iterator& left, const typename MapBase<T>::const_iterator& right);
2483 template <typename T> bool operator!=(const typename MapBase<T>::const_iterator& left, const typename MapBase<T>::const_iterator& right);
2484
2485 extern bool operator==(const Mapping::iterator& left, const Mapping::iterator& right);
2486 extern bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right);
2487 extern bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
2488 extern bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
2489
2490
2491 // ==================================================
2492 // class Dict
2493 class Dict: public Mapping
2494 {
2495 public:
2496 // Constructor
2497 explicit Dict (PyObject *pyob, bool owned=false): Mapping (pyob, owned)
2498 {
2499 validate();
2500 }
2501 Dict (const Dict& ob): Mapping(ob)
2502 {
2503 validate();
2504 }
2505 // Creation
2506 Dict ()
2507 {
2508 set(PyDict_New (), true);
2509 validate();
2510 }
2511 // Assignment acquires new ownership of pointer
2512
2513 Dict& operator= (const Object& rhs)
2514 {
2515 return (*this = *rhs);
2516 }
2517
2518 Dict& operator= (PyObject* rhsp)
2519 {
2520 if(ptr() == rhsp) return *this;
2521 set(rhsp);
2522 return *this;
2523 }
2524 // Membership
2525 virtual bool accepts (PyObject *pyob) const
2526 {
2527 return pyob && Py::_Dict_Check (pyob);
2528 }
2529 };
2530
2531 class Callable: public Object
2532 {
2533 protected:
2534 explicit Callable (): Object()
2535 {}
2536 public:
2537 // Constructor
2538 explicit Callable (PyObject *pyob, bool owned = false): Object (pyob, owned)
2539 {
2540 validate();
2541 }
2542
2543 Callable (const Object& ob): Object(ob)
2544 {
2545 validate();
2546 }
2547
2548 // Assignment acquires new ownership of pointer
2549
2550 Callable& operator= (const Object& rhs)
2551 {
2552 return (*this = *rhs);
2553 }
2554
2555 Callable& operator= (PyObject* rhsp)
2556 {
2557 if(ptr() == rhsp) return *this;
2558 set (rhsp);
2559 return *this;
2560 }
2561
2562 // Membership
2563 virtual bool accepts (PyObject *pyob) const
2564 {
2565 return pyob && PyCallable_Check (pyob);
2566 }
2567
2568 // Call
2569 Object apply(const Tuple& args) const
2570 {
2571 return asObject(PyObject_CallObject(ptr(), args.ptr()));
2572 }
2573
2574 // Call with keywords
2575 Object apply(const Tuple& args, const Dict& kw) const
2576 {
2577 return asObject(PyObject_CallObject(ptr(), args.ptr(), kw.ptr()));
2578 }
2579
2580 Object apply(PyObject* pargs = 0) const
2581 {
2582 return apply (Tuple(pargs));
2583 }
2584 };
2585
2586 class Module: public Object
2587 {
2588 public:
2589 explicit Module (PyObject* pyob, bool owned = false): Object (pyob, owned)
2590 {
2591 validate();
2592 }
2593
2594 // Construct from module name
2595 explicit Module (const std::string&s): Object()
2596 {
2597 PyObject *m = PyImport_AddModule( const_cast<char *>(s.c_str()) );
2598 set( m, false );
2599 validate ();
2600 }
2601
2602 // Copy constructor acquires new ownership of pointer
2603 Module (const Module& ob): Object(*ob)
2604 {
2605 validate();
2606 }
2607
2608 Module& operator= (const Object& rhs)
2609 {
2610 return (*this = *rhs);
2611 }
2612
2613 Module& operator= (PyObject* rhsp)
2614 {
2615 if(ptr() == rhsp) return *this;
2616 set(rhsp);
2617 return *this;
2618 }
2619
2620 Dict getDict()
2621 {
2622 return Dict(PyModule_GetDict(ptr()));
2623 // Caution -- PyModule_GetDict returns borrowed reference!
2624 }
2625 };
2626
2627 // Numeric interface
2628 inline Object operator+ (const Object& a)
2629 {
2630 return asObject(PyNumber_Positive(*a));
2631 }
2632 inline Object operator- (const Object& a)
2633 {
2634 return asObject(PyNumber_Negative(*a));
2635 }
2636
2637 inline Object abs(const Object& a)
2638 {
2639 return asObject(PyNumber_Absolute(*a));
2640 }
2641
2642 inline std::pair<Object,Object> coerce(const Object& a, const Object& b)
2643 {
2644 PyObject *p1, *p2;
2645 p1 = *a;
2646 p2 = *b;
2647 if(PyNumber_Coerce(&p1,&p2) == -1)
2648 {
2649 throw Exception();
2650 }
2651 return std::pair<Object,Object>(asObject(p1), asObject(p2));
2652 }
2653
2654 inline Object operator+ (const Object& a, const Object& b)
2655 {
2656 return asObject(PyNumber_Add(*a, *b));
2657 }
2658 inline Object operator+ (const Object& a, int j)
2659 {
2660 return asObject(PyNumber_Add(*a, *Int(j)));
2661 }
2662 inline Object operator+ (const Object& a, double v)
2663 {
2664 return asObject(PyNumber_Add(*a, *Float(v)));
2665 }
2666 inline Object operator+ (int j, const Object& b)
2667 {
2668 return asObject(PyNumber_Add(*Int(j), *b));
2669 }
2670 inline Object operator+ (double v, const Object& b)
2671 {
2672 return asObject(PyNumber_Add(*Float(v), *b));
2673 }
2674
2675 inline Object operator- (const Object& a, const Object& b)
2676 {
2677 return asObject(PyNumber_Subtract(*a, *b));
2678 }
2679 inline Object operator- (const Object& a, int j)
2680 {
2681 return asObject(PyNumber_Subtract(*a, *Int(j)));
2682 }
2683 inline Object operator- (const Object& a, double v)
2684 {
2685 return asObject(PyNumber_Subtract(*a, *Float(v)));
2686 }
2687 inline Object operator- (int j, const Object& b)
2688 {
2689 return asObject(PyNumber_Subtract(*Int(j), *b));
2690 }
2691 inline Object operator- (double v, const Object& b)
2692 {
2693 return asObject(PyNumber_Subtract(*Float(v), *b));
2694 }
2695
2696 inline Object operator* (const Object& a, const Object& b)
2697 {
2698 return asObject(PyNumber_Multiply(*a, *b));
2699 }
2700 inline Object operator* (const Object& a, int j)
2701 {
2702 return asObject(PyNumber_Multiply(*a, *Int(j)));
2703 }
2704 inline Object operator* (const Object& a, double v)
2705 {
2706 return asObject(PyNumber_Multiply(*a, *Float(v)));
2707 }
2708 inline Object operator* (int j, const Object& b)
2709 {
2710 return asObject(PyNumber_Multiply(*Int(j), *b));
2711 }
2712 inline Object operator* (double v, const Object& b)
2713 {
2714 return asObject(PyNumber_Multiply(*Float(v), *b));
2715 }
2716
2717 inline Object operator/ (const Object& a, const Object& b)
2718 {
2719 return asObject(PyNumber_Divide(*a, *b));
2720 }
2721 inline Object operator/ (const Object& a, int j)
2722 {
2723 return asObject(PyNumber_Divide(*a, *Int(j)));
2724 }
2725 inline Object operator/ (const Object& a, double v)
2726 {
2727 return asObject(PyNumber_Divide(*a, *Float(v)));
2728 }
2729 inline Object operator/ (int j, const Object& b)
2730 {
2731 return asObject(PyNumber_Divide(*Int(j), *b));
2732 }
2733 inline Object operator/ (double v, const Object& b)
2734 {
2735 return asObject(PyNumber_Divide(*Float(v), *b));
2736 }
2737
2738 inline Object operator% (const Object& a, const Object& b)
2739 {
2740 return asObject(PyNumber_Remainder(*a, *b));
2741 }
2742 inline Object operator% (const Object& a, int j)
2743 {
2744 return asObject(PyNumber_Remainder(*a, *Int(j)));
2745 }
2746 inline Object operator% (const Object& a, double v)
2747 {
2748 return asObject(PyNumber_Remainder(*a, *Float(v)));
2749 }
2750 inline Object operator% (int j, const Object& b)
2751 {
2752 return asObject(PyNumber_Remainder(*Int(j), *b));
2753 }
2754 inline Object operator% (double v, const Object& b)
2755 {
2756 return asObject(PyNumber_Remainder(*Float(v), *b));
2757 }
2758
2759 inline Object type(const Exception&) // return the type of the error
2760 {
2761 PyObject *ptype, *pvalue, *ptrace;
2762 PyErr_Fetch(&ptype, &pvalue, &ptrace);
2763 Object result(ptype);
2764 PyErr_Restore(ptype, pvalue, ptrace);
2765 return result;
2766 }
2767
2768 inline Object value(const Exception&) // return the value of the error
2769 {
2770 PyObject *ptype, *pvalue, *ptrace;
2771 PyErr_Fetch(&ptype, &pvalue, &ptrace);
2772 Object result;
2773 if(pvalue) result = pvalue;
2774 PyErr_Restore(ptype, pvalue, ptrace);
2775 return result;
2776 }
2777
2778 inline Object trace(const Exception&) // return the traceback of the error
2779 {
2780 PyObject *ptype, *pvalue, *ptrace;
2781 PyErr_Fetch(&ptype, &pvalue, &ptrace);
2782 Object result;
2783 if(ptrace) result = ptrace;
2784 PyErr_Restore(ptype, pvalue, ptrace);
2785 return result;
2786 }
2787
2788
2789
2790template<typename T>
2791String seqref<T>::str () const
2792 {
2793 return the_item.str();
2794 }
2795
2796template<typename T>
2797String seqref<T>::repr () const
2798 {
2799 return the_item.repr();
2800 }
2801
2802
2803 } // namespace Py
2804#endif // __CXX_Objects__h
TDEAction * back(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
TDEAction * clear(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
const char * name(StdAction id)
@ String
string
Definition property.h:71
@ List
TQValueList<TQVariant>
Definition property.h:70