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