F:/KPlato/koffice/libs/kross/python/cxx/Objects.hxx

Aller à la documentation de ce fichier.
00001 //----------------------------------*-C++-*----------------------------------//
00002 // Copyright 1998 The Regents of the University of California.
00003 // All rights reserved. See LEGAL.LLNL for full text and disclaimer.
00004 //---------------------------------------------------------------------------//
00005 
00006 #ifndef __CXX_Objects__h
00007 #define __CXX_Objects__h
00008 
00009 // Prevent warnings
00010 #if defined(_XOPEN_SOURCE)
00011 #undef _XOPEN_SOURCE
00012 #endif
00013 
00014 #include "Python.h"
00015 #include "Version.hxx"
00016 #include "Config.hxx"
00017 #include "Exception.hxx"
00018 
00019 
00020 #include <iostream>
00021 #include STR_STREAM
00022 #include <string>
00023 #include <iterator>
00024 #include <utility>
00025 #include <typeinfo>
00026 
00027 namespace Py
00028         {
00029         typedef int sequence_index_type;        // type of an index into a sequence
00030 
00031         // Forward declarations
00032         class Object;
00033         class Type;
00034         template<TEMPLATE_TYPENAME T> class SeqBase;
00035         class String;
00036         class List;
00037         template<TEMPLATE_TYPENAME T> class MapBase;
00038 
00039         // new_reference_to also overloaded below on Object
00040         inline PyObject* new_reference_to(PyObject* p)
00041                 {
00042                 Py::_XINCREF(p);
00043                 return p;
00044                 }
00045 
00046         // returning Null() from an extension method triggers a
00047         // Python exception
00048         inline PyObject* Null()
00049                 {
00050                 return (static_cast<PyObject*>(0));
00051                 }
00052 
00053         //===========================================================================//
00054         // class Object
00055         // The purpose of this class is to serve as the most general kind of
00056         // Python object, for the purpose of writing C++ extensions in Python
00057         // Objects hold a PyObject* which they own. This pointer is always a
00058         // valid pointer to a Python object. In children we must maintain this behavior.
00059         //
00060         // Instructions on how to make your own class MyType descended from Object:
00061         // (0) Pick a base class, either Object or perhaps SeqBase<T> or MapBase<T>.
00062         //     This example assumes Object.
00063 
00064         // (1) Write a routine int MyType_Check (PyObject *) modeled after PyInt_Check,
00065         //     PyFloat_Check, etc.
00066 
00067         // (2) Add method accepts:
00068         //     virtual bool accepts (PyObject *pyob) const {
00069         //         return pyob && MyType_Check (pyob);
00070         //     }
00071 
00072         // (3) Include the following constructor and copy constructor
00073         //
00074         /*
00075         explicit MyType (PyObject *pyob): Object(pyob) {
00076         validate();
00077         }
00078 
00079         MyType(const Object& other): Object(other.ptr()) {
00080         validate();
00081         }
00082         */
00083 
00084         // Alernate version for the constructor to allow for construction from owned pointers:
00085         /*
00086         explicit MyType (PyObject *pyob): Object(pyob) {
00087         validate();
00088         }
00089         */
00090 
00091         // You may wish to add other constructors; see the classes below for examples.
00092         // Each constructor must use "set" to set the pointer
00093         // and end by validating the pointer you have created.
00094 
00095         // (4) Each class needs at least these two assignment operators:
00096         /*
00097         MyType& operator= (const Object& rhs) {
00098         return (*this = *rhs);
00099         }
00100 
00101         Mytype& operator= (PyObject* rhsp) {
00102         if(ptr() == rhsp) return *this;
00103         set(rhsp);
00104         return *this;
00105         }
00106         */
00107         // Note on accepts: constructors call the base class
00108         // version of a virtual when calling the base class constructor,
00109         // so the test has to be done explicitly in a descendent.
00110 
00111         // If you are inheriting from PythonExtension<T> to define an object
00112         // note that it contains PythonExtension<T>::check
00113         // which you can use in accepts when writing a wrapper class.
00114         // See Demo/range.h and Demo/range.cxx for an example.
00115 
00116         class Object
00117                 {
00118         private:
00119                 // the pointer to the Python object
00120                 // Only Object sets this directly.
00121                 // The default constructor for Object sets it to Py_None and
00122                 // child classes must use "set" to set it
00123                 //
00124                 PyObject* p;
00125 
00126         protected:
00127 
00128                 void set (PyObject* pyob, bool owned = false)
00129                         {
00130                         release();
00131                         p = pyob;
00132                         if (!owned)
00133                                 {
00134                                 Py::_XINCREF (p);
00135                                 }
00136                         validate();
00137                         }
00138 
00139                 void release ()
00140                         {
00141                         Py::_XDECREF (p);
00142                         p = 0;
00143                         }
00144 
00145                 void validate()
00146                         {
00147                         // release pointer if not the right type
00148                         if (! accepts (p))
00149                                 {
00150                                 release ();
00151                                 if(PyErr_Occurred())
00152                                         { // Error message already set
00153                                         throw Exception();
00154                                         }
00155                                 // Better error message if RTTI available
00156 #if defined( _CPPRTTI ) || defined(__GNUG__)
00157                                 std::string s("CXX : Error creating object of type ");
00158                                 s += (typeid (*this)).name();
00159                                 throw TypeError (s);
00160 #else
00161                                 throw TypeError ("CXX: type error.");
00162 #endif
00163                                 }
00164                         }
00165 
00166         public:
00167                 // Constructor acquires new ownership of pointer unless explicitly told not to.
00168                 explicit Object (PyObject* pyob=Py::_None(), bool owned = false): p (pyob)
00169                         {
00170                         if(!owned)
00171                                 {
00172                                 Py::_XINCREF (p);
00173                                 }
00174                         validate();
00175                         }
00176 
00177                 // Copy constructor acquires new ownership of pointer
00178                 Object (const Object& ob): p(ob.p)
00179                         {
00180                         Py::_XINCREF (p);
00181                         validate();
00182                         }
00183 
00184                 // Assignment acquires new ownership of pointer
00185                 Object& operator= (const Object& rhs)
00186                         {
00187                         set(rhs.p);
00188                         return *this;
00189                         }
00190 
00191                 Object& operator= (PyObject* rhsp)
00192                         {
00193                         if(ptr() == rhsp) return *this;
00194                         set (rhsp);
00195                         return *this;
00196                         }
00197 
00198                 // Destructor
00199                 virtual ~Object ()
00200                         {
00201                         release ();
00202                         }
00203 
00204                 // Loaning the pointer to others, retain ownership
00205                 PyObject* operator* () const
00206                         {
00207                         return p;
00208                         }
00209 
00210                 // Explicit reference_counting changes
00211                 void increment_reference_count()
00212                         {
00213                         Py::_XINCREF(p);
00214                         }
00215 
00216                 void decrement_reference_count()
00217                         {
00218                         // not allowed to commit suicide, however
00219                         if(reference_count() == 1)
00220                         throw RuntimeError("Object::decrement_reference_count error.");
00221                         Py::_XDECREF(p);
00222                         }
00223                 // Would like to call this pointer() but messes up STL in SeqBase<T>
00224                 PyObject* ptr () const
00225                         {
00226                         return p;
00227                         }
00228 
00229                 //
00230                 // Queries
00231                 //
00232 
00233                 // Can pyob be used in this object's constructor?
00234                 virtual bool accepts (PyObject *pyob) const
00235                         {
00236                         return (pyob != 0);
00237                         }
00238 
00239                 int reference_count () const
00240                         { // the reference count
00241                         return p ? p->ob_refcnt : 0;
00242                         }
00243 
00244                 Type type () const; // the type object associated with this one
00245 
00246                 String str () const; // the str() representation
00247 
00248                 std::string as_string() const;
00249 
00250                 String repr () const; // the repr () representation
00251 
00252                 List dir () const; // the dir() list
00253 
00254                 bool hasAttr (const std::string& s) const
00255                         {
00256                         return PyObject_HasAttrString (p, const_cast<char*>(s.c_str())) ? true: false;
00257                         }
00258 
00259                 Object getAttr (const std::string& s) const
00260                         {
00261                         return Object (PyObject_GetAttrString (p, const_cast<char*>(s.c_str())), true);
00262                         }
00263 
00264                 Object getItem (const Object& key) const
00265                         {
00266                         return Object (PyObject_GetItem(p, *key), true);
00267                         }
00268 
00269                 long hashValue () const
00270                         {
00271                         return PyObject_Hash (p);
00272                         }
00273 
00274                 //
00275                 // int print (FILE* fp, int flags=Py_Print_RAW)
00276                 //      {
00277                 //      return PyObject_Print (p, fp, flags);
00278                 //      }
00279                 //
00280                 bool is(PyObject *pother) const
00281                         {  // identity test
00282                         return p == pother;
00283                         }
00284 
00285                 bool is(const Object& other) const
00286                         { // identity test
00287                         return p == other.p;
00288                         }
00289 
00290                 bool isCallable () const
00291                         {
00292                         return PyCallable_Check (p) != 0;
00293                         }
00294 
00295                 bool isInstance () const
00296                         {
00297                         return PyInstance_Check (p) != 0;
00298                         }
00299 
00300                 bool isDict () const
00301                         {
00302                         return Py::_Dict_Check (p);
00303                         }
00304 
00305                 bool isList () const
00306                         {
00307                         return Py::_List_Check (p);
00308                         }
00309 
00310                 bool isMapping () const
00311                         {
00312                         return PyMapping_Check (p) != 0;
00313                         }
00314 
00315                 bool isNumeric () const
00316                         {
00317                         return PyNumber_Check (p) != 0;
00318                         }
00319 
00320                 bool isSequence () const
00321                         {
00322                         return PySequence_Check (p) != 0;
00323                         }
00324 
00325                 bool isTrue () const
00326                         {
00327                         return PyObject_IsTrue (p) != 0;
00328                         }
00329 
00330                 bool isType (const Type& t) const;
00331 
00332                 bool isTuple() const
00333                         {
00334                         return Py::_Tuple_Check(p);
00335                         }
00336 
00337                 bool isString() const
00338                         {
00339                         return Py::_String_Check(p) || Py::_Unicode_Check(p);
00340                         }
00341 
00342                 bool isUnicode() const
00343                         {
00344                         return Py::_Unicode_Check(p);
00345                         }
00346 
00347                 // Commands
00348                 void setAttr (const std::string& s, const Object& value)
00349                         {
00350                         if(PyObject_SetAttrString (p, const_cast<char*>(s.c_str()), *value) == -1)
00351                         throw AttributeError ("getAttr failed.");
00352                         }
00353 
00354                 void delAttr (const std::string& s)
00355                         {
00356                         if(PyObject_DelAttrString (p, const_cast<char*>(s.c_str())) == -1)
00357                         throw AttributeError ("delAttr failed.");
00358                         }
00359 
00360                 // PyObject_SetItem is too weird to be using from C++
00361                 // so it is intentionally omitted.
00362 
00363                 void delItem (const Object& /*key*/)
00364                         {
00365                         //if(PyObject_DelItem(p, *key) == -1)
00366                         // failed to link on Windows?
00367                         throw KeyError("delItem failed.");
00368                         }
00369                 // Equality and comparison use PyObject_Compare
00370 
00371                 bool operator==(const Object& o2) const
00372                         {
00373                         int k = PyObject_Compare (p, *o2);
00374                         if (PyErr_Occurred()) throw Exception();
00375                         return k == 0;
00376                         }
00377 
00378                 bool operator!=(const Object& o2) const
00379                         {
00380                         int k = PyObject_Compare (p, *o2);
00381                         if (PyErr_Occurred()) throw Exception();
00382                         return k != 0;
00383 
00384                         }
00385 
00386                 bool operator>=(const Object& o2) const
00387                         {
00388                         int k = PyObject_Compare (p, *o2);
00389                         if (PyErr_Occurred()) throw Exception();
00390                         return k >= 0;
00391                         }
00392 
00393                 bool operator<=(const Object& o2) const
00394                         {
00395                         int k = PyObject_Compare (p, *o2);
00396                         if (PyErr_Occurred()) throw Exception();
00397                         return k <= 0;
00398                         }
00399 
00400                 bool operator<(const Object& o2) const
00401                         {
00402                         int k = PyObject_Compare (p, *o2);
00403                         if (PyErr_Occurred()) throw Exception();
00404                         return k < 0;
00405                         }
00406 
00407                 bool operator>(const Object& o2) const
00408                         {
00409                         int k = PyObject_Compare (p, *o2);
00410                         if (PyErr_Occurred()) throw Exception();
00411                         return k > 0;
00412                         }
00413                 };
00414         // End of class Object
00415         inline PyObject* new_reference_to(const Object& g)
00416                 {
00417                 PyObject* p = g.ptr();
00418                 Py::_XINCREF(p);
00419                 return p;
00420                 }
00421 
00422         // Nothing() is what an extension method returns if
00423         // there is no other return value.
00424         inline Object Nothing()
00425                 {
00426                 return Object(Py::_None());
00427                 }
00428 
00429         // Python special None value
00430         inline Object None()
00431                 {
00432                 return Object(Py::_None());
00433                 }
00434 
00435         // TMM: 31May'01 - Added the #ifndef so I can exlude iostreams.
00436 #ifndef CXX_NO_IOSTREAMS
00437         std::ostream& operator<< (std::ostream& os, const Object& ob);
00438 #endif
00439 
00440         // Class Type
00441         class Type: public Object
00442                 {
00443         public:
00444                 explicit Type (PyObject* pyob, bool owned = false): Object(pyob, owned)
00445                         {
00446                         validate();
00447                         }
00448 
00449                 Type (const Object& ob): Object(*ob)
00450                         {
00451                         validate();
00452                         }
00453 
00454                 Type(const Type& t): Object(t)
00455                         {
00456                         validate();
00457                         }
00458 
00459                 Type& operator= (const Object& rhs)
00460                         {
00461                         return (*this = *rhs);
00462                         }
00463 
00464                 Type& operator= (PyObject* rhsp)
00465                         {
00466                         if(ptr() == rhsp) return *this;
00467                         set (rhsp);
00468                         return *this;
00469                         }
00470                 virtual bool accepts (PyObject *pyob) const
00471                         {
00472                         return pyob && Py::_Type_Check (pyob);
00473                         }
00474                 };
00475 
00476 
00477         //
00478         //      Convert an owned Python pointer into a CXX Object
00479         //
00480         inline Object asObject (PyObject *p)
00481                 {
00482                 return Object(p, true);
00483                 }
00484 
00485 
00486 
00487 
00488         // ===============================================
00489         // class Int
00490         class Int: public Object
00491                 {
00492         public:
00493                 // Constructor
00494                 explicit Int (PyObject *pyob, bool owned = false): Object (pyob, owned)
00495                         {
00496                         validate();
00497                         }
00498 
00499                 Int (const Int& ob): Object(*ob)
00500                         {
00501                         validate();
00502                         }
00503 
00504                 // create from long
00505                 explicit Int (long v = 0L): Object(PyInt_FromLong(v), true)
00506                         {
00507                         validate();
00508                         }
00509 
00510                 // create from int
00511                 explicit Int (int v)
00512                         {
00513                         long w = v;
00514                         set(PyInt_FromLong(w), true);
00515                         validate();
00516                         }
00517 
00518                 // create from bool
00519                 explicit Int (bool v)
00520                         {
00521                         long w = v ? 1 : 0;
00522                         set(PyInt_FromLong(w), true);
00523                         validate();
00524                         }
00525 
00526                 explicit Int (const Object& ob)
00527                         {
00528                         set(PyNumber_Int(*ob), true);
00529                         validate();
00530                         }
00531 
00532                 // Assignment acquires new ownership of pointer
00533 
00534                 Int& operator= (const Object& rhs)
00535                         {
00536                         return (*this = *rhs);
00537                         }
00538 
00539                 Int& operator= (PyObject* rhsp)
00540                         {
00541                         if(ptr() == rhsp) return *this;
00542                         set (PyNumber_Int(rhsp), true);
00543                         return *this;
00544                         }
00545                 // Membership
00546                 virtual bool accepts (PyObject *pyob) const
00547                         {
00548                         return pyob && Py::_Int_Check (pyob);
00549                         }
00550                 // convert to long
00551                 operator long() const
00552                         {
00553                         return PyInt_AsLong (ptr());
00554                         }
00555                 // assign from an int
00556                 Int& operator= (int v)
00557                         {
00558                         set (PyInt_FromLong (long(v)), true);
00559                         return *this;
00560                         }
00561                 // assign from long
00562                 Int& operator= (long v)
00563                         {
00564                         set (PyInt_FromLong (v), true);
00565                         return *this;
00566                         }
00567                 };
00568 
00569         // ===============================================
00570         // class Long
00571         class Long: public Object
00572                 {
00573         public:
00574                 // Constructor
00575                 explicit Long (PyObject *pyob, bool owned = false): Object (pyob, owned)
00576                         {
00577                         validate();
00578                         }
00579 
00580                 Long (const Long& ob): Object(ob.ptr())
00581                         {
00582                         validate();
00583                         }
00584 
00585                 // create from long
00586                 explicit Long (long v = 0L)
00587                         : Object(PyLong_FromLong(v), true)
00588                         {
00589                         validate();
00590                         }
00591                 // create from unsigned long
00592                 explicit Long (unsigned long v)
00593                         : Object(PyLong_FromUnsignedLong(v), true)
00594                         {
00595                         validate();
00596                         }
00597                 // create from int
00598                 explicit Long (int v)
00599                         : Object(PyLong_FromLong(static_cast<long>(v)), true)
00600                         {
00601                         validate();
00602                         }
00603 
00604                 // try to create from any object
00605                 Long (const Object& ob)
00606                         : Object(PyNumber_Long(*ob), true)
00607                         {
00608                         validate();
00609                         }
00610 
00611                 // Assignment acquires new ownership of pointer
00612 
00613                 Long& operator= (const Object& rhs)
00614                         {
00615                         return (*this = *rhs);
00616                         }
00617 
00618                 Long& operator= (PyObject* rhsp)
00619                         {
00620                         if(ptr() == rhsp) return *this;
00621                         set (PyNumber_Long(rhsp), true);
00622                         return *this;
00623                         }
00624                 // Membership
00625                 virtual bool accepts (PyObject *pyob) const
00626                         {
00627                         return pyob && Py::_Long_Check (pyob);
00628                         }
00629                 // convert to long
00630                 operator long() const
00631                         {
00632                         return PyLong_AsLong (ptr());
00633                         }
00634                 // convert to unsigned
00635                 operator unsigned long() const
00636                         {
00637                         return PyLong_AsUnsignedLong (ptr());
00638                         }
00639                 operator double() const
00640                         {
00641                         return PyLong_AsDouble (ptr());
00642                         }
00643                 // assign from an int
00644                 Long& operator= (int v)
00645                         {
00646                         set(PyLong_FromLong (long(v)), true);
00647                         return *this;
00648                         }
00649                 // assign from long
00650                 Long& operator= (long v)
00651                         {
00652                         set(PyLong_FromLong (v), true);
00653                         return *this;
00654                         }
00655                 // assign from unsigned long
00656                 Long& operator= (unsigned long v)
00657                         {
00658                         set(PyLong_FromUnsignedLong (v), true);
00659                         return *this;
00660                         }
00661                 };
00662 
00663         // ===============================================
00664         // class Float
00665         //
00666         class Float: public Object
00667                 {
00668         public:
00669                 // Constructor
00670                 explicit Float (PyObject *pyob, bool owned = false): Object(pyob, owned)
00671                         {
00672                         validate();
00673                         }
00674 
00675                 Float (const Float& f): Object(f)
00676                         {
00677                         validate();
00678                         }
00679 
00680                 // make from double
00681                 explicit Float (double v=0.0)
00682                         : Object(PyFloat_FromDouble (v), true)
00683                         {
00684                         validate();
00685                         }
00686 
00687                 // try to make from any object
00688                 Float (const Object& ob)
00689                         : Object(PyNumber_Float(*ob), true)
00690                         {
00691                         validate();
00692                         }
00693 
00694                 Float& operator= (const Object& rhs)
00695                         {
00696                         return (*this = *rhs);
00697                         }
00698 
00699                 Float& operator= (PyObject* rhsp)
00700                         {
00701                         if(ptr() == rhsp) return *this;
00702                         set (PyNumber_Float(rhsp), true);
00703                         return *this;
00704                         }
00705                 // Membership
00706                 virtual bool accepts (PyObject *pyob) const
00707                         {
00708                         return pyob && Py::_Float_Check (pyob);
00709                         }
00710                 // convert to double
00711                 operator double () const
00712                         {
00713                         return PyFloat_AsDouble (ptr());
00714                         }
00715                 // assign from a double
00716                 Float& operator= (double v)
00717                         {
00718                         set(PyFloat_FromDouble (v), true);
00719                         return *this;
00720                         }
00721                 // assign from an int
00722                 Float& operator= (int v)
00723                         {
00724                         set(PyFloat_FromDouble (double(v)), true);
00725                         return *this;
00726                         }
00727                 // assign from long
00728                 Float& operator= (long v)
00729                         {
00730                         set(PyFloat_FromDouble (double(v)), true);
00731                         return *this;
00732                         }
00733                 // assign from an Int
00734                 Float& operator= (const Int& iob)
00735                         {
00736                         set(PyFloat_FromDouble (double(long(iob))), true);
00737                         return *this;
00738                         }
00739                 };
00740 
00741         // ===============================================
00742         // class Complex
00743         class Complex: public Object
00744                 {
00745         public:
00746                 // Constructor
00747                 explicit Complex (PyObject *pyob, bool owned = false): Object(pyob, owned)
00748                         {
00749                         validate();
00750                         }
00751 
00752                 Complex (const Complex& f): Object(f)
00753                         {
00754                         validate();
00755                         }
00756 
00757                 // make from double
00758                 explicit Complex (double v=0.0, double w=0.0)
00759                         :Object(PyComplex_FromDoubles (v, w), true)
00760                         {
00761                         validate();
00762                         }
00763 
00764                 Complex& operator= (const Object& rhs)
00765                         {
00766                         return (*this = *rhs);
00767                         }
00768 
00769                 Complex& operator= (PyObject* rhsp)
00770                         {
00771                         if(ptr() == rhsp) return *this;
00772                         set (rhsp);
00773                         return *this;
00774                         }
00775                 // Membership
00776                 virtual bool accepts (PyObject *pyob) const
00777                         {
00778                         return pyob && Py::_Complex_Check (pyob);
00779                         }
00780                 // convert to Py_complex
00781                 operator Py_complex () const
00782                         {
00783                         return PyComplex_AsCComplex (ptr());
00784                         }
00785                 // assign from a Py_complex
00786                 Complex& operator= (const Py_complex& v)
00787                         {
00788                         set(PyComplex_FromCComplex (v), true);
00789                         return *this;
00790                         }
00791                 // assign from a double
00792                 Complex& operator= (double v)
00793                         {
00794                         set(PyComplex_FromDoubles (v, 0.0), true);
00795                         return *this;
00796                         }
00797                 // assign from an int
00798                 Complex& operator= (int v)
00799                         {
00800                         set(PyComplex_FromDoubles (double(v), 0.0), true);
00801                         return *this;
00802                         }
00803                 // assign from long
00804                 Complex& operator= (long v)
00805                         {
00806                         set(PyComplex_FromDoubles (double(v), 0.0), true);
00807                         return *this;
00808                         }
00809                 // assign from an Int
00810                 Complex& operator= (const Int& iob)
00811                         {
00812                         set(PyComplex_FromDoubles (double(long(iob)), 0.0), true);
00813                         return *this;
00814                         }
00815 
00816                 double real() const
00817                         {
00818                         return PyComplex_RealAsDouble(ptr());
00819                         }
00820 
00821                 double imag() const
00822                         {
00823                         return PyComplex_ImagAsDouble(ptr());
00824                         }
00825                 };
00826         // Sequences
00827         // Sequences are here represented as sequences of items of type T.
00828         // The base class SeqBase<T> represents that.
00829         // In basic Python T is always "Object".
00830 
00831         // seqref<T> is what you get if you get elements from a non-const SeqBase<T>.
00832         // Note: seqref<T> could probably be a nested class in SeqBase<T> but that might stress
00833         // some compilers needlessly. Simlarly for mapref later.
00834 
00835         // While this class is not intended for enduser use, it needs some public
00836         // constructors for the benefit of the STL.
00837 
00838         // See Scott Meyer's More Essential C++ for a description of proxies.
00839         // This application is even more complicated. We are doing an unusual thing
00840         // in having a double proxy. If we want the STL to work
00841         // properly we have to compromise by storing the rvalue inside. The
00842         // entire Object API is repeated so that things like s[i].isList() will
00843         // work properly.
00844 
00845         // Still, once in a while a weird compiler message may occur using expressions like x[i]
00846         // Changing them to Object(x[i]) helps the compiler to understand that the
00847         // conversion of a seqref to an Object is wanted.
00848 
00849         template<TEMPLATE_TYPENAME T>
00850         class seqref
00851                 {
00852         protected:
00853                 SeqBase<T>& s; // the sequence
00854                 int offset; // item number
00855                 T the_item; // lvalue
00856         public:
00857 
00858                 seqref (SeqBase<T>& seq, sequence_index_type j)
00859                         : s(seq), offset(j), the_item (s.getItem(j))
00860                         {}
00861 
00862                 seqref (const seqref<T>& range)
00863                         : s(range.s), offset(range.offset), the_item(range.the_item)
00864                         {}
00865 
00866                 // TMM: added this seqref ctor for use with STL algorithms
00867                 seqref (Object& obj)
00868                         : s(dynamic_cast< SeqBase<T>&>(obj))
00869                         , offset( NULL )
00870                         , the_item(s.getItem(offset))
00871                         {}
00872                 ~seqref()
00873                         {}
00874 
00875                 operator T() const
00876                         { // rvalue
00877                         return the_item;
00878                         }
00879 
00880                 seqref<T>& operator=(const seqref<T>& rhs)
00881                         { //used as lvalue
00882                         the_item = rhs.the_item;
00883                         s.setItem(offset, the_item);
00884                         return *this;
00885                         }
00886 
00887                 seqref<T>& operator=(const T& ob)
00888                         { // used as lvalue
00889                         the_item = ob;
00890                         s.setItem(offset, ob);
00891                         return *this;
00892                         }
00893 
00894                 // forward everything else to the item
00895                 PyObject* ptr () const
00896                         {
00897                         return the_item.ptr();
00898                         }
00899 
00900                 int reference_count () const
00901                         { // the reference count
00902                         return the_item.reference_count();
00903                         }
00904 
00905                 Type type () const
00906                         {
00907                         return the_item.type();
00908                         }
00909 
00910                 String str () const;
00911 
00912                 String repr () const;
00913 
00914                 bool hasAttr (const std::string& attr_name) const
00915                         {
00916                         return the_item.hasAttr(attr_name);
00917                         }
00918 
00919                 Object getAttr (const std::string& attr_name) const
00920                         {
00921                         return the_item.getAttr(attr_name);
00922                         }
00923 
00924                 Object getItem (const Object& key) const
00925                         {
00926                         return the_item.getItem(key);
00927                         }
00928 
00929                 long hashValue () const
00930                         {
00931                         return the_item.hashValue();
00932                         }
00933 
00934                 bool isCallable () const
00935                         {
00936                         return the_item.isCallable();
00937                         }
00938 
00939                 bool isDict () const
00940                         {
00941                         return the_item.isDict();
00942                         }
00943 
00944                 bool isList () const
00945                         {
00946                         return the_item.isList();
00947                         }
00948 
00949                 bool isMapping () const
00950                         {
00951                         return the_item.isMapping();
00952                         }
00953 
00954                 bool isNumeric () const
00955                         {
00956                         return the_item.isNumeric();
00957                         }
00958 
00959                 bool isSequence () const
00960                         {
00961                         return the_item.isSequence();
00962                         }
00963 
00964                 bool isTrue () const
00965                         {
00966                         return the_item.isTrue();
00967                         }
00968 
00969                 bool isType (const Type& t) const
00970                         {
00971                         return the_item.isType (t);
00972                         }
00973 
00974                 bool isTuple() const
00975                         {
00976                         return the_item.isTuple();
00977                         }
00978 
00979                 bool isString() const
00980                         {
00981                         return the_item.isString();
00982                         }
00983                 // Commands
00984                 void setAttr (const std::string& attr_name, const Object& value)
00985                         {
00986                         the_item.setAttr(attr_name, value);
00987                         }
00988 
00989                 void delAttr (const std::string& attr_name)
00990                         {
00991                         the_item.delAttr(attr_name);
00992                         }
00993 
00994                 void delItem (const Object& key)
00995                         {
00996                         the_item.delItem(key);
00997                         }
00998 
00999                 bool operator==(const Object& o2) const
01000                         {
01001                         return the_item == o2;
01002                         }
01003 
01004                 bool operator!=(const Object& o2) const
01005                         {
01006                         return the_item != o2;
01007                         }
01008 
01009                 bool operator>=(const Object& o2) const
01010                         {
01011                         return the_item >= o2;
01012                         }
01013 
01014                 bool operator<=(const Object& o2) const
01015                         {
01016                         return the_item <= o2;
01017                         }
01018 
01019                 bool operator<(const Object& o2) const
01020                         {
01021                         return the_item < o2;
01022                         }
01023 
01024                 bool operator>(const Object& o2) const
01025                         {
01026                         return the_item > o2;
01027                         }
01028                 }; // end of seqref
01029 
01030 
01031         // class SeqBase<T>
01032         // ...the base class for all sequence types
01033 
01034         template<TEMPLATE_TYPENAME T>
01035         class SeqBase: public Object
01036                 {
01037         public:
01038                 // STL definitions
01039                 typedef size_t size_type;
01040                 typedef seqref<T> reference;
01041                 typedef T const_reference;
01042                 typedef seqref<T>* pointer;
01043                 typedef int difference_type;
01044                 typedef T value_type;           // TMM: 26Jun'01
01045 
01046                 virtual size_type max_size() const
01047                         {
01048                         return std::string::npos; // ?
01049                         }
01050 
01051                 virtual size_type capacity() const
01052                         {
01053                         return size();
01054                         }
01055 
01056                 virtual void swap(SeqBase<T>& c)
01057                         {
01058                         SeqBase<T> temp = c;
01059                         c = ptr();
01060                         set(temp.ptr());
01061                         }
01062 
01063                 virtual size_type size () const
01064                         {
01065                         return PySequence_Length (ptr());
01066                         }
01067 
01068                 explicit SeqBase<T> ()
01069                         :Object(PyTuple_New(0), true)
01070                         {
01071                         validate();
01072                         }
01073 
01074                 explicit SeqBase<T> (PyObject* pyob, bool owned=false)
01075                         : Object(pyob, owned)
01076                         {
01077                         validate();
01078                         }
01079 
01080                 SeqBase<T> (const Object& ob): Object(ob)
01081                         {
01082                         validate();
01083                         }
01084 
01085                 // Assignment acquires new ownership of pointer
01086 
01087                 SeqBase<T>& operator= (const Object& rhs)
01088                         {
01089                         return (*this = *rhs);
01090                         }
01091 
01092                 SeqBase<T>& operator= (PyObject* rhsp)
01093                         {
01094                         if(ptr() == rhsp) return *this;
01095                         set (rhsp);
01096                         return *this;
01097                         }
01098 
01099                 virtual bool accepts (PyObject *pyob) const
01100                         {
01101                         return pyob && PySequence_Check (pyob);
01102                         }
01103 
01104                 size_type length () const
01105                         {
01106                         return PySequence_Length (ptr());
01107                         }
01108 
01109                 // Element access
01110                 const T operator[](sequence_index_type index) const
01111                         {
01112                         return getItem(index);
01113                         }
01114 
01115                 seqref<T> operator[](sequence_index_type index)
01116                         {
01117                         return seqref<T>(*this, index);
01118                         }
01119 
01120                 virtual T getItem (sequence_index_type i) const
01121                         {
01122                         return T(asObject(PySequence_GetItem (ptr(), i)));
01123                         }
01124 
01125                 virtual void setItem (sequence_index_type i, const T& ob)
01126                         {
01127                         if (PySequence_SetItem (ptr(), i, *ob) == -1)
01128                                 {
01129                                 throw Exception();
01130                                 }
01131                         }
01132 
01133                 SeqBase<T> repeat (int count) const
01134                         {
01135                         return SeqBase<T> (PySequence_Repeat (ptr(), count), true);
01136                         }
01137 
01138                 SeqBase<T> concat (const SeqBase<T>& other) const
01139                         {
01140                         return SeqBase<T> (PySequence_Concat(ptr(), *other), true);
01141                         }
01142 
01143                 // more STL compatability
01144                 const T front () const
01145                         {
01146                         return getItem(0);
01147                         }
01148 
01149                 seqref<T> front()
01150                         {
01151                         return seqref<T>(this, 0);
01152                         }
01153 
01154                 const T back () const
01155                         {
01156                         return getItem(size()-1);
01157                         }
01158 
01159                 seqref<T> back()
01160                         {
01161                         return seqref<T>(this, size()-1);
01162                         }
01163 
01164                 void verify_length(size_type required_size) const
01165                         {
01166                         if (size() != required_size)
01167                         throw IndexError ("Unexpected SeqBase<T> length.");
01168                         }
01169 
01170                 void verify_length(size_type min_size, size_type max_size) const
01171                         {
01172                         size_type n = size();
01173                         if (n < min_size || n > max_size)
01174                         throw IndexError ("Unexpected SeqBase<T> length.");
01175                         }
01176 
01177                 class iterator
01178                         : public random_access_iterator_parent(seqref<T>)
01179                         {
01180                 protected:
01181                         friend class SeqBase<T>;
01182                         SeqBase<T>* seq;
01183                         int count;
01184 
01185                 public:
01186                         ~iterator ()
01187                                 {}
01188 
01189                         iterator ()
01190                                 : seq( 0 )
01191                                 , count( 0 )
01192                                 {}
01193 
01194                         iterator (SeqBase<T>* s, int where)
01195                                 : seq( s )
01196                                 , count( where )
01197                                 {}
01198 
01199                         iterator (const iterator& other)
01200                                 : seq( other.seq )
01201                                 , count( other.count )
01202                                 {}
01203 
01204                         bool eql (const iterator& other) const
01205                                 {
01206                                 return (*seq == *other.seq) && (count == other.count);
01207                                 }
01208 
01209                         bool neq (const iterator& other) const
01210                                 {
01211                                 return (*seq != *other.seq) || (count != other.count);
01212                                 }
01213 
01214                         bool lss (const iterator& other) const
01215                                 {
01216                                 return (count < other.count);
01217                                 }
01218 
01219                         bool gtr (const iterator& other) const
01220                                 {
01221                                 return (count > other.count);
01222                                 }
01223 
01224                         bool leq (const iterator& other) const
01225                                 {
01226                                 return (count <= other.count);
01227                                 }
01228 
01229                         bool geq (const iterator& other) const
01230                                 {
01231                                 return (count >= other.count);
01232                                 }
01233 
01234                         seqref<T> operator*()
01235                                 {
01236                                 return seqref<T>(*seq, count);
01237                                 }
01238 
01239                         seqref<T> operator[] (sequence_index_type i)
01240                                 {
01241                                 return seqref<T>(*seq, count + i);
01242                                 }
01243 
01244                         iterator& operator=(const iterator& other)
01245                                 {
01246                                 if (this == &other) return *this;
01247                                 seq = other.seq;
01248                                 count = other.count;
01249                                 return *this;
01250                                 }
01251 
01252                         iterator operator+(int n) const
01253                                 {
01254                                 return iterator(seq, count + n);
01255                                 }
01256 
01257                         iterator operator-(int n) const
01258                                 {
01259                                 return iterator(seq, count - n);
01260                                 }
01261 
01262                         iterator& operator+=(int n)
01263                                 {
01264                                 count = count + n;
01265                                 return *this;
01266                                 }
01267 
01268                         iterator& operator-=(int n)
01269                                 {
01270                                 count = count - n;
01271                                 return *this;
01272                                 }
01273 
01274                         int operator-(const iterator& other) const
01275                                 {
01276                                 if (*seq != *other.seq)
01277                                 throw RuntimeError ("SeqBase<T>::iterator comparison error");
01278                                 return count - other.count;
01279                                 }
01280 
01281                         // prefix ++
01282                         iterator& operator++ ()
01283                                 { count++; return *this;}
01284                         // postfix ++
01285                         iterator operator++ (int)
01286                                 { return iterator(seq, count++);}
01287                         // prefix --
01288                         iterator& operator-- ()
01289                                 { count--; return *this;}
01290                         // postfix --
01291                         iterator operator-- (int)
01292                                 { return iterator(seq, count--);}
01293 
01294                         std::string diagnose() const
01295                                 {
01296                                 std::OSTRSTREAM oss;
01297                                 oss << "iterator diagnosis " << seq << ", " << count << std::ends;
01298                                 return std::string(oss.str());
01299                                 }
01300                         };    // end of class SeqBase<T>::iterator
01301 
01302                 iterator begin ()
01303                         {
01304                         return iterator(this, 0);
01305                         }
01306 
01307                 iterator end ()
01308                         {
01309                         return iterator(this, length());
01310                         }
01311 
01312                 class const_iterator
01313                         : public random_access_iterator_parent(const Object)
01314                         {
01315                 protected:
01316                         friend class SeqBase<T>;
01317                         const SeqBase<T>* seq;
01318                         sequence_index_type count;
01319 
01320                 public:
01321                         ~const_iterator ()
01322                                 {}
01323 
01324                         const_iterator ()
01325                                 : seq( 0 )
01326                                 , count( 0 )
01327                                 {}
01328 
01329                         const_iterator (const SeqBase<T>* s, int where)
01330                                 : seq( s )
01331                                 , count( where )
01332                                 {}
01333 
01334                         const_iterator(const const_iterator& other)
01335                                 : seq( other.seq )
01336                                 , count( other.count )
01337                                 {}
01338 
01339                         const T operator*() const
01340                                 {
01341                                 return seq->getItem(count);
01342                                 }
01343 
01344                         const T operator[] (sequence_index_type i) const
01345                                 {
01346                                 return seq->getItem(count + i);
01347                                 }
01348 
01349                         const_iterator& operator=(const const_iterator& other)
01350                                 {
01351                                 if (this == &other) return *this;
01352                                 seq = other.seq;
01353                                 count = other.count;
01354                                 return *this;
01355                                 }
01356 
01357                         const_iterator operator+(int n) const
01358                                 {
01359                                 return const_iterator(seq, count + n);
01360                                 }
01361 
01362                         bool eql (const const_iterator& other) const
01363                                 {
01364                                 return (*seq == *other.seq) && (count == other.count);
01365                                 }
01366 
01367                         bool neq (const const_iterator& other) const
01368                                 {
01369                                 return (*seq != *other.seq) || (count != other.count);
01370                                 }
01371 
01372                         bool lss (const const_iterator& other) const
01373                                 {
01374                                 return (count < other.count);
01375                                 }
01376 
01377                         bool gtr (const const_iterator& other) const
01378                                 {
01379                                 return (count > other.count);
01380                                 }
01381 
01382                         bool leq (const const_iterator& other) const
01383                                 {
01384                                 return (count <= other.count);
01385                                 }
01386 
01387                         bool geq (const const_iterator& other) const
01388                                 {
01389                                 return (count >= other.count);
01390                                 }
01391 
01392                         const_iterator operator-(int n)
01393                                 {
01394                                 return const_iterator(seq, count - n);
01395                                 }
01396 
01397                         const_iterator& operator+=(int n)
01398                                 {
01399                                 count = count + n;
01400                                 return *this;
01401                                 }
01402 
01403                         const_iterator& operator-=(int n)
01404                                 {
01405                                 count = count - n;
01406                                 return *this;
01407                                 }
01408 
01409                         int operator-(const const_iterator& other) const
01410                                 {
01411                                 if (*seq != *other.seq)
01412                                 throw RuntimeError ("SeqBase<T>::const_iterator::- error");
01413                                 return count - other.count;
01414                                 }
01415                         // prefix ++
01416                         const_iterator& operator++ ()
01417                                 { count++; return *this;}
01418                         // postfix ++
01419                         const_iterator operator++ (int)
01420                                 { return const_iterator(seq, count++);}
01421                         // prefix --
01422                         const_iterator& operator-- ()
01423                                 { count--; return *this;}
01424                         // postfix --
01425                         const_iterator operator-- (int)
01426                                 { return const_iterator(seq, count--);}
01427                         };    // end of class SeqBase<T>::const_iterator
01428 
01429                 const_iterator begin () const
01430                         {
01431                         return const_iterator(this, 0);
01432                         }
01433 
01434                 const_iterator end () const
01435                         {
01436                         return const_iterator(this, length());
01437                         }
01438                 };
01439 
01440         // Here's an important typedef you might miss if reading too fast...
01441         typedef SeqBase<Object> Sequence;
01442 
01443         template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01444         template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01445         template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01446         template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01447         template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01448         template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01449 
01450         template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01451         template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01452         template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01453         template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01454         template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01455         template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right); 
01456 
01457 
01458         extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right);
01459         extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right);
01460         extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right);
01461         extern bool operator> (const Sequence::iterator& left, const Sequence::iterator& right);
01462         extern bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right);
01463         extern bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right);
01464 
01465         extern bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01466         extern bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01467         extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01468         extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01469         extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01470         extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right); 
01471 
01472         // ==================================================
01473         // class Char
01474         // Python strings return strings as individual elements.
01475         // I'll try having a class Char which is a String of length 1
01476         //
01477         typedef std::basic_string<Py_UNICODE> unicodestring;
01478         extern Py_UNICODE unicode_null_string[1];
01479 
01480         class Char: public Object
01481                 {
01482         public:
01483                 explicit Char (PyObject *pyob, bool owned = false): Object(pyob, owned)
01484                         {
01485                         validate();
01486                         }
01487 
01488                 Char (const Object& ob): Object(ob)
01489                         {
01490                         validate();
01491                         }
01492 
01493                 Char (const std::string& v = "")
01494                         :Object(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true)
01495                         {
01496                         validate();
01497                         }
01498 
01499                 Char (char v)
01500                         : Object(PyString_FromStringAndSize (&v, 1), true)
01501                         {
01502                         validate();
01503                         }
01504 
01505                 Char (Py_UNICODE v)
01506                         : Object(PyUnicode_FromUnicode (&v, 1), true)
01507                         {
01508                         validate();
01509                         }
01510                 // Assignment acquires new ownership of pointer
01511                 Char& operator= (const Object& rhs)
01512                         {
01513                         return (*this = *rhs);
01514                         }
01515 
01516                 Char& operator= (PyObject* rhsp)
01517                         {
01518                         if(ptr() == rhsp) return *this;
01519                         set (rhsp);
01520                         return *this;
01521                         }
01522 
01523                 // Membership
01524                 virtual bool accepts (PyObject *pyob) const
01525                         {
01526                         return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob)) && PySequence_Length (pyob) == 1;
01527                         }
01528 
01529                 // Assignment from C string
01530                 Char& operator= (const std::string& v)
01531                         {
01532                         set(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true);
01533                         return *this;
01534                         }
01535 
01536                 Char& operator= (char v)
01537                         {
01538                         set(PyString_FromStringAndSize (&v, 1), true);
01539                         return *this;
01540                         }
01541 
01542                 Char& operator= (const unicodestring& v)
01543                         {
01544                         set(PyUnicode_FromUnicode (const_cast<Py_UNICODE*>(v.data()),1), true);
01545                         return *this;
01546                         }
01547 
01548                 Char& operator= (Py_UNICODE v)
01549                         {
01550                         set(PyUnicode_FromUnicode (&v, 1), true);
01551                         return *this;
01552                         }
01553 
01554                 // Conversion
01555                 operator String() const;
01556 
01557                 operator std::string () const
01558                         {
01559                         return std::string(PyString_AsString (ptr()));
01560                         }
01561                 };
01562 
01563         class String: public SeqBase<Char>
01564                 {
01565         public:
01566                 virtual size_type capacity() const
01567                         {
01568                         return max_size();
01569                         }
01570 
01571                 explicit String (PyObject *pyob, bool owned = false): SeqBase<Char>(pyob, owned)
01572                         {
01573                         validate();
01574                         }
01575 
01576                 String (const Object& ob): SeqBase<Char>(ob)
01577                         {
01578                         validate();
01579                         }
01580 
01581                 String()
01582                         : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
01583                         {
01584                         validate();
01585                         }
01586 
01587                 String( const std::string& v )
01588                         : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()),
01589                                 static_cast<int>( v.length() ) ), true )
01590                         {
01591                         validate();
01592                         }
01593 
01594                 String( const char *s, const char *encoding, const char *error="strict" )
01595                         : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true )
01596                         {
01597                         validate();
01598                         }
01599 
01600                 String( const char *s, int len, const char *encoding, const char *error="strict" )
01601                         : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true )
01602                         {
01603                         validate();
01604                         }
01605 
01606                 String( const std::string &s, const char *encoding, const char *error="strict" )
01607                         : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true )
01608                         {
01609                         validate();
01610                         }
01611 
01612                 String( const std::string& v, std::string::size_type vsize )
01613                         : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v.data()),
01614                                         static_cast<int>( vsize ) ), true)
01615                         {
01616                         validate();
01617                         }
01618 
01619                 String( const char *v, int vsize )
01620                         : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
01621                         {
01622                         validate();
01623                         }
01624 
01625                 String( const char* v )
01626                         : SeqBase<Char>( PyString_FromString( v ), true )
01627                         {
01628                         validate();
01629                         }
01630 
01631                 // Assignment acquires new ownership of pointer
01632                 String& operator= ( const Object& rhs )
01633                         {
01634                         return *this = *rhs;
01635                         }
01636 
01637                 String& operator= (PyObject* rhsp)
01638                         {
01639                         if( ptr() == rhsp )
01640                                 return *this;
01641                         set (rhsp);
01642                         return *this;
01643                         }
01644                 // Membership
01645                 virtual bool accepts (PyObject *pyob) const
01646                         {
01647                         return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob));
01648                         }
01649 
01650                 // Assignment from C string
01651                 String& operator= (const std::string& v)
01652                         {
01653                         set( PyString_FromStringAndSize( const_cast<char*>( v.data() ),
01654                                         static_cast<int>( v.length() ) ), true );
01655                         return *this;
01656                         }
01657                 String& operator= (const unicodestring& v)
01658                         {
01659                         set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ),
01660                                         static_cast<int>( v.length() ) ), true );
01661                         return *this;
01662                         }
01663 
01664 
01665                 // Encode
01666                 String encode( const char *encoding, const char *error="strict" )
01667                         {
01668                         if( isUnicode() )
01669                         {
01670                                 return String( PyUnicode_AsEncodedString( ptr(), encoding, error ) );
01671                         }
01672                         else
01673                         {
01674                                 return String( PyString_AsEncodedObject( ptr(), encoding, error ) );
01675                         }
01676                         }
01677 
01678                 String decode( const char *encoding, const char *error="strict" )
01679                         {
01680                         return Object( PyString_AsDecodedObject( ptr(), encoding, error ) );
01681                         }
01682 
01683                 // Queries
01684                 virtual size_type size () const
01685                         {
01686                         if( isUnicode() )
01687                         {
01688                                 return static_cast<size_type>( PyUnicode_GET_SIZE (ptr()) );
01689                         }
01690                         else
01691                         {
01692                                 return static_cast<size_type>( PyString_Size (ptr()) );
01693                         }
01694                         }
01695 
01696                 operator std::string () const
01697                         {
01698                         return as_std_string();
01699                         }
01700 
01701                 std::string as_std_string() const
01702                         {
01703                         if( isUnicode() )
01704                         {
01705                                 throw TypeError("cannot return std::string from Unicode object");
01706                         }
01707                         else
01708                         {
01709                                 return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
01710                         }
01711                         }
01712 
01713                 unicodestring as_unicodestring() const
01714                         {
01715                         if( isUnicode() )
01716                         {
01717                                 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
01718                                         static_cast<size_type>( PyUnicode_GET_SIZE( ptr() ) ) );
01719                         }
01720                         else
01721                         {
01722                                 throw TypeError("can only return unicodestring from Unicode object");
01723                         }
01724                         }
01725                 };
01726 
01727         // ==================================================
01728         // class Tuple
01729         class Tuple: public Sequence
01730                 {
01731         public:
01732                 virtual void setItem (sequence_index_type offset, const Object&ob)
01733                         {
01734                         // note PyTuple_SetItem is a thief...
01735                         if(PyTuple_SetItem (ptr(), offset, new_reference_to(ob)) == -1)
01736                                 {
01737                                 throw Exception();
01738                                 }
01739                         }
01740 
01741                 // Constructor
01742                 explicit Tuple (PyObject *pyob, bool owned = false): Sequence (pyob, owned)
01743                         {
01744                         validate();
01745                         }
01746 
01747                 Tuple (const Object& ob): Sequence(ob)
01748                         {
01749                         validate();
01750                         }
01751 
01752                 // New tuple of a given size
01753                 explicit Tuple (int size = 0)
01754                         {
01755                         set(PyTuple_New (size), true);
01756                         validate ();
01757                         for (sequence_index_type i=0; i < size; i++)
01758                                 {
01759                                 if(PyTuple_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
01760                                         {
01761                                         throw Exception();
01762                                         }
01763                                 }
01764                         }
01765                 // Tuple from any sequence
01766                 explicit Tuple (const Sequence& s)
01767                         {
01768                         sequence_index_type limit( sequence_index_type( s.length() ) );
01769 
01770                         set(PyTuple_New (limit), true);
01771                         validate();
01772                         
01773                         for(sequence_index_type i=0; i < limit; i++)
01774                                 {
01775                                 if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
01776                                         {
01777                                         throw Exception();
01778                                         }
01779                                 }
01780                         }
01781                 // Assignment acquires new ownership of pointer
01782 
01783                 Tuple& operator= (const Object& rhs)
01784                         {
01785                         return (*this = *rhs);
01786                         }
01787 
01788                 Tuple& operator= (PyObject* rhsp)
01789                         {
01790                         if(ptr() == rhsp) return *this;
01791                         set (rhsp);
01792                         return *this;
01793                         }
01794                 // Membership
01795                 virtual bool accepts (PyObject *pyob) const
01796                         {
01797                         return pyob && Py::_Tuple_Check (pyob);
01798                         }
01799 
01800                 Tuple getSlice (int i, int j) const
01801                         {
01802                         return Tuple (PySequence_GetSlice (ptr(), i, j), true);
01803                         }
01804 
01805                 };
01806 
01807         // ==================================================
01808         // class List
01809 
01810         class List: public Sequence
01811                 {
01812         public:
01813                 // Constructor
01814                 explicit List (PyObject *pyob, bool owned = false): Sequence(pyob, owned)
01815                         {
01816                         validate();
01817                         }
01818                 List (const Object& ob): Sequence(ob)
01819                         {
01820                         validate();
01821                         }
01822                 // Creation at a fixed size
01823                 List (int size = 0)
01824                         {
01825                         set(PyList_New (size), true);
01826                         validate();
01827                         for (sequence_index_type i=0; i < size; i++)
01828                                 {
01829                                 if(PyList_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
01830                                         {
01831                                         throw Exception();
01832                                         }
01833                                 }
01834                         }
01835 
01836                 // List from a sequence
01837                 List (const Sequence& s): Sequence()
01838                         {
01839                         int n = s.length();
01840                         set(PyList_New (n), true);
01841                         validate();
01842                         for (sequence_index_type i=0; i < n; i++)
01843                                 {
01844                                 if(PyList_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
01845                                         {
01846                                         throw Exception();
01847                                         }
01848                                 }
01849                         }
01850 
01851                 virtual size_type capacity() const
01852                         {
01853                         return max_size();
01854                         }
01855                 // Assignment acquires new ownership of pointer
01856 
01857                 List& operator= (const Object& rhs)
01858                         {
01859                         return (*this = *rhs);
01860                         }
01861 
01862                 List& operator= (PyObject* rhsp)
01863                         {
01864                         if(ptr() == rhsp) return *this;
01865                         set (rhsp);
01866                         return *this;
01867                         }
01868                 // Membership
01869                 virtual bool accepts (PyObject *pyob) const
01870                         {
01871                         return pyob && Py::_List_Check (pyob);
01872                         }
01873 
01874                 List getSlice (int i, int j) const
01875                         {
01876                         return List (PyList_GetSlice (ptr(), i, j), true);
01877                         }
01878 
01879                 void setSlice (int i, int j, const Object& v)
01880                         {
01881                         if(PyList_SetSlice (ptr(), i, j, *v) == -1)
01882                                 {
01883                                 throw Exception();
01884                                 }
01885                         }
01886 
01887                 void append (const Object& ob)
01888                         {
01889                         if(PyList_Append (ptr(), *ob) == -1)
01890                                 {
01891                                 throw Exception();
01892                                 }
01893                         }
01894 
01895                 void insert (int i, const Object& ob)
01896                         {
01897                         if(PyList_Insert (ptr(), i, *ob) == -1)
01898                                 {
01899                                 throw Exception();
01900                                 }
01901                         }
01902 
01903                 void sort ()
01904                         {
01905                         if(PyList_Sort(ptr()) == -1)
01906                                 {
01907                                 throw Exception();
01908                                 }
01909                         }
01910 
01911                 void reverse ()
01912                         {
01913                         if(PyList_Reverse(ptr()) == -1)
01914                                 {
01915                                 throw Exception();
01916                                 }
01917                         }
01918                 };
01919 
01920 
01921         // Mappings
01922         // ==================================================
01923         template<TEMPLATE_TYPENAME T>
01924         class mapref
01925                 {
01926         protected:
01927                 MapBase<T>& s; // the map
01928                 Object key; // item key
01929                 T the_item;
01930 
01931         public:
01932                 mapref<T> (MapBase<T>& map, const std::string& k)
01933                         : s(map), the_item()
01934                         {
01935                         key = String(k);
01936                         if(map.hasKey(key)) the_item = map.getItem(key);
01937                         };
01938 
01939                 mapref<T> (MapBase<T>& map, const Object& k)
01940                         : s(map), key(k), the_item()
01941                         {
01942                         if(map.hasKey(key)) the_item = map.getItem(key);
01943                         };
01944 
01945 /*
01946                 ~mapref<T>()
01947                         {}
01948 */
01949 
01950                 // MapBase<T> stuff
01951                 // lvalue
01952                 mapref<T>& operator=(const mapref<T>& other)
01953                         {
01954                         if(this == &other) return *this;
01955                         the_item = other.the_item;
01956                         s.setItem(key, other.the_item);
01957                         return *this;
01958                         };
01959 
01960                 mapref<T>& operator= (const T& ob)
01961                         {
01962                         the_item = ob;
01963                         s.setItem (key, ob);
01964                         return *this;
01965                         }
01966 
01967                 // rvalue
01968                 operator T() const
01969                         {
01970                         return the_item;
01971                         }
01972 
01973                 // forward everything else to the_item
01974                 PyObject* ptr () const
01975                         {
01976                         return the_item.ptr();
01977                         }
01978 
01979                 int reference_count () const
01980                         { // the mapref count
01981                         return the_item.reference_count();
01982                         }
01983 
01984                 Type type () const
01985                         {
01986                         return the_item.type();
01987                         }
01988 
01989                 String str () const
01990                         {
01991                         return the_item.str();
01992                         }
01993 
01994                 String repr () const
01995                         {
01996                         return the_item.repr();
01997                         }
01998 
01999                 bool hasAttr (const std::string& attr_name) const
02000                         {
02001                         return the_item.hasAttr(attr_name);
02002                         }
02003 
02004                 Object getAttr (const std::string& attr_name) const
02005                         {
02006                         return the_item.getAttr(attr_name);
02007                         }
02008 
02009                 Object getItem (const Object& k) const
02010                         {
02011                         return the_item.getItem(k);
02012                         }
02013 
02014                 long hashValue () const
02015                         {
02016                         return the_item.hashValue();
02017                         }
02018 
02019                 bool isCallable () const
02020                         {
02021                         return the_item.isCallable();
02022                         }
02023 
02024                 bool isList () const
02025                         {
02026                         return the_item.isList();
02027                         }
02028 
02029                 bool isMapping () const
02030                         {
02031                         return the_item.isMapping();
02032                         }
02033 
02034                 bool isNumeric () const
02035                         {
02036                         return the_item.isNumeric();
02037                         }
02038 
02039                 bool isSequence () const
02040                         {
02041                         return the_item.isSequence();
02042                         }
02043 
02044                 bool isTrue () const
02045                         {
02046                         return the_item.isTrue();
02047                         }
02048 
02049                 bool isType (const Type& t) const
02050                         {
02051                         return the_item.isType (t);
02052                         }
02053 
02054                 bool isTuple() const
02055                         {
02056                         return the_item.isTuple();
02057                         }
02058 
02059                 bool isString() const
02060                         {
02061                         return the_item.isString();
02062                         }
02063 
02064                 // Commands
02065                 void setAttr (const std::string& attr_name, const Object& value)
02066                         {
02067                         the_item.setAttr(attr_name, value);
02068                         }
02069 
02070                 void delAttr (const std::string& attr_name)
02071                         {
02072                         the_item.delAttr(attr_name);
02073                         }
02074 
02075                 void delItem (const Object& k)
02076                         {
02077                         the_item.delItem(k);
02078                         }
02079                 }; // end of mapref
02080 
02081         // TMM: now for mapref<T>
02082         template< class T >
02083         bool operator==(const mapref<T>& left, const mapref<T>& right)
02084                 {
02085                 return true;    // NOT completed.
02086                 }
02087 
02088         template< class T >
02089         bool operator!=(const mapref<T>& left, const mapref<T>& right)
02090                 {
02091                 return true;    // not completed.
02092                 }
02093 
02094         template<TEMPLATE_TYPENAME T>
02095         class MapBase: public Object
02096                 {
02097         protected:
02098                 explicit MapBase<T>()
02099                         {}
02100         public:
02101                 // reference: proxy class for implementing []
02102                 // TMM: 26Jun'01 - the types
02103                 // If you assume that Python mapping is a hash_map...
02104                 // hash_map::value_type is not assignable, but
02105                 // (*it).second = data must be a valid expression
02106                 typedef size_t size_type;
02107                 typedef Object key_type;
02108                 typedef mapref<T> data_type;
02109                 typedef std::pair< const T, T > value_type;
02110                 typedef std::pair< const T, mapref<T> > reference;
02111                 typedef const std::pair< const T, const T > const_reference;
02112                 typedef std::pair< const T, mapref<T> > pointer;
02113 
02114                 // Constructor
02115                 explicit MapBase<T> (PyObject *pyob, bool owned = false): Object(pyob, owned)
02116                         {
02117                         validate();
02118                         }
02119 
02120                 // TMM: 02Jul'01 - changed MapBase<T> to Object in next line
02121                 MapBase<T> (const Object& ob): Object(ob)
02122                         {
02123                         validate();
02124                         }
02125 
02126                 // Assignment acquires new ownership of pointer
02127                 MapBase<T>& operator= (const Object& rhs)
02128                         {
02129                         return (*this = *rhs);
02130                         }
02131 
02132                 MapBase<T>& operator= (PyObject* rhsp)
02133                         {
02134                         if(ptr() == rhsp) return *this;
02135                         set (rhsp);
02136                         return *this;
02137                         }
02138                 // Membership
02139                 virtual bool accepts (PyObject *pyob) const
02140                         {
02141                         return pyob && PyMapping_Check(pyob);
02142                         }
02143 
02144                 // Clear -- PyMapping Clear is missing
02145                 //
02146 
02147                 void clear ()
02148                         {
02149                         List k = keys();
02150                         for(List::iterator i = k.begin(); i != k.end(); i++)
02151                                 {
02152                                 delItem(*i);
02153                                 }
02154                         }
02155 
02156                 virtual size_type size() const
02157                         {
02158                         return PyMapping_Length (ptr());
02159                         }
02160 
02161                 // Element Access
02162                 T operator[](const std::string& key) const
02163                         {
02164                         return getItem(key);
02165                         }
02166 
02167                 T operator[](const Object& key) const
02168                         {
02169                         return getItem(key);
02170                         }
02171 
02172                 mapref<T> operator[](const std::string& key)
02173                         {
02174                         return mapref<T>(*this, key);
02175                         }
02176 
02177                 mapref<T> operator[](const Object& key)
02178                         {
02179                         return mapref<T>(*this, key);
02180                         }
02181 
02182                 int length () const
02183                         {
02184                         return PyMapping_Length (ptr());
02185                         }
02186 
02187                 bool hasKey (const std::string& s) const
02188                         {
02189                         return PyMapping_HasKeyString (ptr(),const_cast<char*>(s.c_str())) != 0;
02190                         }
02191 
02192                 bool hasKey (const Object& s) const
02193                         {
02194                         return PyMapping_HasKey (ptr(), s.ptr()) != 0;
02195                         }
02196 
02197                 T getItem (const std::string& s) const
02198                         {
02199                         return T(
02200                         asObject(PyMapping_GetItemString (ptr(),const_cast<char*>(s.c_str())))
02201                         );
02202                         }
02203 
02204                 T getItem (const Object& s) const
02205                         {
02206                         return T(
02207                         asObject(PyObject_GetItem (ptr(), s.ptr()))
02208                         );
02209                         }
02210 
02211                 virtual void setItem (const char *s, const Object& ob)
02212                         {
02213                         if (PyMapping_SetItemString (ptr(), const_cast<char*>(s), *ob) == -1)
02214                                 {
02215                                 throw Exception();
02216                                 }
02217                         }
02218 
02219                 virtual void setItem (const std::string& s, const Object& ob)
02220                         {
02221                         if (PyMapping_SetItemString (ptr(), const_cast<char*>(s.c_str()), *ob) == -1)
02222                                 {
02223                                 throw Exception();
02224                                 }
02225                         }
02226 
02227                 virtual void setItem (const Object& s, const Object& ob)
02228                         {
02229                         if (PyObject_SetItem (ptr(), s.ptr(), ob.ptr()) == -1)
02230                                 {
02231                                 throw Exception();
02232                                 }
02233                         }
02234 
02235                 void delItem (const std::string& s)
02236                         {
02237                         if (PyMapping_DelItemString (ptr(), const_cast<char*>(s.c_str())) == -1)
02238                                 {
02239                                 throw Exception();
02240                                 }
02241                         }
02242 
02243                 void delItem (const Object& s)
02244                         {
02245                         if (PyMapping_DelItem (ptr(), *s) == -1)
02246                                 {
02247                                 throw Exception();
02248                                 }
02249                         }
02250                 // Queries
02251                 List keys () const
02252                         {
02253                         return List(PyMapping_Keys(ptr()), true);
02254                         }
02255 
02256                 List values () const
02257                         { // each returned item is a (key, value) pair
02258                         return List(PyMapping_Values(ptr()), true);
02259                         }
02260 
02261                 List items () const
02262                         {
02263                         return List(PyMapping_Items(ptr()), true);
02264                         }
02265 
02266                 // iterators for MapBase<T>
02267                 // Added by TMM: 2Jul'01 - NOT COMPLETED
02268                 // There is still a bug.  I decided to stop, before fixing the bug, because
02269                 // this can't be halfway efficient until Python gets built-in iterators.
02270                 // My current soln is to iterate over the map by getting a copy of its keys
02271                 // and iterating over that.  Not a good solution.
02272 
02273                 // The iterator holds a MapBase<T>* rather than a MapBase<T> because that's
02274                 // how the sequence iterator is implemented and it works.  But it does seem
02275                 // odd to me - we are iterating over the map object, not the reference.
02276 
02277 #if 0   // here is the test code with which I found the (still existing) bug
02278                 typedef cxx::Dict       d_t;
02279                 d_t     d;
02280                 cxx::String     s1("blah");
02281                 cxx::String     s2("gorf");
02282                 d[ "one" ] = s1;
02283                 d[ "two" ] = s1;
02284                 d[ "three" ] = s2;
02285                 d[ "four" ] = s2;
02286 
02287                 d_t::iterator   it;
02288                 it = d.begin();         // this (using the assignment operator) is causing
02289                 // a problem; if I just use the copy ctor it works fine.
02290                 for( ; it != d.end(); ++it )
02291                         {
02292                         d_t::value_type vt( *it );
02293                         cxx::String rs = vt.second.repr();
02294                         std::string ls = rs.operator std::string();
02295                         fprintf( stderr, "%s\n", ls );
02296                         }
02297 #endif // 0
02298 
02299                 class iterator
02300                         {
02301                         // : public forward_iterator_parent( std::pair<const T,T> ) {
02302                 protected:
02303                         typedef std::forward_iterator_tag iterator_category;
02304                         typedef std::pair< const T, T > value_type;
02305                         typedef int difference_type;
02306                         typedef std::pair< const T, mapref<T> > pointer;
02307                         typedef std::pair< const T, mapref<T> > reference;
02308 
02309                         friend class MapBase<T>;
02310                         //
02311                         MapBase<T>* map;
02312                         List    keys;                   // for iterating over the map
02313                         List::iterator  pos;            // index into the keys
02314 
02315                 public:
02316                         ~iterator ()
02317                                 {}
02318 
02319                         iterator ()
02320                                 : map( 0 )
02321                                 , keys()
02322                                 , pos()
02323                                 {}
02324 
02325                         iterator (MapBase<T>* m, bool end = false )
02326                                 : map( m )
02327                                 , keys( m->keys() )
02328                                 , pos( end ? keys.end() : keys.begin() )
02329                                 {}
02330 
02331                         iterator (const iterator& other)
02332                                 : map( other.map )
02333                                 , keys( other.keys )
02334                                 , pos( other.pos )
02335                                 {}
02336 
02337                         reference operator*()
02338                                 {
02339                                 Object key = *pos;
02340                                 return std::make_pair(key, mapref<T>(*map,key));
02341                                 }
02342 
02343                         iterator& operator=(const iterator& other)
02344                                 {
02345                                 if (this == &other)
02346                                         return *this;
02347                                 map = other.map;
02348                                 keys = other.keys;
02349                                 pos = other.pos;
02350                                 return *this;
02351                                 }
02352 
02353                         bool eql(const iterator& right) const
02354                                 {
02355                                 return *map == *right.map && pos == right.pos;
02356                                 }
02357                         bool neq( const iterator& right ) const
02358                                 {
02359                                 return *map != *right.map || pos != right.pos;
02360                                 }
02361 
02362                         // pointer operator->() {
02363                         //    return ;
02364                         // }
02365 
02366                         // prefix ++
02367                         iterator& operator++ ()
02368                                 { pos++; return *this;}
02369                         // postfix ++
02370                         iterator operator++ (int)
02371                                 { return iterator(map, keys, pos++);}
02372                         // prefix --
02373                         iterator& operator-- ()
02374                                 { pos--; return *this;}
02375                         // postfix --
02376                         iterator operator-- (int)
02377                                 { return iterator(map, keys, pos--);}
02378 
02379                         std::string diagnose() const
02380                                 {
02381                                 std::OSTRSTREAM oss;
02382                                 oss << "iterator diagnosis " << map << ", " << pos << std::ends;
02383                                 return std::string(oss.str());
02384                                 }
02385                         };    // end of class MapBase<T>::iterator
02386 
02387                 iterator begin ()
02388                         {
02389                         return iterator(this);
02390                         }
02391 
02392                 iterator end ()
02393                         {
02394                         return iterator(this, true);
02395                         }
02396 
02397                 class const_iterator
02398                         {
02399                 protected:
02400                         typedef std::forward_iterator_tag iterator_category;
02401                         typedef const std::pair< const T, T > value_type;
02402                         typedef int difference_type;
02403                         typedef const std::pair< const T, T > pointer;
02404                         typedef const std::pair< const T, T > reference;
02405 
02406                         friend class MapBase<T>;
02407                         const MapBase<T>* map;
02408                         List    keys;   // for iterating over the map
02409                         List::iterator  pos;            // index into the keys
02410 
02411                 public:
02412                         ~const_iterator ()
02413                                 {}
02414 
02415                         const_iterator ()
02416                                 : map( 0 )
02417                                 , keys()
02418                                 , pos()
02419                                 {}
02420 
02421                         const_iterator (const MapBase<T>* m, List k, List::iterator p )
02422                                 : map( m )
02423                                 , keys( k )
02424                                 , pos( p )
02425                                 {}
02426 
02427                         const_iterator(const const_iterator& other)
02428                                 : map( other.map )
02429                                 , keys( other.keys )
02430                                 , pos( other.pos )
02431                                 {}
02432 
02433                         bool eql(const const_iterator& right) const
02434                                 {
02435                                 return *map == *right.map && pos == right.pos;
02436                                 }
02437                         bool neq( const const_iterator& right ) const
02438                                 {
02439                                 return *map != *right.map || pos != right.pos;
02440                                 }
02441 
02442 
02443                         //                      const_reference operator*() {
02444                         //                              Object key = *pos;
02445                         //                              return std::make_pair( key, map->[key] );
02446                         // GCC < 3 barfes on this line at the '['.
02447                         //             }
02448 
02449                         const_iterator& operator=(const const_iterator& other)
02450                                 {
02451                                 if (this == &other) return *this;
02452                                 map = other.map;
02453                                 keys = other.keys;
02454                                 pos = other.pos;
02455                                 return *this;
02456                                 }
02457 
02458                         // prefix ++
02459                         const_iterator& operator++ ()
02460                                 { pos++; return *this;}
02461                         // postfix ++
02462                         const_iterator operator++ (int)
02463                                 { return const_iterator(map, keys, pos++);}
02464                         // prefix --
02465                         const_iterator& operator-- ()
02466                                 { pos--; return *this;}
02467                         // postfix --
02468                         const_iterator operator-- (int)
02469                                 { return const_iterator(map, keys, pos--);}
02470                         };    // end of class MapBase<T>::const_iterator
02471 
02472                 const_iterator begin () const
02473                         {
02474                         return const_iterator(this, 0);
02475                         }
02476 
02477                 const_iterator end () const
02478                         {
02479                         return const_iterator(this, length());
02480                         }
02481 
02482                 };      // end of MapBase<T>
02483 
02484         typedef MapBase<Object> Mapping;
02485 
02486         template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
02487         template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
02488         template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
02489         template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
02490 
02491         extern bool operator==(const Mapping::iterator& left, const Mapping::iterator& right);
02492         extern bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right);
02493         extern bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
02494         extern bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
02495 
02496 
02497         // ==================================================
02498         // class Dict
02499         class Dict: public Mapping
02500                 {
02501         public:
02502                 // Constructor
02503                 explicit Dict (PyObject *pyob, bool owned=false): Mapping (pyob, owned)
02504                         {
02505                         validate();
02506                         }
02507                 Dict (const Dict& ob): Mapping(ob)
02508                         {
02509                         validate();
02510                         }
02511                 // Creation
02512                 Dict ()
02513                         {
02514                         set(PyDict_New (), true);
02515                         validate();
02516                         }
02517                 // Assignment acquires new ownership of pointer
02518 
02519                 Dict& operator= (const Object& rhs)
02520                         {
02521                         return (*this = *rhs);
02522                         }
02523 
02524                 Dict& operator= (PyObject* rhsp)
02525                         {
02526                         if(ptr() == rhsp) return *this;
02527                         set(rhsp);
02528                         return *this;
02529                         }
02530                 // Membership
02531                 virtual bool accepts (PyObject *pyob) const
02532                         {
02533                         return pyob && Py::_Dict_Check (pyob);
02534                         }
02535                 };
02536 
02537         class Callable: public Object
02538                 {
02539         public:
02540                 // Constructor
02541                 explicit Callable (): Object()  {}
02542                 explicit Callable (PyObject *pyob, bool owned = false): Object (pyob, owned)
02543                         {
02544                         validate();
02545                         }
02546 
02547                 Callable (const Object& ob): Object(ob)
02548                         {
02549                         validate();
02550                         }
02551 
02552                 // Assignment acquires new ownership of pointer
02553 
02554                 Callable& operator= (const Object& rhs)
02555                         {
02556                         return (*this = *rhs);
02557                         }
02558 
02559                 Callable& operator= (PyObject* rhsp)
02560                         {
02561                         if(ptr() == rhsp) return *this;
02562                         set (rhsp);
02563                         return *this;
02564                         }
02565 
02566                 // Membership
02567                 virtual bool accepts (PyObject *pyob) const
02568                         {
02569                         return pyob && PyCallable_Check (pyob);
02570                         }
02571 
02572                 // Call
02573                 Object apply(const Tuple& args) const
02574                         {
02575                         return asObject(PyObject_CallObject(ptr(), args.ptr()));
02576                         }
02577 
02578                 // Call with keywords
02579                 Object apply(const Tuple& args, const Dict& kw) const
02580                         {
02581                         return asObject( PyEval_CallObjectWithKeywords( ptr(), args.ptr(), kw.ptr() ) );
02582                         }
02583 
02584                 Object apply(PyObject* pargs = 0) const
02585                         {
02586                         return apply (Tuple(pargs));
02587                         }
02588                 };
02589 
02590         class Module: public Object
02591                 {
02592         public:
02593                 explicit Module (PyObject* pyob, bool owned = false): Object (pyob, owned)
02594                         {
02595                         validate();
02596                         }
02597 
02598                 // Construct from module name
02599                 explicit Module (const std::string&s): Object()
02600                         {
02601                         PyObject *m = PyImport_AddModule( const_cast<char *>(s.c_str()) );
02602                         set( m, false );
02603                         validate ();
02604                         }
02605 
02606                 // Copy constructor acquires new ownership of pointer
02607                 Module (const Module& ob): Object(*ob)
02608                         {
02609                         validate();
02610                         }
02611 
02612                 Module& operator= (const Object& rhs)
02613                         {
02614                         return (*this = *rhs);
02615                         }
02616 
02617                 Module& operator= (PyObject* rhsp)
02618                         {
02619                         if(ptr() == rhsp) return *this;
02620                         set(rhsp);
02621                         return *this;
02622                         }
02623 
02624                 Dict getDict()
02625                         {
02626                         return Dict(PyModule_GetDict(ptr()));
02627                         // Caution -- PyModule_GetDict returns borrowed reference!
02628                         }
02629                 };
02630 
02631         // Numeric interface
02632         inline Object operator+ (const Object& a)
02633                 {
02634                 return asObject(PyNumber_Positive(*a));
02635                 }
02636         inline Object operator- (const Object& a)
02637                 {
02638                 return asObject(PyNumber_Negative(*a));
02639                 }
02640 
02641         inline Object abs(const Object& a)
02642                 {
02643                 return asObject(PyNumber_Absolute(*a));
02644                 }
02645 
02646         inline std::pair<Object,Object> coerce(const Object& a, const Object& b)
02647                 {
02648                 PyObject *p1, *p2;
02649                 p1 = *a;
02650                 p2 = *b;
02651                 if(PyNumber_Coerce(&p1,&p2) == -1)
02652                         {
02653                         throw Exception();
02654                         }
02655                 return std::pair<Object,Object>(asObject(p1), asObject(p2));
02656                 }
02657 
02658         inline Object operator+ (const Object& a, const Object& b)
02659                 {
02660                 return asObject(PyNumber_Add(*a, *b));
02661                 }
02662         inline Object operator+ (const Object& a, int j)
02663                 {
02664                 return asObject(PyNumber_Add(*a, *Int(j)));
02665                 }
02666         inline Object operator+ (const Object& a, double v)
02667                 {
02668                 return asObject(PyNumber_Add(*a, *Float(v)));
02669                 }
02670         inline Object operator+ (int j, const Object& b)
02671                 {
02672                 return asObject(PyNumber_Add(*Int(j), *b));
02673                 }
02674         inline Object operator+ (double v, const Object& b)
02675                 {
02676                 return asObject(PyNumber_Add(*Float(v), *b));
02677                 }
02678 
02679         inline Object operator- (const Object& a, const Object& b)
02680                 {
02681                 return asObject(PyNumber_Subtract(*a, *b));
02682                 }
02683         inline Object operator- (const Object& a, int j)
02684                 {
02685                 return asObject(PyNumber_Subtract(*a, *Int(j)));
02686                 }
02687         inline Object operator- (const Object& a, double v)
02688                 {
02689                 return asObject(PyNumber_Subtract(*a, *Float(v)));
02690                 }
02691         inline Object operator- (int j, const Object& b)
02692                 {
02693                 return asObject(PyNumber_Subtract(*Int(j), *b));
02694                 }
02695         inline Object operator- (double v, const Object& b)
02696                 {
02697                 return asObject(PyNumber_Subtract(*Float(v), *b));
02698                 }
02699 
02700         inline Object operator* (const Object& a, const Object& b)
02701                 {
02702                 return asObject(PyNumber_Multiply(*a, *b));
02703                 }
02704         inline Object operator* (const Object& a, int j)
02705                 {
02706                 return asObject(PyNumber_Multiply(*a, *Int(j)));
02707                 }
02708         inline Object operator* (const Object& a, double v)
02709                 {
02710                 return asObject(PyNumber_Multiply(*a, *Float(v)));
02711                 }
02712         inline Object operator* (int j, const Object& b)
02713                 {
02714                 return asObject(PyNumber_Multiply(*Int(j), *b));
02715                 }
02716         inline Object operator* (double v, const Object& b)
02717                 {
02718                 return asObject(PyNumber_Multiply(*Float(v), *b));
02719                 }
02720 
02721         inline Object operator/ (const Object& a, const Object& b)
02722                 {
02723                 return asObject(PyNumber_Divide(*a, *b));
02724                 }
02725         inline Object operator/ (const Object& a, int j)
02726                 {
02727                 return asObject(PyNumber_Divide(*a, *Int(j)));
02728                 }
02729         inline Object operator/ (const Object& a, double v)
02730                 {
02731                 return asObject(PyNumber_Divide(*a, *Float(v)));
02732                 }
02733         inline Object operator/ (int j, const Object& b)
02734                 {
02735                 return asObject(PyNumber_Divide(*Int(j), *b));
02736                 }
02737         inline Object operator/ (double v, const Object& b)
02738                 {
02739                 return asObject(PyNumber_Divide(*Float(v), *b));
02740                 }
02741 
02742         inline Object operator% (const Object& a, const Object& b)
02743                 {
02744                 return asObject(PyNumber_Remainder(*a, *b));
02745                 }
02746         inline Object operator% (const Object& a, int j)
02747                 {
02748                 return asObject(PyNumber_Remainder(*a, *Int(j)));
02749                 }
02750         inline Object operator% (const Object& a, double v)
02751                 {
02752                 return asObject(PyNumber_Remainder(*a, *Float(v)));
02753                 }
02754         inline Object operator% (int j, const Object& b)
02755                 {
02756                 return asObject(PyNumber_Remainder(*Int(j), *b));
02757                 }
02758         inline Object operator% (double v, const Object& b)
02759                 {
02760                 return asObject(PyNumber_Remainder(*Float(v), *b));
02761                 }
02762 
02763         inline Object type(const Exception&) // return the type of the error
02764                 {
02765                 PyObject *ptype, *pvalue, *ptrace;
02766                 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02767                 Object result(ptype);
02768                 PyErr_Restore(ptype, pvalue, ptrace);
02769                 return result;
02770                 }
02771 
02772         inline Object value(const Exception&) // return the value of the error
02773                 {
02774                 PyObject *ptype, *pvalue, *ptrace;
02775                 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02776                 Object result;
02777                 if(pvalue) result = pvalue;
02778                 PyErr_Restore(ptype, pvalue, ptrace);
02779                 return result;
02780                 }
02781 
02782         inline Object trace(const Exception&) // return the traceback of the error
02783                 {
02784                 PyObject *ptype, *pvalue, *ptrace;
02785                 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02786                 Object result;
02787                 if(ptrace) result = ptrace;
02788                 PyErr_Restore(ptype, pvalue, ptrace);
02789                 return result;
02790                 }
02791 
02792 
02793 
02794 template<TEMPLATE_TYPENAME T>
02795 String seqref<T>::str () const
02796                         {
02797                         return the_item.str();
02798                         }
02799 
02800 template<TEMPLATE_TYPENAME T>
02801 String seqref<T>::repr () const
02802                         {
02803                         return the_item.repr();
02804                         }
02805 
02806 
02807         } // namespace Py
02808 #endif  // __CXX_Objects__h

Généré le Wed Nov 22 23:41:12 2006 pour KPlato par  doxygen 1.5.1-p1