1 //-----------------------------------------------------------------------------
2 //
3 // Copyright (c) 1998 - 2007, The Regents of the University of California
4 // Produced at the Lawrence Livermore National Laboratory
5 // All rights reserved.
6 //
7 // This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
8 // full copyright notice is contained in the file COPYRIGHT located at the root
9 // of the PyCXX distribution.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are met:
13 //
14 // - Redistributions of source code must retain the above copyright notice,
15 // this list of conditions and the disclaimer below.
16 // - Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the disclaimer (as noted below) in the
18 // documentation and/or materials provided with the distribution.
19 // - Neither the name of the UC/LLNL nor the names of its contributors may be
20 // used to endorse or promote products derived from this software without
21 // specific prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 // ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
27 // CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR
28 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
34 // DAMAGE.
35 //
36 //-----------------------------------------------------------------------------
37
38 #ifndef __CXX_Objects__h
39 #define __CXX_Objects__h
40
41 #include "CXX/WrapPython.h"
42 #include "CXX/Version.hxx"
43 #include "CXX/Config.hxx"
44 #include "CXX/Exception.hxx"
45
46 #include <iostream>
47 #include STR_STREAM
48 #include <string>
49 #include <iterator>
50 #include <utility>
51 #include <typeinfo>
52 #include <algorithm>
53
54
55 namespace Py
56 {
57 void ifPyErrorThrowCxxException();
58
59 typedef PyCxx_ssize_t sequence_index_type; // type of an index into a sequence
60
61 // Forward declarations
62 class Object;
63 class Type;
64 template<TEMPLATE_TYPENAME T> class SeqBase;
65 class String;
66 class List;
67 template<TEMPLATE_TYPENAME T> class MapBase;
68 class Tuple;
69 class Dict;
70
71 // new_reference_to also overloaded below on Object
new_reference_to(PyObject * p)72 inline PyObject* new_reference_to(PyObject* p)
73 {
74 Py::_XINCREF(p);
75 return p;
76 }
77
78 // returning Null() from an extension method triggers a
79 // Python exception
Null()80 inline PyObject* Null()
81 {
82 return (static_cast<PyObject*>(0));
83 }
84
85 //===========================================================================//
86 // class Object
87 // The purpose of this class is to serve as the most general kind of
88 // Python object, for the purpose of writing C++ extensions in Python
89 // Objects hold a PyObject* which they own. This pointer is always a
90 // valid pointer to a Python object. In children we must maintain this behavior.
91 //
92 // Instructions on how to make your own class MyType descended from Object:
93 // (0) Pick a base class, either Object or perhaps SeqBase<T> or MapBase<T>.
94 // This example assumes Object.
95
96 // (1) Write a routine int MyType_Check (PyObject *) modeled after PyInt_Check,
97 // PyFloat_Check, etc.
98
99 // (2) Add method accepts:
100 // virtual bool accepts (PyObject *pyob) const {
101 // return pyob && MyType_Check (pyob);
102 // }
103
104 // (3) Include the following constructor and copy constructor
105 //
106 /*
107 explicit MyType (PyObject *pyob): Object(pyob) {
108 validate();
109 }
110
111 MyType(const Object& other): Object(other.ptr()) {
112 validate();
113 }
114 */
115
116 // Alernate version for the constructor to allow for construction from owned pointers:
117 /*
118 explicit MyType (PyObject *pyob)
119 : Object(pyob) {
120 validate();
121 }
122 */
123
124 // You may wish to add other constructors; see the classes below for examples.
125 // Each constructor must use "set" to set the pointer
126 // and end by validating the pointer you have created.
127
128 // (4) Each class needs at least these two assignment operators:
129 /*
130 MyType& operator= (const Object& rhs) {
131 return (*this = *rhs);
132 }
133
134 Mytype& operator= (PyObject* rhsp) {
135 if(ptr() == rhsp) return *this;
136 set(rhsp);
137 return *this;
138 }
139 */
140 // Note on accepts: constructors call the base class
141 // version of a virtual when calling the base class constructor,
142 // so the test has to be done explicitly in a descendent.
143
144 // If you are inheriting from PythonExtension<T> to define an object
145 // note that it contains PythonExtension<T>::check
146 // which you can use in accepts when writing a wrapper class.
147 // See Demo/range.h and Demo/range.cxx for an example.
148
149 class Object
150 {
151 private:
152 // the pointer to the Python object
153 // Only Object sets this directly.
154 // The default constructor for Object sets it to Py_None and
155 // child classes must use "set" to set it
156 //
157 PyObject* p;
158
159 protected:
160
set(PyObject * pyob,bool owned=false)161 void set (PyObject* pyob, bool owned = false)
162 {
163 release();
164 p = pyob;
165 if (!owned)
166 {
167 Py::_XINCREF (p);
168 }
169 validate();
170 }
171
release()172 void release ()
173 {
174 Py::_XDECREF (p);
175 p = 0;
176 }
177
178 void validate();
179
180 public:
181 // Constructor acquires new ownership of pointer unless explicitly told not to.
Object(PyObject * pyob=Py::_None (),bool owned=false)182 explicit Object (PyObject* pyob=Py::_None(), bool owned = false)
183 : p(pyob)
184 {
185 if(!owned)
186 {
187 Py::_XINCREF (p);
188 }
189 validate();
190 }
191
192 // Copy constructor acquires new ownership of pointer
Object(const Object & ob)193 Object (const Object& ob)
194 : p(ob.p)
195 {
196 Py::_XINCREF (p);
197 validate();
198 }
199
200 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)201 Object& operator= (const Object& rhs)
202 {
203 set(rhs.p);
204 return *this;
205 }
206
operator =(PyObject * rhsp)207 Object& operator= (PyObject* rhsp)
208 {
209 if(ptr() == rhsp) return *this;
210 set (rhsp);
211 return *this;
212 }
213
214 // Destructor
~Object()215 virtual ~Object ()
216 {
217 release ();
218 }
219
220 // Loaning the pointer to others, retain ownership
operator *() const221 PyObject* operator* () const
222 {
223 return p;
224 }
225
226 // Explicit reference_counting changes
increment_reference_count()227 void increment_reference_count()
228 {
229 Py::_XINCREF(p);
230 }
231
decrement_reference_count()232 void decrement_reference_count()
233 {
234 // not allowed to commit suicide, however
235 if(reference_count() == 1)
236 throw RuntimeError("Object::decrement_reference_count error.");
237 Py::_XDECREF(p);
238 }
239
240 // Would like to call this pointer() but messes up STL in SeqBase<T>
ptr() const241 PyObject* ptr () const
242 {
243 return p;
244 }
245
246 //
247 // Queries
248 //
249
250 // Can pyob be used in this object's constructor?
accepts(PyObject *) const251 virtual bool accepts (PyObject *) const
252 {
253 // allow any object or NULL
254 return true;
255 }
256
reference_count() const257 Py_ssize_t reference_count () const
258 { // the reference count
259 return p ? p->ob_refcnt : 0;
260 }
261
262 Type type () const; // the type object associated with this one
263
264 String str () const; // the str() representation
265
266 std::string as_string() const;
267
268 String repr () const; // the repr () representation
269
270 List dir () const; // the dir() list
271
hasAttr(const std::string & s) const272 bool hasAttr (const std::string& s) const
273 {
274 return PyObject_HasAttrString (p, const_cast<char*>(s.c_str())) ? true: false;
275 }
276
getAttr(const std::string & s) const277 Object getAttr (const std::string& s) const
278 {
279 return Object (PyObject_GetAttrString (p, const_cast<char*>(s.c_str())), true);
280 }
281
282 Object callMemberFunction( const std::string& function_name ) const;
283 Object callMemberFunction( const std::string& function_name, const Tuple &args ) const;
284 Object callMemberFunction( const std::string& function_name, const Tuple &args, const Dict &kw ) const;
285
getItem(const Object & key) const286 Object getItem (const Object& key) const
287 {
288 return Object (PyObject_GetItem(p, *key), true);
289 }
290
hashValue() const291 long hashValue () const
292 {
293 return PyObject_Hash (p);
294 }
295
296 // convert to bool
as_bool() const297 bool as_bool() const
298 {
299 return PyObject_IsTrue( ptr() ) != 0;
300 }
301
is(PyObject * pother) const302 bool is(PyObject *pother) const
303 { // identity test
304 return p == pother;
305 }
306
is(const Object & other) const307 bool is(const Object& other) const
308 { // identity test
309 return p == other.p;
310 }
311
isNull() const312 bool isNull() const
313 {
314 return p == NULL;
315 }
316
isNone() const317 bool isNone() const
318 {
319 return p == _None();
320 }
321
isCallable() const322 bool isCallable () const
323 {
324 return PyCallable_Check (p) != 0;
325 }
326
isInstance() const327 bool isInstance () const
328 {
329 return PyInstance_Check (p) != 0;
330 }
331
isDict() const332 bool isDict () const
333 {
334 return Py::_Dict_Check (p);
335 }
336
isList() const337 bool isList () const
338 {
339 return Py::_List_Check (p);
340 }
341
isMapping() const342 bool isMapping () const
343 {
344 return PyMapping_Check (p) != 0;
345 }
346
isNumeric() const347 bool isNumeric () const
348 {
349 return PyNumber_Check (p) != 0;
350 }
351
isSequence() const352 bool isSequence () const
353 {
354 return PySequence_Check (p) != 0;
355 }
356
isTrue() const357 bool isTrue () const
358 {
359 return PyObject_IsTrue (p) != 0;
360 }
361
362 bool isType (const Type& t) const;
363
isTuple() const364 bool isTuple() const
365 {
366 return Py::_Tuple_Check(p);
367 }
368
isString() const369 bool isString() const
370 {
371 return Py::_String_Check(p) || Py::_Unicode_Check(p);
372 }
373
isUnicode() const374 bool isUnicode() const
375 {
376 return Py::_Unicode_Check( p );
377 }
378
isBoolean() const379 bool isBoolean() const
380 {
381 return Py::_Boolean_Check( p );
382 }
383
384 // Commands
setAttr(const std::string & s,const Object & value)385 void setAttr (const std::string& s, const Object& value)
386 {
387 if(PyObject_SetAttrString (p, const_cast<char*>(s.c_str()), *value) == -1)
388 ifPyErrorThrowCxxException();
389 }
390
delAttr(const std::string & s)391 void delAttr (const std::string& s)
392 {
393 if(PyObject_DelAttrString (p, const_cast<char*>(s.c_str())) == -1)
394 ifPyErrorThrowCxxException();
395 }
396
397 // PyObject_SetItem is too weird to be using from C++
398 // so it is intentionally omitted.
399
delItem(const Object & key)400 void delItem (const Object& key)
401 {
402 if(PyObject_DelItem(p, *key) == -1)
403 ifPyErrorThrowCxxException();
404 }
405
406 // Equality and comparison use PyObject_RichCompareBool
407
operator ==(const Object & o2) const408 bool operator==(const Object& o2) const
409 {
410 int k = PyObject_RichCompareBool (p, *o2, Py_EQ);
411 ifPyErrorThrowCxxException();
412 return k != 0;
413 }
414
operator !=(const Object & o2) const415 bool operator!=(const Object& o2) const
416 {
417 int k = PyObject_RichCompareBool (p, *o2, Py_NE);
418 ifPyErrorThrowCxxException();
419 return k != 0;
420 }
421
operator >=(const Object & o2) const422 bool operator>=(const Object& o2) const
423 {
424 int k = PyObject_RichCompareBool (p, *o2, Py_GE);
425 ifPyErrorThrowCxxException();
426 return k != 0;
427 }
428
operator <=(const Object & o2) const429 bool operator<=(const Object& o2) const
430 {
431 int k = PyObject_RichCompareBool (p, *o2, Py_LE);
432 ifPyErrorThrowCxxException();
433 return k != 0;
434 }
435
operator <(const Object & o2) const436 bool operator<(const Object& o2) const
437 {
438 int k = PyObject_RichCompareBool (p, *o2, Py_LT);
439 ifPyErrorThrowCxxException();
440 return k != 0;
441 }
442
operator >(const Object & o2) const443 bool operator>(const Object& o2) const
444 {
445 int k = PyObject_RichCompareBool (p, *o2, Py_GT);
446 ifPyErrorThrowCxxException();
447 return k != 0;
448 }
449 };
450 // End of class Object
new_reference_to(const Object & g)451 inline PyObject* new_reference_to(const Object& g)
452 {
453 PyObject* p = g.ptr();
454 Py::_XINCREF(p);
455 return p;
456 }
457
458 // Nothing() is what an extension method returns if
459 // there is no other return value.
Nothing()460 inline Object Nothing()
461 {
462 return Object(Py::_None());
463 }
464
465 // Python special None value
None()466 inline Object None()
467 {
468 return Object(Py::_None());
469 }
470
471 // Python special Boolean values
False()472 inline Object False()
473 {
474 return Object(Py::_False());
475 }
476
True()477 inline Object True()
478 {
479 return Object(Py::_True());
480 }
481
482 // TMM: 31May'01 - Added the #ifndef so I can exlude iostreams.
483 #ifndef CXX_NO_IOSTREAMS
484 std::ostream& operator<< (std::ostream& os, const Object& ob);
485 #endif
486
487 // Class Type
488 class Type: public Object
489 {
490 public:
Type(PyObject * pyob,bool owned=false)491 explicit Type (PyObject* pyob, bool owned = false): Object(pyob, owned)
492 {
493 validate();
494 }
495
Type(const Object & ob)496 Type (const Object& ob): Object(*ob)
497 {
498 validate();
499 }
500
Type(const Type & t)501 Type(const Type& t): Object(t)
502 {
503 validate();
504 }
505
operator =(const Object & rhs)506 Type& operator= (const Object& rhs)
507 {
508 return (*this = *rhs);
509 }
510
operator =(PyObject * rhsp)511 Type& operator= (PyObject* rhsp)
512 {
513 if(ptr() == rhsp) return *this;
514 set (rhsp);
515 return *this;
516 }
accepts(PyObject * pyob) const517 virtual bool accepts (PyObject *pyob) const
518 {
519 return pyob && Py::_Type_Check (pyob);
520 }
521 };
522
523
524 //
525 // Convert an owned Python pointer into a CXX Object
526 //
asObject(PyObject * p)527 inline Object asObject (PyObject *p)
528 {
529 return Object(p, true);
530 }
531
532 // ===============================================
533 // class boolean
534 class Boolean: public Object
535 {
536 public:
537 // Constructor
Boolean(PyObject * pyob,bool owned=false)538 Boolean (PyObject *pyob, bool owned = false)
539 : Object (pyob, owned)
540 {
541 validate();
542 }
543
Boolean(const Boolean & ob)544 Boolean (const Boolean& ob): Object(*ob)
545 {
546 validate();
547 }
548
549 // create from bool
Boolean(bool v=false)550 Boolean (bool v=false)
551 {
552 set(PyBool_FromLong(v ? 1 : 0), true);
553 validate();
554 }
555
Boolean(const Object & ob)556 explicit Boolean (const Object& ob)
557 : Object( *ob )
558 {
559 validate();
560 }
561
562 // Assignment increases reference count on pointer
563
operator =(const Object & rhs)564 Boolean& operator= (const Object& rhs)
565 {
566 return (*this = *rhs);
567 }
568
operator =(PyObject * rhsp)569 Boolean& operator= (PyObject* rhsp)
570 {
571 if(ptr() == rhsp) return *this;
572 set (rhsp);
573 return *this;
574 }
575
576 // Membership
accepts(PyObject * pyob) const577 virtual bool accepts (PyObject *pyob) const
578 {
579 return pyob && PyObject_IsTrue(pyob) != -1;
580 }
581
582 // convert to long
operator bool() const583 operator bool() const
584 {
585 return PyObject_IsTrue (ptr()) != 0;
586 }
587
operator =(bool v)588 Boolean& operator= (bool v)
589 {
590 set (PyBool_FromLong (v ? 1 : 0), true);
591 return *this;
592 }
593 };
594
595 // ===============================================
596 // class Int
597 class Int: public Object
598 {
599 public:
600 // Constructor
Int(PyObject * pyob,bool owned=false)601 Int (PyObject *pyob, bool owned = false): Object (pyob, owned)
602 {
603 validate();
604 }
605
Int(const Int & ob)606 Int (const Int& ob): Object(*ob)
607 {
608 validate();
609 }
610
611 // create from long
Int(long v=0L)612 Int (long v = 0L): Object(PyInt_FromLong(v), true)
613 {
614 validate();
615 }
616
617 // create from int
Int(int v)618 Int (int v)
619 {
620 long w = v;
621 set(PyInt_FromLong(w), true);
622 validate();
623 }
624
625 // create from bool
Int(bool v)626 Int (bool v)
627 {
628 long w = v ? 1 : 0;
629 set(PyInt_FromLong(w), true);
630 validate();
631 }
632
Int(const Object & ob)633 explicit Int (const Object& ob)
634 {
635 set(PyNumber_Int(*ob), true);
636 validate();
637 }
638
639 // Assignment acquires new ownership of pointer
640
operator =(const Object & rhs)641 Int& operator= (const Object& rhs)
642 {
643 return (*this = *rhs);
644 }
645
operator =(PyObject * rhsp)646 Int& operator= (PyObject* rhsp)
647 {
648 if(ptr() == rhsp) return *this;
649 set (PyNumber_Int(rhsp), true);
650 return *this;
651 }
652
653 // Membership
accepts(PyObject * pyob) const654 virtual bool accepts (PyObject *pyob) const
655 {
656 return pyob && Py::_Int_Check (pyob);
657 }
658
659 // convert to long
operator long() const660 operator long() const
661 {
662 return PyInt_AsLong (ptr());
663 }
664
665 #ifdef HAVE_LONG_LONG
666 // convert to long long
asLongLong() const667 PY_LONG_LONG asLongLong() const
668 {
669 return PyLong_AsLongLong (ptr());
670 }
671 // convert to unsigned long long
asUnsignedLongLong() const672 unsigned PY_LONG_LONG asUnsignedLongLong() const
673 {
674 return PyLong_AsUnsignedLongLong (ptr());
675 }
676 #endif
677
678 // assign from an int
operator =(int v)679 Int& operator= (int v)
680 {
681 set (PyInt_FromLong (long(v)), true);
682 return *this;
683 }
684
685 // assign from long
operator =(long v)686 Int& operator= (long v)
687 {
688 set (PyInt_FromLong (v), true);
689 return *this;
690 }
691
692 #ifdef HAVE_LONG_LONG
693 // assign from long long
operator =(PY_LONG_LONG v)694 Int& operator= (PY_LONG_LONG v)
695 {
696 set (PyLong_FromLongLong (v), true);
697 return *this;
698 }
699 // assign from unsigned long long
operator =(unsigned PY_LONG_LONG v)700 Int& operator= (unsigned PY_LONG_LONG v)
701 {
702 set (PyLong_FromUnsignedLongLong (v), true);
703 return *this;
704 }
705 #endif
706 };
707
708 // ===============================================
709 // class Long
710 class Long: public Object
711 {
712 public:
713 // Constructor
Long(PyObject * pyob,bool owned=false)714 explicit Long (PyObject *pyob, bool owned = false)
715 : Object (pyob, owned)
716 {
717 validate();
718 }
719
Long(const Long & ob)720 Long (const Long& ob)
721 : Object(ob.ptr())
722 {
723 validate();
724 }
725
726 // try to create from any object
Long(const Object & ob)727 explicit Long (const Object& ob)
728 : Object(PyNumber_Long(*ob), true)
729 {
730 validate();
731 }
732
733 // create from long
Long(long v=0L)734 explicit Long (long v = 0L)
735 : Object(PyLong_FromLong(v), true)
736 {
737 validate();
738 }
739
740 // create from unsigned long
Long(unsigned long v)741 explicit Long (unsigned long v)
742 : Object(PyLong_FromUnsignedLong(v), true)
743 {
744 validate();
745 }
746
747 // create from int
Long(int v)748 explicit Long (int v)
749 : Object(PyLong_FromLong(static_cast<long>(v)), true)
750 {
751 validate();
752 }
753
754 #ifdef HAVE_LONG_LONG
755 // create from long long
Long(PY_LONG_LONG v)756 explicit Long( PY_LONG_LONG v )
757 : Object( PyLong_FromLongLong( v ), true )
758 {
759 validate();
760 }
761
762 // create from unsigned long long
Long(unsigned PY_LONG_LONG v)763 explicit Long( unsigned PY_LONG_LONG v )
764 : Object( PyLong_FromUnsignedLongLong( v ), true )
765 {
766 validate();
767 }
768 #endif
769
770 // Membership
accepts(PyObject * pyob) const771 virtual bool accepts (PyObject *pyob) const
772 {
773 return pyob && Py::_Long_Check (pyob);
774 }
775
776 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)777 Long& operator= (const Object& rhs)
778 {
779 return *this = *rhs;
780 }
781
operator =(PyObject * rhsp)782 Long& operator= (PyObject* rhsp)
783 {
784 if(ptr() != rhsp)
785 set (PyNumber_Long(rhsp), true);
786 return *this;
787 }
788
789 // assign from an int
operator =(int v)790 Long& operator= (int v)
791 {
792 set(PyLong_FromLong (long(v)), true);
793 return *this;
794 }
795
796 // assign from long
operator =(long v)797 Long& operator= (long v)
798 {
799 set(PyLong_FromLong (v), true);
800 return *this;
801 }
802
803 // assign from unsigned long
operator =(unsigned long v)804 Long& operator= (unsigned long v)
805 {
806 set(PyLong_FromUnsignedLong (v), true);
807 return *this;
808 }
809
810 #ifdef HAVE_LONG_LONG
operator =(PY_LONG_LONG v)811 Long &operator=( PY_LONG_LONG v )
812 {
813 set( PyLong_FromLongLong( v ), true );
814 return *this;
815 }
816
operator =(unsigned PY_LONG_LONG v)817 Long &operator=( unsigned PY_LONG_LONG v )
818 {
819 set( PyLong_FromUnsignedLongLong( v ), true );
820 return *this;
821 }
822 #endif
823
824 // convert to long
as_long() const825 long as_long() const
826 {
827 return PyLong_AsLong( ptr() );
828 }
829
operator long() const830 operator long() const
831 {
832 return as_long();
833 }
834
operator int() const835 operator int() const
836 {
837 return static_cast<int>( as_long() );
838 }
839
840 // convert to unsigned
as_unsigned_long() const841 long as_unsigned_long() const
842 {
843 return PyLong_AsUnsignedLong( ptr() );
844 }
845
846 // convert to unsigned
operator unsigned long() const847 operator unsigned long() const
848 {
849 return as_unsigned_long();
850 }
851
as_double() const852 double as_double() const
853 {
854 return PyLong_AsDouble( ptr() );
855 }
856
operator double() const857 operator double() const
858 {
859 return as_double();
860 }
861
862 #ifdef HAVE_LONG_LONG
as_long_long() const863 PY_LONG_LONG as_long_long() const
864 {
865 return PyLong_AsLongLong( ptr() );
866 }
867
operator PY_LONG_LONG() const868 operator PY_LONG_LONG() const
869 {
870 return as_long_long();
871 }
872
as_unsigned_long_long() const873 unsigned PY_LONG_LONG as_unsigned_long_long() const
874 {
875 return PyLong_AsUnsignedLongLong( ptr() );
876 }
877
operator unsigned PY_LONG_LONG() const878 operator unsigned PY_LONG_LONG() const
879 {
880 return as_unsigned_long_long();
881 }
882 #endif
883
884 // prefix ++
operator ++()885 Long operator++()
886 {
887 set( PyNumber_Add( ptr(), *Long( 1 ) ) );
888 return *this;
889 }
890
891 // postfix ++
operator ++(int)892 Long operator++( int )
893 {
894 Long a = *this;
895 set( PyNumber_Add( ptr(), *Long( 1 ) ) );
896 return a;
897 }
898
899 // prefix --
operator --()900 Long operator--()
901 {
902 set( PyNumber_Subtract( ptr(), *Long( 1 ) ) );
903 return *this;
904 }
905
906 // postfix --
operator --(int)907 Long operator--( int )
908 {
909 Long a = *this;
910 set( PyNumber_Subtract( ptr(), *Long( 1 ) ) );
911 return a;
912 }
913 };
914
915 #ifdef HAVE_LONG_LONG
916 // ===============================================
917 // class LongLong
918 class LongLong: public Object
919 {
920 public:
921 // Constructor
LongLong(PyObject * pyob,bool owned=false)922 explicit LongLong (PyObject *pyob, bool owned = false): Object (pyob, owned)
923 {
924 validate();
925 }
926
LongLong(const LongLong & ob)927 LongLong (const LongLong& ob): Object(ob.ptr())
928 {
929 validate();
930 }
931 // create from long long
LongLong(PY_LONG_LONG v=0L)932 explicit LongLong (PY_LONG_LONG v = 0L)
933 : Object(PyLong_FromLongLong(v), true)
934 {
935 validate();
936 }
937 // create from unsigned long long
LongLong(unsigned PY_LONG_LONG v)938 explicit LongLong (unsigned PY_LONG_LONG v)
939 : Object(PyLong_FromUnsignedLongLong(v), true)
940 {
941 validate();
942 }
943 // create from long
LongLong(long v)944 explicit LongLong (long v)
945 : Object(PyLong_FromLongLong(v), true)
946 {
947 validate();
948 }
949 // create from unsigned long
LongLong(unsigned long v)950 explicit LongLong (unsigned long v)
951 : Object(PyLong_FromUnsignedLongLong(v), true)
952 {
953 validate();
954 }
955 // create from int
LongLong(int v)956 explicit LongLong (int v)
957 : Object(PyLong_FromLongLong(static_cast<PY_LONG_LONG>(v)), true)
958 {
959 validate();
960 }
961
962 // try to create from any object
LongLong(const Object & ob)963 LongLong (const Object& ob)
964 : Object(PyNumber_Long(*ob), true)
965 {
966 validate();
967 }
968
969 // Assignment acquires new ownership of pointer
970
operator =(const Object & rhs)971 LongLong& operator= (const Object& rhs)
972 {
973 return (*this = *rhs);
974 }
975
operator =(PyObject * rhsp)976 LongLong& operator= (PyObject* rhsp)
977 {
978 if(ptr() == rhsp) return *this;
979 set (PyNumber_Long(rhsp), true);
980 return *this;
981 }
982 // Membership
accepts(PyObject * pyob) const983 virtual bool accepts (PyObject *pyob) const
984 {
985 return pyob && Py::_Long_Check (pyob);
986 }
987 // convert to long long
operator PY_LONG_LONG() const988 operator PY_LONG_LONG() const
989 {
990 return PyLong_AsLongLong (ptr());
991 }
992 // convert to unsigned long
operator unsigned PY_LONG_LONG() const993 operator unsigned PY_LONG_LONG() const
994 {
995 return PyLong_AsUnsignedLongLong (ptr());
996 }
997 // convert to long
operator long() const998 operator long() const
999 {
1000 return PyLong_AsLong (ptr());
1001 }
1002 // convert to unsigned
operator unsigned long() const1003 operator unsigned long() const
1004 {
1005 return PyLong_AsUnsignedLong (ptr());
1006 }
operator double() const1007 operator double() const
1008 {
1009 return PyLong_AsDouble (ptr());
1010 }
1011 // assign from an int
operator =(int v)1012 LongLong& operator= (int v)
1013 {
1014 set(PyLong_FromLongLong (long(v)), true);
1015 return *this;
1016 }
1017 // assign from long long
operator =(PY_LONG_LONG v)1018 LongLong& operator= (PY_LONG_LONG v)
1019 {
1020 set(PyLong_FromLongLong (v), true);
1021 return *this;
1022 }
1023 // assign from unsigned long long
operator =(unsigned PY_LONG_LONG v)1024 LongLong& operator= (unsigned PY_LONG_LONG v)
1025 {
1026 set(PyLong_FromUnsignedLongLong (v), true);
1027 return *this;
1028 }
1029 // assign from long
operator =(long v)1030 LongLong& operator= (long v)
1031 {
1032 set(PyLong_FromLongLong (v), true);
1033 return *this;
1034 }
1035 // assign from unsigned long
operator =(unsigned long v)1036 LongLong& operator= (unsigned long v)
1037 {
1038 set(PyLong_FromUnsignedLongLong (v), true);
1039 return *this;
1040 }
1041 };
1042 #endif
1043
1044 // ===============================================
1045 // class Float
1046 //
1047 class Float: public Object
1048 {
1049 public:
1050 // Constructor
Float(PyObject * pyob,bool owned=false)1051 explicit Float (PyObject *pyob, bool owned = false): Object(pyob, owned)
1052 {
1053 validate();
1054 }
1055
Float(const Float & f)1056 Float (const Float& f): Object(f)
1057 {
1058 validate();
1059 }
1060
1061 // make from double
Float(double v=0.0)1062 explicit Float (double v=0.0)
1063 : Object(PyFloat_FromDouble (v), true)
1064 {
1065 validate();
1066 }
1067
1068 // try to make from any object
Float(const Object & ob)1069 Float (const Object& ob)
1070 : Object(PyNumber_Float(*ob), true)
1071 {
1072 validate();
1073 }
1074
operator =(const Object & rhs)1075 Float& operator= (const Object& rhs)
1076 {
1077 return (*this = *rhs);
1078 }
1079
operator =(PyObject * rhsp)1080 Float& operator= (PyObject* rhsp)
1081 {
1082 if(ptr() == rhsp) return *this;
1083 set (PyNumber_Float(rhsp), true);
1084 return *this;
1085 }
1086 // Membership
accepts(PyObject * pyob) const1087 virtual bool accepts (PyObject *pyob) const
1088 {
1089 return pyob && Py::_Float_Check (pyob);
1090 }
1091 // convert to double
operator double() const1092 operator double () const
1093 {
1094 return PyFloat_AsDouble (ptr());
1095 }
1096 // assign from a double
operator =(double v)1097 Float& operator= (double v)
1098 {
1099 set(PyFloat_FromDouble (v), true);
1100 return *this;
1101 }
1102 // assign from an int
operator =(int v)1103 Float& operator= (int v)
1104 {
1105 set(PyFloat_FromDouble (double(v)), true);
1106 return *this;
1107 }
1108 // assign from long
operator =(long v)1109 Float& operator= (long v)
1110 {
1111 set(PyFloat_FromDouble (double(v)), true);
1112 return *this;
1113 }
1114 // assign from an Int
operator =(const Int & iob)1115 Float& operator= (const Int& iob)
1116 {
1117 set(PyFloat_FromDouble (double(long(iob))), true);
1118 return *this;
1119 }
1120 };
1121
1122 // ===============================================
1123 // class Complex
1124 class Complex: public Object
1125 {
1126 public:
1127 // Constructor
Complex(PyObject * pyob,bool owned=false)1128 explicit Complex (PyObject *pyob, bool owned = false): Object(pyob, owned)
1129 {
1130 validate();
1131 }
1132
Complex(const Complex & f)1133 Complex (const Complex& f): Object(f)
1134 {
1135 validate();
1136 }
1137
1138 // make from double
Complex(double v=0.0,double w=0.0)1139 explicit Complex (double v=0.0, double w=0.0)
1140 :Object(PyComplex_FromDoubles (v, w), true)
1141 {
1142 validate();
1143 }
1144
operator =(const Object & rhs)1145 Complex& operator= (const Object& rhs)
1146 {
1147 return (*this = *rhs);
1148 }
1149
operator =(PyObject * rhsp)1150 Complex& operator= (PyObject* rhsp)
1151 {
1152 if(ptr() == rhsp) return *this;
1153 set (rhsp);
1154 return *this;
1155 }
1156 // Membership
accepts(PyObject * pyob) const1157 virtual bool accepts (PyObject *pyob) const
1158 {
1159 return pyob && Py::_Complex_Check (pyob);
1160 }
1161 // convert to Py_complex
operator Py_complex() const1162 operator Py_complex () const
1163 {
1164 return PyComplex_AsCComplex (ptr());
1165 }
1166 // assign from a Py_complex
operator =(const Py_complex & v)1167 Complex& operator= (const Py_complex& v)
1168 {
1169 set(PyComplex_FromCComplex (v), true);
1170 return *this;
1171 }
1172 // assign from a double
operator =(double v)1173 Complex& operator= (double v)
1174 {
1175 set(PyComplex_FromDoubles (v, 0.0), true);
1176 return *this;
1177 }
1178 // assign from an int
operator =(int v)1179 Complex& operator= (int v)
1180 {
1181 set(PyComplex_FromDoubles (double(v), 0.0), true);
1182 return *this;
1183 }
1184 // assign from long
operator =(long v)1185 Complex& operator= (long v)
1186 {
1187 set(PyComplex_FromDoubles (double(v), 0.0), true);
1188 return *this;
1189 }
1190 // assign from an Int
operator =(const Int & iob)1191 Complex& operator= (const Int& iob)
1192 {
1193 set(PyComplex_FromDoubles (double(long(iob)), 0.0), true);
1194 return *this;
1195 }
1196
real() const1197 double real() const
1198 {
1199 return PyComplex_RealAsDouble(ptr());
1200 }
1201
imag() const1202 double imag() const
1203 {
1204 return PyComplex_ImagAsDouble(ptr());
1205 }
1206 };
1207 // Sequences
1208 // Sequences are here represented as sequences of items of type T.
1209 // The base class SeqBase<T> represents that.
1210 // In basic Python T is always "Object".
1211
1212 // seqref<T> is what you get if you get elements from a non-const SeqBase<T>.
1213 // Note: seqref<T> could probably be a nested class in SeqBase<T> but that might stress
1214 // some compilers needlessly. Simlarly for mapref later.
1215
1216 // While this class is not intended for enduser use, it needs some public
1217 // constructors for the benefit of the STL.
1218
1219 // See Scott Meyer's More Essential C++ for a description of proxies.
1220 // This application is even more complicated. We are doing an unusual thing
1221 // in having a double proxy. If we want the STL to work
1222 // properly we have to compromise by storing the rvalue inside. The
1223 // entire Object API is repeated so that things like s[i].isList() will
1224 // work properly.
1225
1226 // Still, once in a while a weird compiler message may occur using expressions like x[i]
1227 // Changing them to Object(x[i]) helps the compiler to understand that the
1228 // conversion of a seqref to an Object is wanted.
1229
1230 template<TEMPLATE_TYPENAME T>
1231 class seqref
1232 {
1233 protected:
1234 SeqBase<T>& s; // the sequence
1235 sequence_index_type offset; // item number
1236 T the_item; // lvalue
1237 public:
1238
seqref(SeqBase<T> & seq,sequence_index_type j)1239 seqref (SeqBase<T>& seq, sequence_index_type j)
1240 : s(seq), offset(j), the_item (s.getItem(j))
1241 {}
1242
seqref(const seqref<T> & range)1243 seqref (const seqref<T>& range)
1244 : s(range.s), offset(range.offset), the_item(range.the_item)
1245 {}
1246
1247 // TMM: added this seqref ctor for use with STL algorithms
seqref(Object & obj)1248 seqref (Object& obj)
1249 : s(dynamic_cast< SeqBase<T>&>(obj))
1250 , offset( 0 )
1251 , the_item(s.getItem(offset))
1252 {}
~seqref()1253 ~seqref()
1254 {}
1255
operator T() const1256 operator T() const
1257 { // rvalue
1258 return the_item;
1259 }
1260
operator =(const seqref<T> & rhs)1261 seqref<T>& operator=(const seqref<T>& rhs)
1262 { //used as lvalue
1263 the_item = rhs.the_item;
1264 s.setItem(offset, the_item);
1265 return *this;
1266 }
1267
operator =(const T & ob)1268 seqref<T>& operator=(const T& ob)
1269 { // used as lvalue
1270 the_item = ob;
1271 s.setItem(offset, ob);
1272 return *this;
1273 }
1274
1275 // forward everything else to the item
ptr() const1276 PyObject* ptr () const
1277 {
1278 return the_item.ptr();
1279 }
1280
reference_count() const1281 int reference_count () const
1282 { // the reference count
1283 return the_item.reference_count();
1284 }
1285
type() const1286 Type type () const
1287 {
1288 return the_item.type();
1289 }
1290
1291 String str () const;
1292
1293 String repr () const;
1294
hasAttr(const std::string & attr_name) const1295 bool hasAttr (const std::string& attr_name) const
1296 {
1297 return the_item.hasAttr(attr_name);
1298 }
1299
getAttr(const std::string & attr_name) const1300 Object getAttr (const std::string& attr_name) const
1301 {
1302 return the_item.getAttr(attr_name);
1303 }
1304
getItem(const Object & key) const1305 Object getItem (const Object& key) const
1306 {
1307 return the_item.getItem(key);
1308 }
1309
hashValue() const1310 long hashValue () const
1311 {
1312 return the_item.hashValue();
1313 }
1314
isCallable() const1315 bool isCallable () const
1316 {
1317 return the_item.isCallable();
1318 }
1319
isInstance() const1320 bool isInstance () const
1321 {
1322 return the_item.isInstance();
1323 }
1324
isDict() const1325 bool isDict () const
1326 {
1327 return the_item.isDict();
1328 }
1329
isList() const1330 bool isList () const
1331 {
1332 return the_item.isList();
1333 }
1334
isMapping() const1335 bool isMapping () const
1336 {
1337 return the_item.isMapping();
1338 }
1339
isNumeric() const1340 bool isNumeric () const
1341 {
1342 return the_item.isNumeric();
1343 }
1344
isSequence() const1345 bool isSequence () const
1346 {
1347 return the_item.isSequence();
1348 }
1349
isTrue() const1350 bool isTrue () const
1351 {
1352 return the_item.isTrue();
1353 }
1354
isType(const Type & t) const1355 bool isType (const Type& t) const
1356 {
1357 return the_item.isType (t);
1358 }
1359
isTuple() const1360 bool isTuple() const
1361 {
1362 return the_item.isTuple();
1363 }
1364
isString() const1365 bool isString() const
1366 {
1367 return the_item.isString();
1368 }
1369 // Commands
setAttr(const std::string & attr_name,const Object & value)1370 void setAttr (const std::string& attr_name, const Object& value)
1371 {
1372 the_item.setAttr(attr_name, value);
1373 }
1374
delAttr(const std::string & attr_name)1375 void delAttr (const std::string& attr_name)
1376 {
1377 the_item.delAttr(attr_name);
1378 }
1379
delItem(const Object & key)1380 void delItem (const Object& key)
1381 {
1382 the_item.delItem(key);
1383 }
1384
operator ==(const Object & o2) const1385 bool operator==(const Object& o2) const
1386 {
1387 return the_item == o2;
1388 }
1389
operator !=(const Object & o2) const1390 bool operator!=(const Object& o2) const
1391 {
1392 return the_item != o2;
1393 }
1394
operator >=(const Object & o2) const1395 bool operator>=(const Object& o2) const
1396 {
1397 return the_item >= o2;
1398 }
1399
operator <=(const Object & o2) const1400 bool operator<=(const Object& o2) const
1401 {
1402 return the_item <= o2;
1403 }
1404
operator <(const Object & o2) const1405 bool operator<(const Object& o2) const
1406 {
1407 return the_item < o2;
1408 }
1409
operator >(const Object & o2) const1410 bool operator>(const Object& o2) const
1411 {
1412 return the_item > o2;
1413 }
1414 }; // end of seqref
1415
1416
1417 // class SeqBase<T>
1418 // ...the base class for all sequence types
1419
1420 template<TEMPLATE_TYPENAME T>
1421 class SeqBase: public Object
1422 {
1423 public:
1424 // STL definitions
1425 typedef PyCxx_ssize_t size_type;
1426 typedef seqref<T> reference;
1427 typedef T const_reference;
1428 typedef seqref<T>* pointer;
1429 typedef int difference_type;
1430 typedef T value_type; // TMM: 26Jun'01
1431
max_size() const1432 virtual size_type max_size() const
1433 {
1434 return static_cast<size_type>( std::string::npos ); // why this constant - its not from python?
1435 }
1436
capacity() const1437 virtual size_type capacity() const
1438 {
1439 return size();
1440 }
1441
swap(SeqBase<T> & c)1442 virtual void swap( SeqBase<T> &c )
1443 {
1444 SeqBase<T> temp = c;
1445 c = ptr();
1446 set(temp.ptr());
1447 }
1448
size() const1449 virtual size_type size() const
1450 {
1451 return PySequence_Length (ptr());
1452 }
1453
1454 explicit SeqBase<T> ()
1455 : Object( PyTuple_New( 0 ), true )
1456 {
1457 validate();
1458 }
1459
1460 explicit SeqBase<T> (PyObject* pyob, bool owned=false)
1461 : Object( pyob, owned )
1462 {
1463 validate();
1464 }
1465
1466 SeqBase<T> (const Object& ob): Object(ob)
1467 {
1468 validate();
1469 }
1470
1471 // Assignment acquires new ownership of pointer
1472
operator =(const Object & rhs)1473 SeqBase<T>& operator= (const Object& rhs)
1474 {
1475 return (*this = *rhs);
1476 }
1477
operator =(PyObject * rhsp)1478 SeqBase<T>& operator= (PyObject* rhsp)
1479 {
1480 if(ptr() == rhsp) return *this;
1481 set (rhsp);
1482 return *this;
1483 }
1484
accepts(PyObject * pyob) const1485 virtual bool accepts (PyObject *pyob) const
1486 {
1487 return pyob && PySequence_Check (pyob);
1488 }
1489
length() const1490 Py_ssize_t length () const
1491 {
1492 return PySequence_Length (ptr());
1493 }
1494
1495 // Element access
operator [](sequence_index_type index) const1496 const T operator[](sequence_index_type index) const
1497 {
1498 return getItem(index);
1499 }
1500
operator [](sequence_index_type index)1501 seqref<T> operator[](sequence_index_type index)
1502 {
1503 return seqref<T>(*this, index);
1504 }
1505
getItem(sequence_index_type i) const1506 virtual T getItem (sequence_index_type i) const
1507 {
1508 return T(asObject(PySequence_GetItem (ptr(), i)));
1509 }
1510
setItem(sequence_index_type i,const T & ob)1511 virtual void setItem (sequence_index_type i, const T& ob)
1512 {
1513 if (PySequence_SetItem (ptr(), i, *ob) == -1)
1514 {
1515 ifPyErrorThrowCxxException();
1516 }
1517 }
1518
repeat(int count) const1519 SeqBase<T> repeat (int count) const
1520 {
1521 return SeqBase<T> (PySequence_Repeat (ptr(), count), true);
1522 }
1523
concat(const SeqBase<T> & other) const1524 SeqBase<T> concat (const SeqBase<T>& other) const
1525 {
1526 return SeqBase<T> (PySequence_Concat(ptr(), *other), true);
1527 }
1528
1529 // more STL compatability
front() const1530 const T front () const
1531 {
1532 return getItem(0);
1533 }
1534
front()1535 seqref<T> front()
1536 {
1537 return seqref<T>(*this, 0);
1538 }
1539
back() const1540 const T back() const
1541 {
1542 return getItem(size()-1);
1543 }
1544
back()1545 seqref<T> back()
1546 {
1547 return seqref<T>(*this, size()-1);
1548 }
1549
verify_length(size_type required_size) const1550 void verify_length( size_type required_size ) const
1551 {
1552 if (size() != required_size)
1553 throw IndexError ("Unexpected SeqBase<T> length.");
1554 }
1555
verify_length(size_type min_size,size_type max_size) const1556 void verify_length( size_type min_size, size_type max_size ) const
1557 {
1558 size_type n = size();
1559 if (n < min_size || n > max_size)
1560 throw IndexError ("Unexpected SeqBase<T> length.");
1561 }
1562
1563 class iterator: public random_access_iterator_parent(seqref<T>)
1564 {
1565 protected:
1566 friend class SeqBase<T>;
1567 SeqBase<T>* seq;
1568 sequence_index_type count;
1569
1570 public:
~iterator()1571 ~iterator ()
1572 {}
1573
iterator()1574 iterator ()
1575 : seq( 0 )
1576 , count( 0 )
1577 {}
1578
iterator(SeqBase<T> * s,sequence_index_type where)1579 iterator (SeqBase<T>* s, sequence_index_type where)
1580 : seq( s )
1581 , count( where )
1582 {}
1583
iterator(const iterator & other)1584 iterator (const iterator& other)
1585 : seq( other.seq )
1586 , count( other.count )
1587 {}
1588
eql(const iterator & other) const1589 bool eql (const iterator& other) const
1590 {
1591 return (seq->ptr() == other.seq->ptr()) && (count == other.count);
1592 }
1593
neq(const iterator & other) const1594 bool neq (const iterator& other) const
1595 {
1596 return (seq->ptr() != other.seq->ptr()) || (count != other.count);
1597 }
1598
lss(const iterator & other) const1599 bool lss (const iterator& other) const
1600 {
1601 return (count < other.count);
1602 }
1603
gtr(const iterator & other) const1604 bool gtr (const iterator& other) const
1605 {
1606 return (count > other.count);
1607 }
1608
leq(const iterator & other) const1609 bool leq (const iterator& other) const
1610 {
1611 return (count <= other.count);
1612 }
1613
geq(const iterator & other) const1614 bool geq (const iterator& other) const
1615 {
1616 return (count >= other.count);
1617 }
1618
operator *()1619 seqref<T> operator*()
1620 {
1621 return seqref<T>(*seq, count);
1622 }
1623
operator [](sequence_index_type i)1624 seqref<T> operator[] (sequence_index_type i)
1625 {
1626 return seqref<T>(*seq, count + i);
1627 }
1628
operator =(const iterator & other)1629 iterator& operator=(const iterator& other)
1630 {
1631 if (this == &other) return *this;
1632 seq = other.seq;
1633 count = other.count;
1634 return *this;
1635 }
1636
operator +(sequence_index_type n) const1637 iterator operator+(sequence_index_type n) const
1638 {
1639 return iterator(seq, count + n);
1640 }
1641
operator -(sequence_index_type n) const1642 iterator operator-(sequence_index_type n) const
1643 {
1644 return iterator(seq, count - n);
1645 }
1646
operator +=(sequence_index_type n)1647 iterator& operator+=(sequence_index_type n)
1648 {
1649 count = count + n;
1650 return *this;
1651 }
1652
operator -=(sequence_index_type n)1653 iterator& operator-=(sequence_index_type n)
1654 {
1655 count = count - n;
1656 return *this;
1657 }
1658
operator -(const iterator & other) const1659 int operator-(const iterator& other) const
1660 {
1661 if (*seq != *other.seq)
1662 throw RuntimeError ("SeqBase<T>::iterator comparison error");
1663 return count - other.count;
1664 }
1665
1666 // prefix ++
operator ++()1667 iterator& operator++ ()
1668 {
1669 count++;
1670 return *this;
1671 }
1672 // postfix ++
operator ++(int)1673 iterator operator++ (int)
1674 {
1675 return iterator(seq, count++);
1676 }
1677 // prefix --
operator --()1678 iterator& operator-- ()
1679 {
1680 count--;
1681 return *this;
1682 }
1683 // postfix --
operator --(int)1684 iterator operator-- (int)
1685 {
1686 return iterator(seq, count--);
1687 }
1688
diagnose() const1689 std::string diagnose() const
1690 {
1691 std::OSTRSTREAM oss;
1692 oss << "iterator diagnosis " << seq << ", " << count << std::ends;
1693 return std::string(oss.str());
1694 }
1695 }; // end of class SeqBase<T>::iterator
1696
begin()1697 iterator begin ()
1698 {
1699 return iterator(this, 0);
1700 }
1701
end()1702 iterator end ()
1703 {
1704 return iterator(this, length());
1705 }
1706
1707 class const_iterator
1708 : public random_access_iterator_parent(const Object)
1709 {
1710 protected:
1711 friend class SeqBase<T>;
1712 const SeqBase<T>* seq;
1713 sequence_index_type count;
1714
1715 private:
const_iterator(const SeqBase<T> * s,sequence_index_type where)1716 const_iterator (const SeqBase<T>* s, sequence_index_type where)
1717 : seq( s )
1718 , count( where )
1719 {}
1720
1721 public:
~const_iterator()1722 ~const_iterator ()
1723 {}
1724
const_iterator()1725 const_iterator ()
1726 : seq( 0 )
1727 , count( 0 )
1728 {}
1729
const_iterator(const const_iterator & other)1730 const_iterator(const const_iterator& other)
1731 : seq( other.seq )
1732 , count( other.count )
1733 {}
1734
operator *() const1735 const T operator*() const
1736 {
1737 return seq->getItem(count);
1738 }
1739
operator [](sequence_index_type i) const1740 const T operator[] (sequence_index_type i) const
1741 {
1742 return seq->getItem(count + i);
1743 }
1744
operator =(const const_iterator & other)1745 const_iterator& operator=(const const_iterator& other)
1746 {
1747 if (this == &other) return *this;
1748 seq = other.seq;
1749 count = other.count;
1750 return *this;
1751 }
1752
operator +(sequence_index_type n) const1753 const_iterator operator+(sequence_index_type n) const
1754 {
1755 return const_iterator(seq, count + n);
1756 }
1757
eql(const const_iterator & other) const1758 bool eql (const const_iterator& other) const
1759 {
1760 return (seq->ptr() == other.seq->ptr()) && (count == other.count);
1761 }
1762
neq(const const_iterator & other) const1763 bool neq (const const_iterator& other) const
1764 {
1765 return (seq->ptr() != other.seq->ptr()) || (count != other.count);
1766 }
1767
lss(const const_iterator & other) const1768 bool lss (const const_iterator& other) const
1769 {
1770 return (count < other.count);
1771 }
1772
gtr(const const_iterator & other) const1773 bool gtr (const const_iterator& other) const
1774 {
1775 return (count > other.count);
1776 }
1777
leq(const const_iterator & other) const1778 bool leq (const const_iterator& other) const
1779 {
1780 return (count <= other.count);
1781 }
1782
geq(const const_iterator & other) const1783 bool geq (const const_iterator& other) const
1784 {
1785 return (count >= other.count);
1786 }
1787
operator -(sequence_index_type n)1788 const_iterator operator-(sequence_index_type n)
1789 {
1790 return const_iterator(seq, count - n);
1791 }
1792
operator +=(sequence_index_type n)1793 const_iterator& operator+=(sequence_index_type n)
1794 {
1795 count = count + n;
1796 return *this;
1797 }
1798
operator -=(sequence_index_type n)1799 const_iterator& operator-=(sequence_index_type n)
1800 {
1801 count = count - n;
1802 return *this;
1803 }
1804
operator -(const const_iterator & other) const1805 int operator-(const const_iterator& other) const
1806 {
1807 if (*seq != *other.seq)
1808 throw RuntimeError ("SeqBase<T>::const_iterator::- error");
1809 return count - other.count;
1810 }
1811 // prefix ++
operator ++()1812 const_iterator& operator++ ()
1813 {
1814 count++;
1815 return *this;
1816 }
1817 // postfix ++
operator ++(int)1818 const_iterator operator++ (int)
1819 {
1820 return const_iterator(seq, count++);
1821 }
1822 // prefix --
operator --()1823 const_iterator& operator-- ()
1824 {
1825 count--;
1826 return *this;
1827 }
1828 // postfix --
operator --(int)1829 const_iterator operator-- (int)
1830 {
1831 return const_iterator(seq, count--);
1832 }
1833 }; // end of class SeqBase<T>::const_iterator
1834
begin() const1835 const_iterator begin () const
1836 {
1837 return const_iterator(this, 0);
1838 }
1839
end() const1840 const_iterator end () const
1841 {
1842 return const_iterator(this, length());
1843 }
1844 };
1845
1846 // Here's an important typedef you might miss if reading too fast...
1847 typedef SeqBase<Object> Sequence;
1848
1849 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1850 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1851 template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1852 template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1853 template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1854 template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
1855
1856 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1857 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1858 template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1859 template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1860 template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1861 template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
1862
1863 extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right);
1864 extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right);
1865 extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right);
1866 extern bool operator> (const Sequence::iterator& left, const Sequence::iterator& right);
1867 extern bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right);
1868 extern bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right);
1869
1870 extern bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1871 extern bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1872 extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1873 extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1874 extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1875 extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
1876
1877 // ==================================================
1878 // class Char
1879 // Python strings return strings as individual elements.
1880 // I'll try having a class Char which is a String of length 1
1881 //
1882 typedef std::basic_string<Py_UNICODE> unicodestring;
1883 extern Py_UNICODE unicode_null_string[1];
1884
1885 class Char: public Object
1886 {
1887 public:
Char(PyObject * pyob,bool owned=false)1888 explicit Char (PyObject *pyob, bool owned = false): Object(pyob, owned)
1889 {
1890 validate();
1891 }
1892
Char(const Object & ob)1893 Char (const Object& ob): Object(ob)
1894 {
1895 validate();
1896 }
1897
Char(const std::string & v="")1898 Char (const std::string& v = "")
1899 :Object(PyString_FromStringAndSize( const_cast<char*>(v.c_str()), 1 ), true)
1900 {
1901 validate();
1902 }
1903
Char(char v)1904 Char (char v)
1905 : Object(PyString_FromStringAndSize (&v, 1), true)
1906 {
1907 validate();
1908 }
1909
Char(Py_UNICODE v)1910 Char (Py_UNICODE v)
1911 : Object(PyUnicode_FromUnicode (&v, 1), true)
1912 {
1913 validate();
1914 }
1915 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)1916 Char& operator= (const Object& rhs)
1917 {
1918 return (*this = *rhs);
1919 }
1920
operator =(PyObject * rhsp)1921 Char& operator= (PyObject* rhsp)
1922 {
1923 if(ptr() == rhsp) return *this;
1924 set (rhsp);
1925 return *this;
1926 }
1927
1928 // Membership
accepts(PyObject * pyob) const1929 virtual bool accepts (PyObject *pyob) const
1930 {
1931 return (pyob &&
1932 (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob))
1933 && PySequence_Length (pyob) == 1);
1934 }
1935
1936 // Assignment from C string
operator =(const std::string & v)1937 Char& operator= (const std::string& v)
1938 {
1939 set(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true);
1940 return *this;
1941 }
1942
operator =(char v)1943 Char& operator= (char v)
1944 {
1945 set(PyString_FromStringAndSize (&v, 1), true);
1946 return *this;
1947 }
1948
operator =(const unicodestring & v)1949 Char& operator= (const unicodestring& v)
1950 {
1951 set(PyUnicode_FromUnicode (const_cast<Py_UNICODE*>(v.data()),1), true);
1952 return *this;
1953 }
1954
operator =(Py_UNICODE v)1955 Char& operator= (Py_UNICODE v)
1956 {
1957 set(PyUnicode_FromUnicode (&v, 1), true);
1958 return *this;
1959 }
1960
ord()1961 long ord()
1962 {
1963 if( Py::_Unicode_Check( ptr() ) )
1964 {
1965 Py_UNICODE *unicode = PyUnicode_AS_UNICODE( ptr() );
1966 return static_cast<long>( unicode[0] );
1967 }
1968 else
1969 {
1970 unsigned char *str = reinterpret_cast<unsigned char *>( PyString_AS_STRING( ptr() ) );
1971 return static_cast<long>( str[0] );
1972 }
1973 }
1974
1975 // Conversion
1976 operator String() const;
1977
operator std::string() const1978 operator std::string () const
1979 {
1980 return std::string(PyString_AsString (ptr()));
1981 }
1982 };
1983
1984 #ifdef PYCXX_PYTHON_2TO3
1985 // String and Bytes compatible with Python3 version in 6.0.0 PyCXX
1986 class Bytes;
1987
1988 class String: public SeqBase<Char>
1989 {
1990 public:
capacity() const1991 virtual size_type capacity() const
1992 {
1993 return max_size();
1994 }
1995
String(PyObject * pyob,bool owned=false)1996 explicit String( PyObject *pyob, bool owned = false)
1997 : SeqBase<Char>( pyob, owned )
1998 {
1999 validate();
2000 }
2001
String(const Object & ob)2002 String( const Object& ob): SeqBase<Char>(ob)
2003 {
2004 validate();
2005 }
2006
String()2007 String()
2008 : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
2009 {
2010 validate();
2011 }
2012
String(const std::string & v)2013 String( const std::string& v )
2014 : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()), v.length() ), true )
2015 {
2016 validate();
2017 }
2018
String(const Py_UNICODE * s,int length)2019 String( const Py_UNICODE *s, int length )
2020 : SeqBase<Char>( PyUnicode_FromUnicode( s, length ), true )
2021 {
2022 validate();
2023 }
2024
String(const char * s,const char * encoding,const char * error="strict")2025 String( const char *s, const char *encoding, const char *error="strict" )
2026 : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true )
2027 {
2028 validate();
2029 }
2030
String(const char * s,int len,const char * encoding,const char * error="strict")2031 String( const char *s, int len, const char *encoding, const char *error="strict" )
2032 : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true )
2033 {
2034 validate();
2035 }
2036
String(const std::string & s,const char * encoding,const char * error="strict")2037 String( const std::string &s, const char *encoding, const char *error="strict" )
2038 : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true )
2039 {
2040 validate();
2041 }
2042
String(const char * v,int vsize)2043 String( const char *v, int vsize )
2044 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
2045 {
2046 validate();
2047 }
2048
String(const char * v)2049 String( const char *v )
2050 : SeqBase<Char>( PyString_FromString( v ), true )
2051 {
2052 validate();
2053 }
2054
2055 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)2056 String &operator=( const Object &rhs )
2057 {
2058 return *this = *rhs;
2059 }
2060
operator =(PyObject * rhsp)2061 String& operator= (PyObject *rhsp)
2062 {
2063 if( ptr() == rhsp )
2064 return *this;
2065 set (rhsp);
2066 return *this;
2067 }
2068 // Membership
accepts(PyObject * pyob) const2069 virtual bool accepts (PyObject *pyob) const
2070 {
2071 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob));
2072 }
2073
2074 // Assignment from C string
operator =(const std::string & v)2075 String& operator=( const std::string &v )
2076 {
2077 set( PyString_FromStringAndSize( const_cast<char*>( v.data() ), v.length() ), true );
2078 return *this;
2079 }
operator =(const unicodestring & v)2080 String& operator=( const unicodestring &v )
2081 {
2082 set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ), v.length() ), true );
2083 return *this;
2084 }
2085
2086 // Encode
2087 Bytes encode( const char *encoding, const char *error="strict" ) const;
2088
2089 // Queries
size() const2090 virtual size_type size() const
2091 {
2092 if( isUnicode() )
2093 {
2094 return PyUnicode_GET_SIZE (ptr());
2095 }
2096 else
2097 {
2098 return PyString_Size (ptr());
2099 }
2100 }
2101
operator std::string() const2102 operator std::string() const
2103 {
2104 return as_std_string( "utf-8" );
2105 }
2106
2107 std::string as_std_string( const char *encoding, const char *error="strict" ) const;
2108
as_unicodestring() const2109 unicodestring as_unicodestring() const
2110 {
2111 if( isUnicode() )
2112 {
2113 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
2114 PyUnicode_GET_SIZE( ptr() ) );
2115 }
2116 else
2117 {
2118 throw TypeError("can only return unicodestring from Unicode object");
2119 }
2120 }
2121
unicode_data() const2122 const Py_UNICODE *unicode_data() const
2123 {
2124 if( isUnicode() )
2125 {
2126 return PyUnicode_AS_UNICODE( ptr() );
2127 }
2128 else
2129 {
2130 throw TypeError("can only return unicode_data from Unicode object");
2131 }
2132 }
2133 };
2134 class Bytes: public SeqBase<Char>
2135 {
2136 public:
capacity() const2137 virtual size_type capacity() const
2138 {
2139 return max_size();
2140 }
2141
Bytes(PyObject * pyob,bool owned=false)2142 explicit Bytes (PyObject *pyob, bool owned = false)
2143 : SeqBase<Char>(pyob, owned)
2144 {
2145 validate();
2146 }
2147
Bytes(const Object & ob)2148 Bytes (const Object& ob): SeqBase<Char>(ob)
2149 {
2150 validate();
2151 }
2152
Bytes()2153 Bytes()
2154 : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
2155 {
2156 validate();
2157 }
2158
Bytes(const std::string & v)2159 Bytes( const std::string& v )
2160 : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()), v.length()), true )
2161 {
2162 validate();
2163 }
2164
Bytes(const char * v,size_type vsize)2165 Bytes( const char *v, size_type vsize )
2166 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
2167 {
2168 validate();
2169 }
2170
Bytes(const char * v)2171 Bytes( const char *v )
2172 : SeqBase<Char>( PyString_FromString( v ), true )
2173 {
2174 validate();
2175 }
2176
2177 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)2178 Bytes &operator= ( const Object& rhs )
2179 {
2180 return *this = *rhs;
2181 }
2182
operator =(PyObject * rhsp)2183 Bytes &operator= (PyObject *rhsp)
2184 {
2185 if( ptr() == rhsp )
2186 return *this;
2187 set (rhsp);
2188 return *this;
2189 }
2190 // Membership
accepts(PyObject * pyob) const2191 virtual bool accepts( PyObject *pyob ) const
2192 {
2193 return pyob && (Py::_String_Check( pyob ) || Py::_Unicode_Check( pyob ));
2194 }
2195
2196 // Assignment from C string
operator =(const std::string & v)2197 Bytes &operator= (const std::string& v)
2198 {
2199 set( PyString_FromStringAndSize( const_cast<char*>( v.data() ), v.length() ), true );
2200 return *this;
2201 }
operator =(const unicodestring & v)2202 Bytes &operator= (const unicodestring& v)
2203 {
2204 set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ), v.length() ), true );
2205 return *this;
2206 }
2207
decode(const char * encoding,const char * error="strict")2208 String decode( const char *encoding, const char *error="strict" )
2209 {
2210 return Object( PyString_AsDecodedObject( ptr(), encoding, error ), true );
2211 }
2212
2213 // Queries
size() const2214 virtual size_type size () const
2215 {
2216 if( isUnicode() )
2217 {
2218 return PyUnicode_GET_SIZE (ptr());
2219 }
2220 else
2221 {
2222 return PyString_Size (ptr());
2223 }
2224 }
2225
operator std::string() const2226 operator std::string () const
2227 {
2228 return as_std_string();
2229 }
2230
as_std_string() const2231 std::string as_std_string() const
2232 {
2233 if( isUnicode() )
2234 {
2235 throw TypeError("cannot return std::string from Unicode object");
2236 }
2237 else
2238 {
2239 return std::string( PyString_AsString( ptr() ), static_cast<size_t>( PyString_Size( ptr() ) ) );
2240 }
2241 }
2242
as_unicodestring() const2243 unicodestring as_unicodestring() const
2244 {
2245 if( isUnicode() )
2246 {
2247 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
2248 static_cast<size_t>( PyUnicode_GET_SIZE( ptr() ) ) );
2249 }
2250 else
2251 {
2252 throw TypeError("can only return unicodestring from Unicode object");
2253 }
2254 }
2255 };
2256
2257 #else
2258 // original PyCXX 5.4.x version of String
2259 class String: public SeqBase<Char>
2260 {
2261 public:
capacity() const2262 virtual size_type capacity() const
2263 {
2264 return max_size();
2265 }
2266
String(PyObject * pyob,bool owned=false)2267 explicit String (PyObject *pyob, bool owned = false): SeqBase<Char>(pyob, owned)
2268 {
2269 validate();
2270 }
2271
String(const Object & ob)2272 String (const Object& ob): SeqBase<Char>(ob)
2273 {
2274 validate();
2275 }
2276
String()2277 String()
2278 : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
2279 {
2280 validate();
2281 }
2282
String(const std::string & v)2283 String( const std::string& v )
2284 : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()), v.length() ), true )
2285 {
2286 validate();
2287 }
2288
String(const char * s,const char * encoding,const char * error="strict")2289 String( const char *s, const char *encoding, const char *error="strict" )
2290 : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true )
2291 {
2292 validate();
2293 }
2294
String(const char * s,size_type len,const char * encoding,const char * error="strict")2295 String( const char *s, size_type len, const char *encoding, const char *error="strict" )
2296 : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true )
2297 {
2298 validate();
2299 }
2300
String(const std::string & s,const char * encoding,const char * error="strict")2301 String( const std::string &s, const char *encoding, const char *error="strict" )
2302 : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true )
2303 {
2304 validate();
2305 }
2306
String(const char * v,size_type vsize)2307 String( const char *v, size_type vsize )
2308 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
2309 {
2310 validate();
2311 }
2312
String(const char * v)2313 String( const char* v )
2314 : SeqBase<Char>( PyString_FromString( v ), true )
2315 {
2316 validate();
2317 }
2318
2319 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)2320 String& operator= ( const Object& rhs )
2321 {
2322 return *this = *rhs;
2323 }
2324
operator =(PyObject * rhsp)2325 String& operator= (PyObject* rhsp)
2326 {
2327 if( ptr() == rhsp )
2328 return *this;
2329 set (rhsp);
2330 return *this;
2331 }
2332 // Membership
accepts(PyObject * pyob) const2333 virtual bool accepts (PyObject *pyob) const
2334 {
2335 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob));
2336 }
2337
2338 // Assignment from C string
operator =(const std::string & v)2339 String& operator= (const std::string& v)
2340 {
2341 set( PyString_FromStringAndSize( const_cast<char*>( v.data() ), v.length() ), true );
2342 return *this;
2343 }
operator =(const unicodestring & v)2344 String& operator= (const unicodestring& v)
2345 {
2346 set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ), v.length() ), true );
2347 return *this;
2348 }
2349
2350
2351 // Encode
encode(const char * encoding,const char * error="strict") const2352 String encode( const char *encoding, const char *error="strict" ) const
2353 {
2354 if( isUnicode() )
2355 {
2356 return String( PyUnicode_AsEncodedString( ptr(), encoding, error ), true );
2357 }
2358 else
2359 {
2360 return String( PyString_AsEncodedObject( ptr(), encoding, error ), true );
2361 }
2362 }
2363
decode(const char * encoding,const char * error="strict")2364 String decode( const char *encoding, const char *error="strict" )
2365 {
2366 return Object( PyString_AsDecodedObject( ptr(), encoding, error ), true );
2367 }
2368
2369 // Queries
size() const2370 virtual size_type size () const
2371 {
2372 if( isUnicode() )
2373 {
2374 return PyUnicode_GET_SIZE (ptr());
2375 }
2376 else
2377 {
2378 return PyString_Size (ptr());
2379 }
2380 }
2381
operator std::string() const2382 operator std::string () const
2383 {
2384 return as_std_string();
2385 }
2386
as_std_string() const2387 std::string as_std_string() const
2388 {
2389 if( isUnicode() )
2390 {
2391 throw TypeError("cannot return std::string from Unicode object");
2392 }
2393 else
2394 {
2395 return std::string( PyString_AsString( ptr() ), static_cast<size_t>( PyString_Size( ptr() ) ) );
2396 }
2397 }
2398
2399 std::string as_std_string( const char *encoding, const char *error="strict" ) const;
2400
as_unicodestring() const2401 unicodestring as_unicodestring() const
2402 {
2403 if( isUnicode() )
2404 {
2405 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
2406 static_cast<size_t>( PyUnicode_GET_SIZE( ptr() ) ) );
2407 }
2408 else
2409 {
2410 throw TypeError("can only return unicodestring from Unicode object");
2411 }
2412 }
2413 };
2414 #endif
2415
2416 // ==================================================
2417 // class Tuple
2418 class Tuple: public Sequence
2419 {
2420 public:
setItem(sequence_index_type offset,const Object & ob)2421 virtual void setItem (sequence_index_type offset, const Object&ob)
2422 {
2423 // note PyTuple_SetItem is a thief...
2424 if(PyTuple_SetItem (ptr(), offset, new_reference_to(ob)) == -1)
2425 {
2426 ifPyErrorThrowCxxException();
2427 }
2428 }
2429
2430 // Constructor
Tuple(PyObject * pyob,bool owned=false)2431 explicit Tuple (PyObject *pyob, bool owned = false): Sequence (pyob, owned)
2432 {
2433 validate();
2434 }
2435
Tuple(const Object & ob)2436 Tuple (const Object& ob): Sequence(ob)
2437 {
2438 validate();
2439 }
2440
2441 // New tuple of a given size
Tuple(int size=0)2442 explicit Tuple (int size = 0)
2443 {
2444 set(PyTuple_New (size), true);
2445 validate ();
2446 for (sequence_index_type i=0; i < size; i++)
2447 {
2448 if(PyTuple_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
2449 {
2450 ifPyErrorThrowCxxException();
2451 }
2452 }
2453 }
2454 // Tuple from any sequence
Tuple(const Sequence & s)2455 explicit Tuple (const Sequence& s)
2456 {
2457 sequence_index_type limit( sequence_index_type( s.length() ) );
2458
2459 set(PyTuple_New (limit), true);
2460 validate();
2461
2462 for(sequence_index_type i=0; i < limit; i++)
2463 {
2464 if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
2465 {
2466 ifPyErrorThrowCxxException();
2467 }
2468 }
2469 }
2470 // Assignment acquires new ownership of pointer
2471
operator =(const Object & rhs)2472 Tuple& operator= (const Object& rhs)
2473 {
2474 return (*this = *rhs);
2475 }
2476
operator =(PyObject * rhsp)2477 Tuple& operator= (PyObject* rhsp)
2478 {
2479 if(ptr() == rhsp) return *this;
2480 set (rhsp);
2481 return *this;
2482 }
2483 // Membership
accepts(PyObject * pyob) const2484 virtual bool accepts (PyObject *pyob) const
2485 {
2486 return pyob && Py::_Tuple_Check (pyob);
2487 }
2488
getSlice(int i,int j) const2489 Tuple getSlice (int i, int j) const
2490 {
2491 return Tuple (PySequence_GetSlice (ptr(), i, j), true);
2492 }
2493
2494 };
2495
2496 class TupleN: public Tuple
2497 {
2498 public:
TupleN()2499 TupleN()
2500 : Tuple( 0 )
2501 {
2502 }
2503
TupleN(const Object & obj1)2504 TupleN( const Object &obj1 )
2505 : Tuple( 1 )
2506 {
2507 setItem( 0, obj1 );
2508 }
2509
TupleN(const Object & obj1,const Object & obj2)2510 TupleN( const Object &obj1, const Object &obj2 )
2511 : Tuple( 2 )
2512 {
2513 setItem( 0, obj1 );
2514 setItem( 1, obj2 );
2515 }
2516
TupleN(const Object & obj1,const Object & obj2,const Object & obj3)2517 TupleN( const Object &obj1, const Object &obj2, const Object &obj3 )
2518 : Tuple( 3 )
2519 {
2520 setItem( 0, obj1 );
2521 setItem( 1, obj2 );
2522 setItem( 2, obj3 );
2523 }
2524
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4)2525 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2526 const Object &obj4 )
2527 : Tuple( 4 )
2528 {
2529 setItem( 0, obj1 );
2530 setItem( 1, obj2 );
2531 setItem( 2, obj3 );
2532 setItem( 3, obj4 );
2533 }
2534
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4,const Object & obj5)2535 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2536 const Object &obj4, const Object &obj5 )
2537 : Tuple( 5 )
2538 {
2539 setItem( 0, obj1 );
2540 setItem( 1, obj2 );
2541 setItem( 2, obj3 );
2542 setItem( 3, obj4 );
2543 setItem( 4, obj5 );
2544 }
2545
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4,const Object & obj5,const Object & obj6)2546 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2547 const Object &obj4, const Object &obj5, const Object &obj6 )
2548 : Tuple( 6 )
2549 {
2550 setItem( 0, obj1 );
2551 setItem( 1, obj2 );
2552 setItem( 2, obj3 );
2553 setItem( 3, obj4 );
2554 setItem( 4, obj5 );
2555 setItem( 5, obj6 );
2556 }
2557
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4,const Object & obj5,const Object & obj6,const Object & obj7)2558 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2559 const Object &obj4, const Object &obj5, const Object &obj6,
2560 const Object &obj7 )
2561 : Tuple( 7 )
2562 {
2563 setItem( 0, obj1 );
2564 setItem( 1, obj2 );
2565 setItem( 2, obj3 );
2566 setItem( 3, obj4 );
2567 setItem( 4, obj5 );
2568 setItem( 5, obj6 );
2569 setItem( 6, obj7 );
2570 }
2571
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4,const Object & obj5,const Object & obj6,const Object & obj7,const Object & obj8)2572 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2573 const Object &obj4, const Object &obj5, const Object &obj6,
2574 const Object &obj7, const Object &obj8 )
2575 : Tuple( 8 )
2576 {
2577 setItem( 0, obj1 );
2578 setItem( 1, obj2 );
2579 setItem( 2, obj3 );
2580 setItem( 3, obj4 );
2581 setItem( 4, obj5 );
2582 setItem( 5, obj6 );
2583 setItem( 6, obj7 );
2584 setItem( 7, obj8 );
2585 }
2586
TupleN(const Object & obj1,const Object & obj2,const Object & obj3,const Object & obj4,const Object & obj5,const Object & obj6,const Object & obj7,const Object & obj8,const Object & obj9)2587 TupleN( const Object &obj1, const Object &obj2, const Object &obj3,
2588 const Object &obj4, const Object &obj5, const Object &obj6,
2589 const Object &obj7, const Object &obj8, const Object &obj9 )
2590 : Tuple( 9 )
2591 {
2592 setItem( 0, obj1 );
2593 setItem( 1, obj2 );
2594 setItem( 2, obj3 );
2595 setItem( 3, obj4 );
2596 setItem( 4, obj5 );
2597 setItem( 5, obj6 );
2598 setItem( 6, obj7 );
2599 setItem( 7, obj8 );
2600 setItem( 8, obj9 );
2601 }
2602
~TupleN()2603 virtual ~TupleN()
2604 { }
2605 };
2606
2607
2608 // ==================================================
2609 // class List
2610
2611 class List: public Sequence
2612 {
2613 public:
2614 // Constructor
List(PyObject * pyob,bool owned=false)2615 explicit List (PyObject *pyob, bool owned = false): Sequence(pyob, owned)
2616 {
2617 validate();
2618 }
List(const Object & ob)2619 List (const Object& ob): Sequence(ob)
2620 {
2621 validate();
2622 }
2623 // Creation at a fixed size
List(size_type size=0)2624 List (size_type size = 0)
2625 {
2626 set(PyList_New (size), true);
2627 validate();
2628 for (sequence_index_type i=0; i < size; i++)
2629 {
2630 if(PyList_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
2631 {
2632 ifPyErrorThrowCxxException();
2633 }
2634 }
2635 }
2636
2637 // List from a sequence
List(const Sequence & s)2638 List (const Sequence& s): Sequence()
2639 {
2640 size_type n = s.length();
2641 set(PyList_New (n), true);
2642 validate();
2643 for (sequence_index_type i=0; i < n; i++)
2644 {
2645 if(PyList_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
2646 {
2647 ifPyErrorThrowCxxException();
2648 }
2649 }
2650 }
2651
capacity() const2652 virtual size_type capacity() const
2653 {
2654 return max_size();
2655 }
2656 // Assignment acquires new ownership of pointer
2657
operator =(const Object & rhs)2658 List& operator= (const Object& rhs)
2659 {
2660 return (*this = *rhs);
2661 }
2662
operator =(PyObject * rhsp)2663 List& operator= (PyObject* rhsp)
2664 {
2665 if(ptr() == rhsp) return *this;
2666 set (rhsp);
2667 return *this;
2668 }
2669 // Membership
accepts(PyObject * pyob) const2670 virtual bool accepts (PyObject *pyob) const
2671 {
2672 return pyob && Py::_List_Check (pyob);
2673 }
2674
getSlice(int i,int j) const2675 List getSlice (int i, int j) const
2676 {
2677 return List (PyList_GetSlice (ptr(), i, j), true);
2678 }
2679
setSlice(int i,int j,const Object & v)2680 void setSlice (int i, int j, const Object& v)
2681 {
2682 if(PyList_SetSlice (ptr(), i, j, *v) == -1)
2683 {
2684 ifPyErrorThrowCxxException();
2685 }
2686 }
2687
append(const Object & ob)2688 void append (const Object& ob)
2689 {
2690 if(PyList_Append (ptr(), *ob) == -1)
2691 {
2692 ifPyErrorThrowCxxException();
2693 }
2694 }
2695
insert(int i,const Object & ob)2696 void insert (int i, const Object& ob)
2697 {
2698 if(PyList_Insert (ptr(), i, *ob) == -1)
2699 {
2700 ifPyErrorThrowCxxException();
2701 }
2702 }
2703
sort()2704 void sort ()
2705 {
2706 if(PyList_Sort(ptr()) == -1)
2707 {
2708 ifPyErrorThrowCxxException();
2709 }
2710 }
2711
reverse()2712 void reverse ()
2713 {
2714 if(PyList_Reverse(ptr()) == -1)
2715 {
2716 ifPyErrorThrowCxxException();
2717 }
2718 }
2719 };
2720
2721
2722 // Mappings
2723 // ==================================================
2724 template<TEMPLATE_TYPENAME T>
2725 class mapref
2726 {
2727 protected:
2728 MapBase<T>& s; // the map
2729 Object key; // item key
2730 T the_item;
2731
2732 public:
2733 mapref<T> (MapBase<T>& map, const std::string& k)
2734 : s(map), the_item()
2735 {
2736 key = String(k);
2737 if(map.hasKey(key)) the_item = map.getItem(key);
2738 }
2739
2740 mapref<T> (MapBase<T>& map, const Object& k)
2741 : s(map), key(k), the_item()
2742 {
2743 if(map.hasKey(key)) the_item = map.getItem(key);
2744 }
2745
2746 virtual ~mapref<T>()
2747 {}
2748
2749 // MapBase<T> stuff
2750 // lvalue
operator =(const mapref<T> & other)2751 mapref<T>& operator=(const mapref<T>& other)
2752 {
2753 if(this == &other) return *this;
2754 the_item = other.the_item;
2755 s.setItem(key, other.the_item);
2756 return *this;
2757 }
2758
operator =(const T & ob)2759 mapref<T>& operator= (const T& ob)
2760 {
2761 the_item = ob;
2762 s.setItem (key, ob);
2763 return *this;
2764 }
2765
2766 // rvalue
operator T() const2767 operator T() const
2768 {
2769 return the_item;
2770 }
2771
2772 // forward everything else to the_item
ptr() const2773 PyObject* ptr () const
2774 {
2775 return the_item.ptr();
2776 }
2777
reference_count() const2778 int reference_count () const
2779 { // the mapref count
2780 return the_item.reference_count();
2781 }
2782
type() const2783 Type type () const
2784 {
2785 return the_item.type();
2786 }
2787
str() const2788 String str () const
2789 {
2790 return the_item.str();
2791 }
2792
repr() const2793 String repr () const
2794 {
2795 return the_item.repr();
2796 }
2797
hasAttr(const std::string & attr_name) const2798 bool hasAttr (const std::string& attr_name) const
2799 {
2800 return the_item.hasAttr(attr_name);
2801 }
2802
getAttr(const std::string & attr_name) const2803 Object getAttr (const std::string& attr_name) const
2804 {
2805 return the_item.getAttr(attr_name);
2806 }
2807
getItem(const Object & k) const2808 Object getItem (const Object& k) const
2809 {
2810 return the_item.getItem(k);
2811 }
2812
hashValue() const2813 long hashValue () const
2814 {
2815 return the_item.hashValue();
2816 }
2817
isCallable() const2818 bool isCallable () const
2819 {
2820 return the_item.isCallable();
2821 }
2822
isInstance() const2823 bool isInstance () const
2824 {
2825 return the_item.isInstance();
2826 }
2827
isList() const2828 bool isList () const
2829 {
2830 return the_item.isList();
2831 }
2832
isMapping() const2833 bool isMapping () const
2834 {
2835 return the_item.isMapping();
2836 }
2837
isNumeric() const2838 bool isNumeric () const
2839 {
2840 return the_item.isNumeric();
2841 }
2842
isSequence() const2843 bool isSequence () const
2844 {
2845 return the_item.isSequence();
2846 }
2847
isTrue() const2848 bool isTrue () const
2849 {
2850 return the_item.isTrue();
2851 }
2852
isType(const Type & t) const2853 bool isType (const Type& t) const
2854 {
2855 return the_item.isType (t);
2856 }
2857
isTuple() const2858 bool isTuple() const
2859 {
2860 return the_item.isTuple();
2861 }
2862
isString() const2863 bool isString() const
2864 {
2865 return the_item.isString();
2866 }
2867
2868 // Commands
setAttr(const std::string & attr_name,const Object & value)2869 void setAttr (const std::string& attr_name, const Object& value)
2870 {
2871 the_item.setAttr(attr_name, value);
2872 }
2873
delAttr(const std::string & attr_name)2874 void delAttr (const std::string& attr_name)
2875 {
2876 the_item.delAttr(attr_name);
2877 }
2878
delItem(const Object & k)2879 void delItem (const Object& k)
2880 {
2881 the_item.delItem(k);
2882 }
2883 }; // end of mapref
2884
2885 // TMM: now for mapref<T>
2886 template< class T >
operator ==(const mapref<T> & left,const mapref<T> & right)2887 bool operator==(const mapref<T>& left, const mapref<T>& right)
2888 {
2889 return true; // NOT completed.
2890 }
2891
2892 template< class T >
operator !=(const mapref<T> & left,const mapref<T> & right)2893 bool operator!=(const mapref<T>& left, const mapref<T>& right)
2894 {
2895 return true; // not completed.
2896 }
2897
2898 template<TEMPLATE_TYPENAME T>
2899 class MapBase: public Object
2900 {
2901 protected:
2902 explicit MapBase<T>()
2903 {}
2904 public:
2905 // reference: proxy class for implementing []
2906 // TMM: 26Jun'01 - the types
2907 // If you assume that Python mapping is a hash_map...
2908 // hash_map::value_type is not assignable, but
2909 // (*it).second = data must be a valid expression
2910 typedef PyCxx_ssize_t size_type;
2911 typedef Object key_type;
2912 typedef mapref<T> data_type;
2913 typedef std::pair< const T, T > value_type;
2914 typedef std::pair< const T, mapref<T> > reference;
2915 typedef const std::pair< const T, const T > const_reference;
2916 typedef std::pair< const T, mapref<T> > pointer;
2917
2918 // Constructor
2919 explicit MapBase<T> (PyObject *pyob, bool owned = false): Object(pyob, owned)
2920 {
2921 validate();
2922 }
2923
2924 // TMM: 02Jul'01 - changed MapBase<T> to Object in next line
2925 MapBase<T> (const Object& ob): Object(ob)
2926 {
2927 validate();
2928 }
2929
2930 // Assignment acquires new ownership of pointer
operator =(const Object & rhs)2931 MapBase<T>& operator= (const Object& rhs)
2932 {
2933 return (*this = *rhs);
2934 }
2935
operator =(PyObject * rhsp)2936 MapBase<T>& operator= (PyObject* rhsp)
2937 {
2938 if(ptr() == rhsp) return *this;
2939 set (rhsp);
2940 return *this;
2941 }
2942 // Membership
accepts(PyObject * pyob) const2943 virtual bool accepts (PyObject *pyob) const
2944 {
2945 return pyob && PyMapping_Check(pyob);
2946 }
2947
2948 // Clear -- PyMapping Clear is missing
2949 //
2950
clear()2951 void clear ()
2952 {
2953 List k = keys();
2954 for(List::iterator i = k.begin(); i != k.end(); i++)
2955 {
2956 delItem(*i);
2957 }
2958 }
2959
size() const2960 virtual Py_ssize_t size() const
2961 {
2962 return PyMapping_Length (ptr());
2963 }
2964
2965 // Element Access
operator [](const std::string & key) const2966 T operator[](const std::string& key) const
2967 {
2968 return getItem(key);
2969 }
2970
operator [](const Object & key) const2971 T operator[](const Object& key) const
2972 {
2973 return getItem(key);
2974 }
2975
operator [](const std::string & key)2976 mapref<T> operator[](const std::string& key)
2977 {
2978 return mapref<T>(*this, key);
2979 }
2980
operator [](const Object & key)2981 mapref<T> operator[](const Object& key)
2982 {
2983 return mapref<T>(*this, key);
2984 }
2985
length() const2986 Py_ssize_t length () const
2987 {
2988 return PyMapping_Length (ptr());
2989 }
2990
hasKey(const std::string & s) const2991 bool hasKey (const std::string& s) const
2992 {
2993 return PyMapping_HasKeyString (ptr(),const_cast<char*>(s.c_str())) != 0;
2994 }
2995
hasKey(const Object & s) const2996 bool hasKey (const Object& s) const
2997 {
2998 return PyMapping_HasKey (ptr(), s.ptr()) != 0;
2999 }
3000
getItem(const std::string & s) const3001 T getItem (const std::string& s) const
3002 {
3003 return T(
3004 asObject(PyMapping_GetItemString (ptr(),const_cast<char*>(s.c_str())))
3005 );
3006 }
3007
getItem(const Object & s) const3008 T getItem (const Object& s) const
3009 {
3010 return T(
3011 asObject(PyObject_GetItem (ptr(), s.ptr()))
3012 );
3013 }
3014
setItem(const char * s,const Object & ob)3015 virtual void setItem (const char *s, const Object& ob)
3016 {
3017 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s), *ob) == -1)
3018 {
3019 ifPyErrorThrowCxxException();
3020 }
3021 }
3022
setItem(const std::string & s,const Object & ob)3023 virtual void setItem (const std::string& s, const Object& ob)
3024 {
3025 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s.c_str()), *ob) == -1)
3026 {
3027 ifPyErrorThrowCxxException();
3028 }
3029 }
3030
setItem(const Object & s,const Object & ob)3031 virtual void setItem (const Object& s, const Object& ob)
3032 {
3033 if (PyObject_SetItem (ptr(), s.ptr(), ob.ptr()) == -1)
3034 {
3035 ifPyErrorThrowCxxException();
3036 }
3037 }
3038
delItem(const std::string & s)3039 void delItem (const std::string& s)
3040 {
3041 if (PyMapping_DelItemString (ptr(), const_cast<char*>(s.c_str())) == -1)
3042 {
3043 ifPyErrorThrowCxxException();
3044 }
3045 }
3046
delItem(const Object & s)3047 void delItem (const Object& s)
3048 {
3049 if (PyMapping_DelItem (ptr(), *s) == -1)
3050 {
3051 ifPyErrorThrowCxxException();
3052 }
3053 }
3054 // Queries
keys() const3055 List keys () const
3056 {
3057 static char keys[] = {'k', 'e', 'y', 's', 0};
3058 return List(PyObject_CallMethod( ptr(), keys, NULL ), true );
3059 }
3060
values() const3061 List values () const
3062 { // each returned item is a (key, value) pair
3063 return List(PyMapping_Values(ptr()), true);
3064 }
3065
items() const3066 List items () const
3067 {
3068 return List(PyMapping_Items(ptr()), true);
3069 }
3070
3071 class iterator
3072 {
3073 // : public forward_iterator_parent( std::pair<const T,T> ) {
3074 protected:
3075 typedef std::forward_iterator_tag iterator_category;
3076 typedef std::pair< const T, T > value_type;
3077 typedef int difference_type;
3078 typedef std::pair< const T, mapref<T> > pointer;
3079 typedef std::pair< const T, mapref<T> > reference;
3080
3081 friend class MapBase<T>;
3082 //
3083 MapBase<T> *map;
3084 List keys; // for iterating over the map
3085 sequence_index_type pos; // index into the keys
3086
3087 private:
iterator(MapBase<T> * m,List k,sequence_index_type p)3088 iterator( MapBase<T>* m, List k, sequence_index_type p )
3089 : map( m )
3090 , keys( k )
3091 , pos( p )
3092 {}
3093
3094 public:
~iterator()3095 ~iterator ()
3096 {}
3097
iterator()3098 iterator ()
3099 : map( 0 )
3100 , keys()
3101 , pos()
3102 {}
3103
iterator(MapBase<T> * m,bool end=false)3104 iterator (MapBase<T>* m, bool end = false )
3105 : map( m )
3106 , keys( m->keys() )
3107 , pos( end ? keys.length() : 0 )
3108 {}
3109
iterator(const iterator & other)3110 iterator (const iterator& other)
3111 : map( other.map )
3112 , keys( other.keys )
3113 , pos( other.pos )
3114 {}
3115
operator *()3116 reference operator*()
3117 {
3118 Object key = keys[ pos ];
3119 return std::make_pair(key, mapref<T>(*map,key));
3120 }
3121
operator =(const iterator & other)3122 iterator& operator=(const iterator& other)
3123 {
3124 if (this == &other)
3125 return *this;
3126 map = other.map;
3127 keys = other.keys;
3128 pos = other.pos;
3129 return *this;
3130 }
3131
eql(const iterator & right) const3132 bool eql(const iterator& right) const
3133 {
3134 return map->ptr() == right.map->ptr() && pos == right.pos;
3135 }
neq(const iterator & right) const3136 bool neq( const iterator& right ) const
3137 {
3138 return map->ptr() != right.map->ptr() || pos != right.pos;
3139 }
3140
3141 // pointer operator->() {
3142 // return ;
3143 // }
3144
3145 // prefix ++
operator ++()3146 iterator& operator++ ()
3147 { pos++; return *this;}
3148 // postfix ++
operator ++(int)3149 iterator operator++ (int)
3150 { return iterator(map, keys, pos++);}
3151 // prefix --
operator --()3152 iterator& operator-- ()
3153 { pos--; return *this;}
3154 // postfix --
operator --(int)3155 iterator operator-- (int)
3156 { return iterator(map, keys, pos--);}
3157
diagnose() const3158 std::string diagnose() const
3159 {
3160 std::OSTRSTREAM oss;
3161 oss << "iterator diagnosis " << map << ", " << pos << std::ends;
3162 return std::string(oss.str());
3163 }
3164 }; // end of class MapBase<T>::iterator
3165
begin()3166 iterator begin ()
3167 {
3168 return iterator(this);
3169 }
3170
end()3171 iterator end ()
3172 {
3173 return iterator(this, true);
3174 }
3175
3176 class const_iterator
3177 {
3178 protected:
3179 typedef std::forward_iterator_tag iterator_category;
3180 typedef const std::pair< const T, T > value_type;
3181 typedef int difference_type;
3182 typedef const std::pair< const T, T > pointer;
3183 typedef const std::pair< const T, T > reference;
3184
3185 friend class MapBase<T>;
3186 const MapBase<T> *map;
3187 List keys; // for iterating over the map
3188 sequence_index_type pos; // index into the keys
3189
3190 private:
const_iterator(const MapBase<T> * m,List k,int p)3191 const_iterator( const MapBase<T>* m, List k, int p )
3192 : map( m )
3193 , keys( k )
3194 , pos( p )
3195 {}
3196
3197 public:
~const_iterator()3198 ~const_iterator ()
3199 {}
3200
const_iterator()3201 const_iterator ()
3202 : map( 0 )
3203 , keys()
3204 , pos()
3205 {}
3206
const_iterator(const MapBase<T> * m,bool end=false)3207 const_iterator (const MapBase<T>* m, bool end = false )
3208 : map( m )
3209 , keys( m->keys() )
3210 , pos( end ? keys.length() : 0 )
3211 {}
3212
const_iterator(const const_iterator & other)3213 const_iterator(const const_iterator& other)
3214 : map( other.map )
3215 , keys( other.keys )
3216 , pos( other.pos )
3217 {}
3218
eql(const const_iterator & right) const3219 bool eql(const const_iterator& right) const
3220 {
3221 return map->ptr() == right.map->ptr() && pos == right.pos;
3222 }
3223
neq(const const_iterator & right) const3224 bool neq( const const_iterator& right ) const
3225 {
3226 return map->ptr() != right.map->ptr() || pos != right.pos;
3227 }
3228
operator *()3229 const_reference operator*()
3230 {
3231 Object key = keys[ pos ];
3232 return std::make_pair( key, mapref<T>( *map, key ) );
3233 }
3234
operator =(const const_iterator & other)3235 const_iterator& operator=(const const_iterator& other)
3236 {
3237 if (this == &other) return *this;
3238 map = other.map;
3239 keys = other.keys;
3240 pos = other.pos;
3241 return *this;
3242 }
3243
3244 // prefix ++
operator ++()3245 const_iterator& operator++ ()
3246 { pos++; return *this;}
3247 // postfix ++
operator ++(int)3248 const_iterator operator++ (int)
3249 { return const_iterator(map, keys, pos++);}
3250 // prefix --
operator --()3251 const_iterator& operator-- ()
3252 { pos--; return *this;}
3253 // postfix --
operator --(int)3254 const_iterator operator-- (int)
3255 { return const_iterator(map, keys, pos--);}
3256 }; // end of class MapBase<T>::const_iterator
3257
begin() const3258 const_iterator begin () const
3259 {
3260 return const_iterator(this);
3261 }
3262
end() const3263 const_iterator end () const
3264 {
3265 return const_iterator(this, true);
3266 }
3267
3268 }; // end of MapBase<T>
3269
3270 typedef MapBase<Object> Mapping;
3271
3272 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
3273 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
3274 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
3275 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
3276
3277 extern bool operator==(const Mapping::iterator& left, const Mapping::iterator& right);
3278 extern bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right);
3279 extern bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
3280 extern bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
3281
3282
3283 // ==================================================
3284 // class Dict
3285 class Dict: public Mapping
3286 {
3287 public:
3288 // Constructor
Dict(PyObject * pyob,bool owned=false)3289 explicit Dict (PyObject *pyob, bool owned=false): Mapping (pyob, owned)
3290 {
3291 validate();
3292 }
Dict(const Object & ob)3293 Dict (const Object& ob): Mapping(ob)
3294 {
3295 validate();
3296 }
3297 // Creation
Dict()3298 Dict ()
3299 {
3300 set(PyDict_New (), true);
3301 validate();
3302 }
3303 // Assignment acquires new ownership of pointer
3304
operator =(const Object & rhs)3305 Dict& operator= (const Object& rhs)
3306 {
3307 return (*this = *rhs);
3308 }
3309
operator =(PyObject * rhsp)3310 Dict& operator= (PyObject* rhsp)
3311 {
3312 if(ptr() == rhsp) return *this;
3313 set(rhsp);
3314 return *this;
3315 }
3316 // Membership
accepts(PyObject * pyob) const3317 virtual bool accepts (PyObject *pyob) const
3318 {
3319 return pyob && Py::_Dict_Check (pyob);
3320 }
3321 };
3322
3323 class Callable: public Object
3324 {
3325 public:
3326 // Constructor
Callable()3327 explicit Callable (): Object() {}
Callable(PyObject * pyob,bool owned=false)3328 explicit Callable (PyObject *pyob, bool owned = false): Object (pyob, owned)
3329 {
3330 validate();
3331 }
3332
Callable(const Object & ob)3333 Callable (const Object& ob): Object(ob)
3334 {
3335 validate();
3336 }
3337
3338 // Assignment acquires new ownership of pointer
3339
operator =(const Object & rhs)3340 Callable& operator= (const Object& rhs)
3341 {
3342 return (*this = *rhs);
3343 }
3344
operator =(PyObject * rhsp)3345 Callable& operator= (PyObject* rhsp)
3346 {
3347 if(ptr() == rhsp) return *this;
3348 set (rhsp);
3349 return *this;
3350 }
3351
3352 // Membership
accepts(PyObject * pyob) const3353 virtual bool accepts (PyObject *pyob) const
3354 {
3355 return pyob && PyCallable_Check (pyob);
3356 }
3357
3358 // Call
apply(const Tuple & args) const3359 Object apply(const Tuple& args) const
3360 {
3361 PyObject *result = PyObject_CallObject( ptr(), args.ptr() );
3362 if( result == NULL )
3363 {
3364 ifPyErrorThrowCxxException();
3365 }
3366 return asObject( result );
3367 }
3368
3369 // Call with keywords
apply(const Tuple & args,const Dict & kw) const3370 Object apply(const Tuple& args, const Dict& kw) const
3371 {
3372 PyObject *result = PyEval_CallObjectWithKeywords( ptr(), args.ptr(), kw.ptr() );
3373 if( result == NULL )
3374 {
3375 ifPyErrorThrowCxxException();
3376 }
3377 return asObject( result );
3378 }
3379
apply(PyObject * pargs=0) const3380 Object apply(PyObject* pargs = 0) const
3381 {
3382 if( pargs == 0 )
3383 {
3384 return apply( Tuple() );
3385 }
3386 else
3387 {
3388 return apply( Tuple( pargs ) );
3389 }
3390 }
3391 };
3392
3393 class Module: public Object
3394 {
3395 public:
Module(PyObject * pyob,bool owned=false)3396 explicit Module (PyObject* pyob, bool owned = false): Object (pyob, owned)
3397 {
3398 validate();
3399 }
3400
3401 // Construct from module name
Module(const std::string & s)3402 explicit Module (const std::string&s): Object()
3403 {
3404 PyObject *m = PyImport_AddModule( const_cast<char *>(s.c_str()) );
3405 set( m, false );
3406 validate ();
3407 }
3408
3409 // Copy constructor acquires new ownership of pointer
Module(const Module & ob)3410 Module (const Module& ob): Object(*ob)
3411 {
3412 validate();
3413 }
3414
operator =(const Object & rhs)3415 Module& operator= (const Object& rhs)
3416 {
3417 return (*this = *rhs);
3418 }
3419
operator =(PyObject * rhsp)3420 Module& operator= (PyObject* rhsp)
3421 {
3422 if(ptr() == rhsp) return *this;
3423 set(rhsp);
3424 return *this;
3425 }
3426
getDict()3427 Dict getDict()
3428 {
3429 return Dict(PyModule_GetDict(ptr()));
3430 // Caution -- PyModule_GetDict returns borrowed reference!
3431 }
3432 };
3433
3434 // Call function helper
callMemberFunction(const std::string & function_name) const3435 inline Object Object::callMemberFunction( const std::string &function_name ) const
3436 {
3437 Callable target( getAttr( function_name ) );
3438 Tuple args( 0 );
3439 return target.apply( args );
3440 }
3441
callMemberFunction(const std::string & function_name,const Tuple & args) const3442 inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args ) const
3443 {
3444 Callable target( getAttr( function_name ) );
3445 return target.apply( args );
3446 }
3447
callMemberFunction(const std::string & function_name,const Tuple & args,const Dict & kw) const3448 inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const
3449 {
3450 Callable target( getAttr( function_name ) );
3451 return target.apply( args, kw );
3452 }
3453
3454 // Numeric interface
operator +(const Object & a)3455 inline Object operator+ (const Object& a)
3456 {
3457 return asObject(PyNumber_Positive(*a));
3458 }
operator -(const Object & a)3459 inline Object operator- (const Object& a)
3460 {
3461 return asObject(PyNumber_Negative(*a));
3462 }
3463
abs(const Object & a)3464 inline Object abs(const Object& a)
3465 {
3466 return asObject(PyNumber_Absolute(*a));
3467 }
3468
coerce(const Object & a,const Object & b)3469 inline std::pair<Object,Object> coerce(const Object& a, const Object& b)
3470 {
3471 PyObject *p1, *p2;
3472 p1 = *a;
3473 p2 = *b;
3474 if(PyNumber_Coerce(&p1,&p2) == -1)
3475 {
3476 ifPyErrorThrowCxxException();
3477 }
3478 return std::pair<Object,Object>(asObject(p1), asObject(p2));
3479 }
3480
operator +(const Object & a,const Object & b)3481 inline Object operator+ (const Object& a, const Object& b)
3482 {
3483 return asObject(PyNumber_Add(*a, *b));
3484 }
operator +(const Object & a,int j)3485 inline Object operator+ (const Object& a, int j)
3486 {
3487 return asObject(PyNumber_Add(*a, *Int(j)));
3488 }
operator +(const Object & a,double v)3489 inline Object operator+ (const Object& a, double v)
3490 {
3491 return asObject(PyNumber_Add(*a, *Float(v)));
3492 }
operator +(int j,const Object & b)3493 inline Object operator+ (int j, const Object& b)
3494 {
3495 return asObject(PyNumber_Add(*Int(j), *b));
3496 }
operator +(double v,const Object & b)3497 inline Object operator+ (double v, const Object& b)
3498 {
3499 return asObject(PyNumber_Add(*Float(v), *b));
3500 }
3501
operator -(const Object & a,const Object & b)3502 inline Object operator- (const Object& a, const Object& b)
3503 {
3504 return asObject(PyNumber_Subtract(*a, *b));
3505 }
operator -(const Object & a,int j)3506 inline Object operator- (const Object& a, int j)
3507 {
3508 return asObject(PyNumber_Subtract(*a, *Int(j)));
3509 }
operator -(const Object & a,double v)3510 inline Object operator- (const Object& a, double v)
3511 {
3512 return asObject(PyNumber_Subtract(*a, *Float(v)));
3513 }
operator -(int j,const Object & b)3514 inline Object operator- (int j, const Object& b)
3515 {
3516 return asObject(PyNumber_Subtract(*Int(j), *b));
3517 }
operator -(double v,const Object & b)3518 inline Object operator- (double v, const Object& b)
3519 {
3520 return asObject(PyNumber_Subtract(*Float(v), *b));
3521 }
3522
operator *(const Object & a,const Object & b)3523 inline Object operator* (const Object& a, const Object& b)
3524 {
3525 return asObject(PyNumber_Multiply(*a, *b));
3526 }
operator *(const Object & a,int j)3527 inline Object operator* (const Object& a, int j)
3528 {
3529 return asObject(PyNumber_Multiply(*a, *Int(j)));
3530 }
operator *(const Object & a,double v)3531 inline Object operator* (const Object& a, double v)
3532 {
3533 return asObject(PyNumber_Multiply(*a, *Float(v)));
3534 }
operator *(int j,const Object & b)3535 inline Object operator* (int j, const Object& b)
3536 {
3537 return asObject(PyNumber_Multiply(*Int(j), *b));
3538 }
operator *(double v,const Object & b)3539 inline Object operator* (double v, const Object& b)
3540 {
3541 return asObject(PyNumber_Multiply(*Float(v), *b));
3542 }
3543
operator /(const Object & a,const Object & b)3544 inline Object operator/ (const Object& a, const Object& b)
3545 {
3546 return asObject(PyNumber_Divide(*a, *b));
3547 }
operator /(const Object & a,int j)3548 inline Object operator/ (const Object& a, int j)
3549 {
3550 return asObject(PyNumber_Divide(*a, *Int(j)));
3551 }
operator /(const Object & a,double v)3552 inline Object operator/ (const Object& a, double v)
3553 {
3554 return asObject(PyNumber_Divide(*a, *Float(v)));
3555 }
operator /(int j,const Object & b)3556 inline Object operator/ (int j, const Object& b)
3557 {
3558 return asObject(PyNumber_Divide(*Int(j), *b));
3559 }
operator /(double v,const Object & b)3560 inline Object operator/ (double v, const Object& b)
3561 {
3562 return asObject(PyNumber_Divide(*Float(v), *b));
3563 }
3564
operator %(const Object & a,const Object & b)3565 inline Object operator% (const Object& a, const Object& b)
3566 {
3567 return asObject(PyNumber_Remainder(*a, *b));
3568 }
operator %(const Object & a,int j)3569 inline Object operator% (const Object& a, int j)
3570 {
3571 return asObject(PyNumber_Remainder(*a, *Int(j)));
3572 }
operator %(const Object & a,double v)3573 inline Object operator% (const Object& a, double v)
3574 {
3575 return asObject(PyNumber_Remainder(*a, *Float(v)));
3576 }
operator %(int j,const Object & b)3577 inline Object operator% (int j, const Object& b)
3578 {
3579 return asObject(PyNumber_Remainder(*Int(j), *b));
3580 }
operator %(double v,const Object & b)3581 inline Object operator% (double v, const Object& b)
3582 {
3583 return asObject(PyNumber_Remainder(*Float(v), *b));
3584 }
3585
type(const BaseException &)3586 inline Object type(const BaseException&) // return the type of the error
3587 {
3588 PyObject *ptype, *pvalue, *ptrace;
3589 PyErr_Fetch(&ptype, &pvalue, &ptrace);
3590 Object result;
3591 if(ptype) result = ptype;
3592 PyErr_Restore(ptype, pvalue, ptrace);
3593 return result;
3594 }
3595
value(const BaseException &)3596 inline Object value(const BaseException&) // return the value of the error
3597 {
3598 PyObject *ptype, *pvalue, *ptrace;
3599 PyErr_Fetch(&ptype, &pvalue, &ptrace);
3600 Object result;
3601 if(pvalue) result = pvalue;
3602 PyErr_Restore(ptype, pvalue, ptrace);
3603 return result;
3604 }
3605
trace(const BaseException &)3606 inline Object trace(const BaseException&) // return the traceback of the error
3607 {
3608 PyObject *ptype, *pvalue, *ptrace;
3609 PyErr_Fetch(&ptype, &pvalue, &ptrace);
3610 Object result;
3611 if(ptrace) result = ptrace;
3612 PyErr_Restore(ptype, pvalue, ptrace);
3613 return result;
3614 }
3615
3616 template<TEMPLATE_TYPENAME T>
str() const3617 String seqref<T>::str () const
3618 {
3619 return the_item.str();
3620 }
3621
3622 template<TEMPLATE_TYPENAME T>
repr() const3623 String seqref<T>::repr () const
3624 {
3625 return the_item.repr();
3626 }
3627
3628 } // namespace Py
3629 #endif // __CXX_Objects__h
3630