diff options
Diffstat (limited to 'lib/kross/python/cxx/Objects.hxx')
-rw-r--r-- | lib/kross/python/cxx/Objects.hxx | 2804 |
1 files changed, 0 insertions, 2804 deletions
diff --git a/lib/kross/python/cxx/Objects.hxx b/lib/kross/python/cxx/Objects.hxx deleted file mode 100644 index 97e52fc0e..000000000 --- a/lib/kross/python/cxx/Objects.hxx +++ /dev/null @@ -1,2804 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright 1998 The Regents of the University of California. -// All rights reserved. See LEGAL.LLNL for full text and disclaimer. -//---------------------------------------------------------------------------// - -#ifndef __CXX_Objects__h -#define __CXX_Objects__h - -// Prevent warnings -#if defined(_XOPEN_SOURCE) -#undef _XOPEN_SOURCE -#endif - -#include "Python.h" -#include "Config.hxx" -#include "Exception.hxx" - - -#include <iostream> -#include <sstream> -#include <string> -#include <iterator> -#include <utility> -#include <typeinfo> - -namespace Py - { - typedef int sequence_index_type; // type of an index into a sequence - - // Forward declarations - class Object; - class Type; - template<typename T> class SeqBase; - class String; - class List; - template<typename T> class MapBase; - - // new_reference_to also overloaded below on Object - inline PyObject* new_reference_to(PyObject* p) - { - Py::_XINCREF(p); - return p; - } - - // returning Null() from an extension method triggers a - // Python exception - inline PyObject* Null() - { - return (static_cast<PyObject*>(0)); - } - - //===========================================================================// - // class Object - // The purpose of this class is to serve as the most general kind of - // Python object, for the purpose of writing C++ extensions in Python - // Objects hold a PyObject* which they own. This pointer is always a - // valid pointer to a Python object. In children we must maintain this behavior. - // - // Instructions on how to make your own class MyType descended from Object: - // (0) Pick a base class, either Object or perhaps SeqBase<T> or MapBase<T>. - // This example assumes Object. - - // (1) Write a routine int MyType_Check (PyObject *) modeled after PyInt_Check, - // PyFloat_Check, etc. - - // (2) Add method accepts: - // virtual bool accepts (PyObject *pyob) const { - // return pyob && MyType_Check (pyob); - // } - - // (3) Include the following constructor and copy constructor - // - /* - explicit MyType (PyObject *pyob): Object(pyob) { - validate(); - } - - MyType(const Object& other): Object(other.ptr()) { - validate(); - } - */ - - // Alernate version for the constructor to allow for construction from owned pointers: - /* - explicit MyType (PyObject *pyob): Object(pyob) { - validate(); - } - */ - - // You may wish to add other constructors; see the classes below for examples. - // Each constructor must use "set" to set the pointer - // and end by validating the pointer you have created. - - // (4) Each class needs at least these two assignment operators: - /* - MyType& operator= (const Object& rhs) { - return (*this = *rhs); - } - - Mytype& operator= (PyObject* rhsp) { - if(ptr() == rhsp) return *this; - set(rhsp); - return *this; - } - */ - // Note on accepts: constructors call the base class - // version of a virtual when calling the base class constructor, - // so the test has to be done explicitly in a descendent. - - // If you are inheriting from PythonExtension<T> to define an object - // note that it contains PythonExtension<T>::check - // which you can use in accepts when writing a wrapper class. - // See Demo/range.h and Demo/range.cxx for an example. - - class Object - { - private: - // the pointer to the Python object - // Only Object sets this directly. - // The default constructor for Object sets it to Py_None and - // child classes must use "set" to set it - // - PyObject* p; - - protected: - - void set (PyObject* pyob, bool owned = false) - { - release(); - p = pyob; - if (!owned) - { - Py::_XINCREF (p); - } - validate(); - } - - void release () - { - Py::_XDECREF (p); - p = 0; - } - - void validate() - { - // release pointer if not the right type - if (! accepts (p)) - { - release (); - if(PyErr_Occurred()) - { // Error message already set - throw Exception(); - } - // Better error message if RTTI available -#if defined( _CPPRTTI ) - std::string s("Error creating object of type "); - s += (typeid (*this)).name(); - throw TypeError (s); -#else - throw TypeError ("CXX: type error."); -#endif - } - } - - public: - // Constructor acquires new ownership of pointer unless explicitly told not to. - explicit Object (PyObject* pyob=Py::_None(), bool owned = false): p (pyob) - { - if(!owned) - { - Py::_XINCREF (p); - } - validate(); - } - - // Copy constructor acquires new ownership of pointer - Object (const Object& ob): p(ob.p) - { - Py::_XINCREF (p); - validate(); - } - - // Assignment acquires new ownership of pointer - Object& operator= (const Object& rhs) - { - set(rhs.p); - return *this; - } - - Object& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - - // Destructor - virtual ~Object () - { - release (); - } - - // Loaning the pointer to others, retain ownership - PyObject* operator* () const - { - return p; - } - - // Explicit reference_counting changes - void increment_reference_count() - { - Py::_XINCREF(p); - } - - void decrement_reference_count() - { - // not allowed to commit suicide, however - if(reference_count() == 1) - throw RuntimeError("Object::decrement_reference_count error."); - Py::_XDECREF(p); - } - // Would like to call this pointer() but messes up STL in SeqBase<T> - PyObject* ptr () const - { - return p; - } - - // - // Queries - // - - // Can pyob be used in this object's constructor? - virtual bool accepts (PyObject *pyob) const - { - return (pyob != 0); - } - - int reference_count () const - { // the reference count - return p ? p->ob_refcnt : 0; - } - - Type type () const; // the type object associated with this one - - String str () const; // the str() representation - - std::string as_string() const; - - String repr () const; // the repr () representation - - List dir () const; // the dir() list - - bool hasAttr (const std::string& s) const - { - return PyObject_HasAttrString (p, const_cast<char*>(s.c_str())) ? true: false; - } - - Object getAttr (const std::string& s) const - { - return Object (PyObject_GetAttrString (p, const_cast<char*>(s.c_str())), true); - } - - Object getItem (const Object& key) const - { - return Object (PyObject_GetItem(p, *key), true); - } - - long hashValue () const - { - return PyObject_Hash (p); - } - - // - // int print (FILE* fp, int flags=Py_Print_RAW) - // { - // return PyObject_Print (p, fp, flags); - // } - // - bool is(PyObject *pother) const - { // identity test - return p == pother; - } - - bool is(const Object& other) const - { // identity test - return p == other.p; - } - - bool isCallable () const - { - return PyCallable_Check (p) != 0; - } - - bool isInstance () const - { - return PyInstance_Check (p) != 0; - } - - bool isDict () const - { - return Py::_Dict_Check (p); - } - - bool isList () const - { - return Py::_List_Check (p); - } - - bool isMapping () const - { - return PyMapping_Check (p) != 0; - } - - bool isNumeric () const - { - return PyNumber_Check (p) != 0; - } - - bool isSequence () const - { - return PySequence_Check (p) != 0; - } - - bool isTrue () const - { - return PyObject_IsTrue (p) != 0; - } - - bool isType (const Type& t) const; - - bool isTuple() const - { - return Py::_Tuple_Check(p); - } - - bool isString() const - { - return Py::_String_Check(p) || Py::_Unicode_Check(p); - } - - bool isUnicode() const - { - return Py::_Unicode_Check(p); - } - - // Commands - void setAttr (const std::string& s, const Object& value) - { - if(PyObject_SetAttrString (p, const_cast<char*>(s.c_str()), *value) == -1) - throw AttributeError ("getAttr failed."); - } - - void delAttr (const std::string& s) - { - if(PyObject_DelAttrString (p, const_cast<char*>(s.c_str())) == -1) - throw AttributeError ("delAttr failed."); - } - - // PyObject_SetItem is too weird to be using from C++ - // so it is intentionally omitted. - - void delItem (const Object& /*key*/) - { - //if(PyObject_DelItem(p, *key) == -1) - // failed to link on Windows? - throw KeyError("delItem failed."); - } - // Equality and comparison use PyObject_Compare - - bool operator==(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k == 0; - } - - bool operator!=(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k != 0; - - } - - bool operator>=(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k >= 0; - } - - bool operator<=(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k <= 0; - } - - bool operator<(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k < 0; - } - - bool operator>(const Object& o2) const - { - int k = PyObject_Compare (p, *o2); - if (PyErr_Occurred()) throw Exception(); - return k > 0; - } - }; - // End of class Object - inline PyObject* new_reference_to(const Object& g) - { - PyObject* p = g.ptr(); - Py::_XINCREF(p); - return p; - } - - // Nothing() is what an extension method returns if - // there is no other return value. - inline Object Nothing() - { - return Object(Py::_None()); - } - - // Python special None value - inline Object None() - { - return Object(Py::_None()); - } - - // TMM: 31May'01 - Added the #ifndef so I can exlude iostreams. -#ifndef CXX_NO_IOSTREAMS - std::ostream& operator<< (std::ostream& os, const Object& ob); -#endif - - // Class Type - class Type: public Object - { - public: - explicit Type (PyObject* pyob, bool owned = false): Object(pyob, owned) - { - validate(); - } - - Type (const Object& ob): Object(*ob) - { - validate(); - } - - Type(const Type& t): Object(t) - { - validate(); - } - - Type& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Type& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Type_Check (pyob); - } - }; - - - // - // Convert an owned Python pointer into a CXX Object - // - inline Object asObject (PyObject *p) - { - return Object(p, true); - } - - - - - // =============================================== - // class Int - class Int: public Object - { - public: - // Constructor - explicit Int (PyObject *pyob, bool owned = false): Object (pyob, owned) - { - validate(); - } - - Int (const Int& ob): Object(*ob) - { - validate(); - } - - // create from long - explicit Int (long v = 0L): Object(PyInt_FromLong(v), true) - { - validate(); - } - - // create from int - explicit Int (int v) - { - long w = v; - set(PyInt_FromLong(w), true); - validate(); - } - - Int (const Object& ob) - { - set(PyNumber_Int(*ob), true); - validate(); - } - - // Assignment acquires new ownership of pointer - - Int& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Int& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (PyNumber_Int(rhsp), true); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Int_Check (pyob); - } - // convert to long - operator long() const - { - return PyInt_AsLong (ptr()); - } - // assign from an int - Int& operator= (int v) - { - set (PyInt_FromLong (long(v)), true); - return *this; - } - // assign from long - Int& operator= (long v) - { - set (PyInt_FromLong (v), true); - return *this; - } - }; - - // =============================================== - // class Long - class Long: public Object - { - public: - // Constructor - explicit Long (PyObject *pyob, bool owned = false): Object (pyob, owned) - { - validate(); - } - - Long (const Long& ob): Object(ob.ptr()) - { - validate(); - } - - // create from long - explicit Long (long v = 0L) - : Object(PyLong_FromLong(v), true) - { - validate(); - } - // create from int - explicit Long (int v) - : Object(PyLong_FromLong(static_cast<long>(v)), true) - { - validate(); - } - - // create from unsigned long - explicit Long (unsigned long v) - : Object(PyLong_FromUnsignedLong(v), true) - { - validate(); - } - - // try to create from any object - Long (const Object& ob) - : Object(PyNumber_Long(*ob), true) - { - validate(); - } - - // Assignment acquires new ownership of pointer - - Long& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Long& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (PyNumber_Long(rhsp), true); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Long_Check (pyob); - } - // convert to long - operator long() const - { - return PyLong_AsLong (ptr()); - } - operator double() const - { - return PyLong_AsDouble (ptr()); - } - operator unsigned long() const - { - return PyLong_AsUnsignedLong (ptr()); - } - // assign from an int - Long& operator= (int v) - { - set(PyLong_FromLong (long(v)), true); - return *this; - } - // assign from long - Long& operator= (long v) - { - set(PyLong_FromLong (v), true); - return *this; - } - // assign from unsigned long - Long& operator= (unsigned long v) - { - set(PyLong_FromUnsignedLong (v), true); - return *this; - } - }; - - // =============================================== - // class Float - // - class Float: public Object - { - public: - // Constructor - explicit Float (PyObject *pyob, bool owned = false): Object(pyob, owned) - { - validate(); - } - - Float (const Float& f): Object(f) - { - validate(); - } - - // make from double - explicit Float (double v=0.0) - : Object(PyFloat_FromDouble (v), true) - { - validate(); - } - - // try to make from any object - Float (const Object& ob) - : Object(PyNumber_Float(*ob), true) - { - validate(); - } - - Float& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Float& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (PyNumber_Float(rhsp), true); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Float_Check (pyob); - } - // convert to double - operator double () const - { - return PyFloat_AsDouble (ptr()); - } - // assign from a double - Float& operator= (double v) - { - set(PyFloat_FromDouble (v), true); - return *this; - } - // assign from an int - Float& operator= (int v) - { - set(PyFloat_FromDouble (double(v)), true); - return *this; - } - // assign from long - Float& operator= (long v) - { - set(PyFloat_FromDouble (double(v)), true); - return *this; - } - // assign from an Int - Float& operator= (const Int& iob) - { - set(PyFloat_FromDouble (double(long(iob))), true); - return *this; - } - }; - - // =============================================== - // class Complex - class Complex: public Object - { - public: - // Constructor - explicit Complex (PyObject *pyob, bool owned = false): Object(pyob, owned) - { - validate(); - } - - Complex (const Complex& f): Object(f) - { - validate(); - } - - // make from double - explicit Complex (double v=0.0, double w=0.0) - :Object(PyComplex_FromDoubles (v, w), true) - { - validate(); - } - - Complex& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Complex& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Complex_Check (pyob); - } - // convert to Py_complex - operator Py_complex () const - { - return PyComplex_AsCComplex (ptr()); - } - // assign from a Py_complex - Complex& operator= (const Py_complex& v) - { - set(PyComplex_FromCComplex (v), true); - return *this; - } - // assign from a double - Complex& operator= (double v) - { - set(PyComplex_FromDoubles (v, 0.0), true); - return *this; - } - // assign from an int - Complex& operator= (int v) - { - set(PyComplex_FromDoubles (double(v), 0.0), true); - return *this; - } - // assign from long - Complex& operator= (long v) - { - set(PyComplex_FromDoubles (double(v), 0.0), true); - return *this; - } - // assign from an Int - Complex& operator= (const Int& iob) - { - set(PyComplex_FromDoubles (double(long(iob)), 0.0), true); - return *this; - } - - double real() const - { - return PyComplex_RealAsDouble(ptr()); - } - - double imag() const - { - return PyComplex_ImagAsDouble(ptr()); - } - }; - // Sequences - // Sequences are here represented as sequences of items of type T. - // The base class SeqBase<T> represents that. - // In basic Python T is always "Object". - - // seqref<T> is what you get if you get elements from a non-const SeqBase<T>. - // Note: seqref<T> could probably be a nested class in SeqBase<T> but that might stress - // some compilers needlessly. Simlarly for mapref later. - - // While this class is not intended for enduser use, it needs some public - // constructors for the benefit of the STL. - - // See Scott Meyer's More Essential C++ for a description of proxies. - // This application is even more complicated. We are doing an unusual thing - // in having a double proxy. If we want the STL to work - // properly we have to compromise by storing the rvalue inside. The - // entire Object API is repeated so that things like s[i].isList() will - // work properly. - - // Still, once in a while a weird compiler message may occur using expressions like x[i] - // Changing them to Object(x[i]) helps the compiler to understand that the - // conversion of a seqref to an Object is wanted. - - template<typename T> - class seqref - { - protected: - SeqBase<T>& s; // the sequence - int offset; // item number - T the_item; // lvalue - public: - - seqref (SeqBase<T>& seq, sequence_index_type j) - : s(seq), offset(j), the_item (s.getItem(j)) - {} - - seqref (const seqref<T>& range) - : s(range.s), offset(range.offset), the_item(range.the_item) - {} - - // TMM: added this seqref ctor for use with STL algorithms - seqref (Object& obj) - : s(dynamic_cast< SeqBase<T>&>(obj)) - , offset( NULL ) - , the_item(s.getItem(offset)) - {} - ~seqref() - {} - - operator T() const - { // rvalue - return the_item; - } - - seqref<T>& operator=(const seqref<T>& rhs) - { //used as lvalue - the_item = rhs.the_item; - s.setItem(offset, the_item); - return *this; - } - - seqref<T>& operator=(const T& ob) - { // used as lvalue - the_item = ob; - s.setItem(offset, ob); - return *this; - } - - // forward everything else to the item - PyObject* ptr () const - { - return the_item.ptr(); - } - - int reference_count () const - { // the reference count - return the_item.reference_count(); - } - - Type type () const - { - return the_item.type(); - } - - String str () const; - - String repr () const; - - bool hasAttr (const std::string& attr_name) const - { - return the_item.hasAttr(attr_name); - } - - Object getAttr (const std::string& attr_name) const - { - return the_item.getAttr(attr_name); - } - - Object getItem (const Object& key) const - { - return the_item.getItem(key); - } - - long hashValue () const - { - return the_item.hashValue(); - } - - bool isCallable () const - { - return the_item.isCallable(); - } - - bool isInstance () const - { - return the_item.isInstance(); - } - - bool isDict () const - { - return the_item.isDict(); - } - - bool isList () const - { - return the_item.isList(); - } - - bool isMapping () const - { - return the_item.isMapping(); - } - - bool isNumeric () const - { - return the_item.isNumeric(); - } - - bool isSequence () const - { - return the_item.isSequence(); - } - - bool isTrue () const - { - return the_item.isTrue(); - } - - bool isType (const Type& t) const - { - return the_item.isType (t); - } - - bool isTuple() const - { - return the_item.isTuple(); - } - - bool isString() const - { - return the_item.isString(); - } - // Commands - void setAttr (const std::string& attr_name, const Object& value) - { - the_item.setAttr(attr_name, value); - } - - void delAttr (const std::string& attr_name) - { - the_item.delAttr(attr_name); - } - - void delItem (const Object& key) - { - the_item.delItem(key); - } - - bool operator==(const Object& o2) const - { - return the_item == o2; - } - - bool operator!=(const Object& o2) const - { - return the_item != o2; - } - - bool operator>=(const Object& o2) const - { - return the_item >= o2; - } - - bool operator<=(const Object& o2) const - { - return the_item <= o2; - } - - bool operator<(const Object& o2) const - { - return the_item < o2; - } - - bool operator>(const Object& o2) const - { - return the_item > o2; - } - }; // end of seqref - - - // class SeqBase<T> - // ...the base class for all sequence types - - template<typename T> - class SeqBase: public Object - { - public: - // STL definitions - typedef size_t size_type; - typedef seqref<T> reference; - typedef T const_reference; - typedef seqref<T>* pointer; - typedef int difference_type; - typedef T value_type; // TMM: 26Jun'01 - - virtual size_type max_size() const - { - return std::string::npos; // ? - } - - virtual size_type capacity() const - { - return size(); - } - - virtual void swap(SeqBase<T>& c) - { - SeqBase<T> temp = c; - c = ptr(); - set(temp.ptr()); - } - - virtual size_type size () const - { - return PySequence_Length (ptr()); - } - - explicit SeqBase<T> () - :Object(PyTuple_New(0), true) - { - validate(); - } - - explicit SeqBase<T> (PyObject* pyob, bool owned=false) - : Object(pyob, owned) - { - validate(); - } - - SeqBase<T> (const Object& ob): Object(ob) - { - validate(); - } - - // Assignment acquires new ownership of pointer - - SeqBase<T>& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - SeqBase<T>& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - - virtual bool accepts (PyObject *pyob) const - { - return pyob && PySequence_Check (pyob); - } - - size_type length () const - { - return PySequence_Length (ptr()); - } - - // Element access - const T operator[](sequence_index_type index) const - { - return getItem(index); - } - - seqref<T> operator[](sequence_index_type index) - { - return seqref<T>(*this, index); - } - - virtual T getItem (sequence_index_type i) const - { - return T(asObject(PySequence_GetItem (ptr(), i))); - } - - virtual void setItem (sequence_index_type i, const T& ob) - { - if (PySequence_SetItem (ptr(), i, *ob) == -1) - { - throw Exception(); - } - } - - SeqBase<T> repeat (int count) const - { - return SeqBase<T> (PySequence_Repeat (ptr(), count), true); - } - - SeqBase<T> concat (const SeqBase<T>& other) const - { - return SeqBase<T> (PySequence_Concat(ptr(), *other), true); - } - - // more STL compatability - const T front () const - { - return getItem(0); - } - - seqref<T> front() - { - return seqref<T>(this, 0); - } - - const T back () const - { - return getItem(size()-1); - } - - seqref<T> back() - { - return seqref<T>(this, size()-1); - } - - void verify_length(size_type required_size) const - { - if (size() != required_size) - throw IndexError ("Unexpected SeqBase<T> length."); - } - - void verify_length(size_type min_size, size_type max_size) const - { - size_type n = size(); - if (n < min_size || n > max_size) - throw IndexError ("Unexpected SeqBase<T> length."); - } - - class iterator - : public random_access_iterator_parent(seqref<T>) - { - protected: - friend class SeqBase<T>; - SeqBase<T>* seq; - int count; - - public: - ~iterator () - {} - - iterator () - : seq( 0 ) - , count( 0 ) - {} - - iterator (SeqBase<T>* s, int where) - : seq( s ) - , count( where ) - {} - - iterator (const iterator& other) - : seq( other.seq ) - , count( other.count ) - {} - - bool eql (const iterator& other) const - { - return (*seq == *other.seq) && (count == other.count); - } - - bool neq (const iterator& other) const - { - return (*seq != *other.seq) || (count != other.count); - } - - bool lss (const iterator& other) const - { - return (count < other.count); - } - - bool gtr (const iterator& other) const - { - return (count > other.count); - } - - bool leq (const iterator& other) const - { - return (count <= other.count); - } - - bool geq (const iterator& other) const - { - return (count >= other.count); - } - - seqref<T> operator*() - { - return seqref<T>(*seq, count); - } - - seqref<T> operator[] (sequence_index_type i) - { - return seqref<T>(*seq, count + i); - } - - iterator& operator=(const iterator& other) - { - if (this == &other) return *this; - seq = other.seq; - count = other.count; - return *this; - } - - iterator operator+(int n) const - { - return iterator(seq, count + n); - } - - iterator operator-(int n) const - { - return iterator(seq, count - n); - } - - iterator& operator+=(int n) - { - count = count + n; - return *this; - } - - iterator& operator-=(int n) - { - count = count - n; - return *this; - } - - int operator-(const iterator& other) const - { - if (*seq != *other.seq) - throw RuntimeError ("SeqBase<T>::iterator comparison error"); - return count - other.count; - } - - // prefix ++ - iterator& operator++ () - { count++; return *this;} - // postfix ++ - iterator operator++ (int) - { return iterator(seq, count++);} - // prefix -- - iterator& operator-- () - { count--; return *this;} - // postfix -- - iterator operator-- (int) - { return iterator(seq, count--);} - - std::string diagnose() const - { - std::ostringstream oss; - oss << "iterator diagnosis " << seq << ", " << count << std::ends; - return std::string(oss.str()); - } - }; // end of class SeqBase<T>::iterator - - iterator begin () - { - return iterator(this, 0); - } - - iterator end () - { - return iterator(this, length()); - } - - class const_iterator - : public random_access_iterator_parent(const Object) - { - protected: - friend class SeqBase<T>; - const SeqBase<T>* seq; - sequence_index_type count; - - public: - ~const_iterator () - {} - - const_iterator () - : seq( 0 ) - , count( 0 ) - {} - - const_iterator (const SeqBase<T>* s, int where) - : seq( s ) - , count( where ) - {} - - const_iterator(const const_iterator& other) - : seq( other.seq ) - , count( other.count ) - {} - - const T operator*() const - { - return seq->getItem(count); - } - - const T operator[] (sequence_index_type i) const - { - return seq->getItem(count + i); - } - - const_iterator& operator=(const const_iterator& other) - { - if (this == &other) return *this; - seq = other.seq; - count = other.count; - return *this; - } - - const_iterator operator+(int n) const - { - return const_iterator(seq, count + n); - } - - bool eql (const const_iterator& other) const - { - return (*seq == *other.seq) && (count == other.count); - } - - bool neq (const const_iterator& other) const - { - return (*seq != *other.seq) || (count != other.count); - } - - bool lss (const const_iterator& other) const - { - return (count < other.count); - } - - bool gtr (const const_iterator& other) const - { - return (count > other.count); - } - - bool leq (const const_iterator& other) const - { - return (count <= other.count); - } - - bool geq (const const_iterator& other) const - { - return (count >= other.count); - } - - const_iterator operator-(int n) - { - return const_iterator(seq, count - n); - } - - const_iterator& operator+=(int n) - { - count = count + n; - return *this; - } - - const_iterator& operator-=(int n) - { - count = count - n; - return *this; - } - - int operator-(const const_iterator& other) const - { - if (*seq != *other.seq) - throw RuntimeError ("SeqBase<T>::const_iterator::- error"); - return count - other.count; - } - // prefix ++ - const_iterator& operator++ () - { count++; return *this;} - // postfix ++ - const_iterator operator++ (int) - { return const_iterator(seq, count++);} - // prefix -- - const_iterator& operator-- () - { count--; return *this;} - // postfix -- - const_iterator operator-- (int) - { return const_iterator(seq, count--);} - }; // end of class SeqBase<T>::const_iterator - - const_iterator begin () const - { - return const_iterator(this, 0); - } - - const_iterator end () const - { - return const_iterator(this, length()); - } - }; - - // Here's an important typedef you might miss if reading too fast... - typedef SeqBase<Object> Sequence; - - template <typename T> bool operator==(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - template <typename T> bool operator!=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - template <typename T> bool operator< (const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - template <typename T> bool operator> (const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - template <typename T> bool operator<=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - template <typename T> bool operator>=(const typename SeqBase<T>::iterator& left, const typename SeqBase<T>::iterator& right); - - template <typename T> bool operator==(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - template <typename T> bool operator!=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - template <typename T> bool operator< (const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - template <typename T> bool operator> (const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - template <typename T> bool operator<=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - template <typename T> bool operator>=(const typename SeqBase<T>::const_iterator& left, const typename SeqBase<T>::const_iterator& right); - - - extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right); - extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right); - extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right); - extern bool operator> (const Sequence::iterator& left, const Sequence::iterator& right); - extern bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right); - extern bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right); - - extern bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right); - extern bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right); - extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right); - extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right); - extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right); - extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right); - - // ================================================== - // class Char - // Python strings return strings as individual elements. - // I'll try having a class Char which is a String of length 1 - // - typedef std::basic_string<Py_UNICODE> unicodestring; - extern Py_UNICODE unicode_null_string[1]; - - class Char: public Object - { - public: - explicit Char (PyObject *pyob, bool owned = false): Object(pyob, owned) - { - validate(); - } - - Char (const Object& ob): Object(ob) - { - validate(); - } - - Char (const std::string& v = "") - :Object(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true) - { - validate(); - } - - Char (char v) - : Object(PyString_FromStringAndSize (&v, 1), true) - { - validate(); - } - - Char (Py_UNICODE v) - : Object(PyUnicode_FromUnicode (&v, 1), true) - { - validate(); - } - // Assignment acquires new ownership of pointer - Char& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Char& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob)) && PySequence_Length (pyob) == 1; - } - - // Assignment from C string - Char& operator= (const std::string& v) - { - set(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true); - return *this; - } - - Char& operator= (char v) - { - set(PyString_FromStringAndSize (&v, 1), true); - return *this; - } - - Char& operator= (const unicodestring& v) - { - set(PyUnicode_FromUnicode (const_cast<Py_UNICODE*>(v.data()),1), true); - return *this; - } - - Char& operator= (Py_UNICODE v) - { - set(PyUnicode_FromUnicode (&v, 1), true); - return *this; - } - - // Conversion - operator String() const; - - operator std::string () const - { - return std::string(PyString_AsString (ptr())); - } - }; - - class String: public SeqBase<Char> - { - public: - virtual size_type capacity() const - { - return max_size(); - } - - explicit String (PyObject *pyob, bool owned = false): SeqBase<Char>(pyob, owned) - { - validate(); - } - - String (const Object& ob): SeqBase<Char>(ob) - { - validate(); - } - - String() - : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true ) - { - validate(); - } - - String( const std::string& v ) - : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()), - static_cast<int>( v.length() ) ), true ) - { - validate(); - } - - String( const char *s, const char *encoding, const char *error="strict" ) - : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true ) - { - validate(); - } - - String( const char *s, int len, const char *encoding, const char *error="strict" ) - : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true ) - { - validate(); - } - - String( const std::string &s, const char *encoding, const char *error="strict" ) - : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true ) - { - validate(); - } - - String( const std::string& v, std::string::size_type vsize ) - : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v.data()), - static_cast<int>( vsize ) ), true) - { - validate(); - } - - String( const char *v, int vsize ) - : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true ) - { - validate(); - } - - String( const char* v ) - : SeqBase<Char>( PyString_FromString( v ), true ) - { - validate(); - } - - // Assignment acquires new ownership of pointer - String& operator= ( const Object& rhs ) - { - return *this = *rhs; - } - - String& operator= (PyObject* rhsp) - { - if( ptr() == rhsp ) - return *this; - set (rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob)); - } - - // Assignment from C string - String& operator= (const std::string& v) - { - set( PyString_FromStringAndSize( const_cast<char*>( v.data() ), - static_cast<int>( v.length() ) ), true ); - return *this; - } - String& operator= (const unicodestring& v) - { - set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ), - static_cast<int>( v.length() ) ), true ); - return *this; - } - - - // Encode - String encode( const char *encoding, const char *error="strict" ) - { - if( isUnicode() ) - { - return String( PyUnicode_AsEncodedString( ptr(), encoding, error ) ); - } - else - { - return String( PyString_AsEncodedObject( ptr(), encoding, error ) ); - } - } - - String decode( const char *encoding, const char *error="strict" ) - { - return Object( PyString_AsDecodedObject( ptr(), encoding, error ) ); - } - - // Queries - virtual size_type size () const - { - if( isUnicode() ) - { - return static_cast<size_type>( PyUnicode_GET_SIZE (ptr()) ); - } - else - { - return static_cast<size_type>( PyString_Size (ptr()) ); - } - } - - operator std::string () const - { - return as_std_string(); - } - - std::string as_std_string() const - { - if( isUnicode() ) - { - throw TypeError("cannot return std::string from Unicode object"); - } - else - { - return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) ); - } - } - - unicodestring as_unicodestring() const - { - if( isUnicode() ) - { - return unicodestring( PyUnicode_AS_UNICODE( ptr() ), - static_cast<size_type>( PyUnicode_GET_SIZE( ptr() ) ) ); - } - else - { - throw TypeError("can only return unicodestring from Unicode object"); - } - } - }; - - // ================================================== - // class Tuple - class Tuple: public Sequence - { - public: - virtual void setItem (sequence_index_type offset, const Object&ob) - { - // note PyTuple_SetItem is a thief... - if(PyTuple_SetItem (ptr(), offset, new_reference_to(ob)) == -1) - { - throw Exception(); - } - } - - // Constructor - explicit Tuple (PyObject *pyob, bool owned = false): Sequence (pyob, owned) - { - validate(); - } - - Tuple (const Object& ob): Sequence(ob) - { - validate(); - } - - // New tuple of a given size - explicit Tuple (int size = 0) - { - set(PyTuple_New (size), true); - validate (); - for (sequence_index_type i=0; i < size; i++) - { - if(PyTuple_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1) - { - throw Exception(); - } - } - } - // Tuple from any sequence - explicit Tuple (const Sequence& s) - { - sequence_index_type limit( sequence_index_type( s.length() ) ); - - set(PyTuple_New (limit), true); - validate(); - - for(sequence_index_type i=0; i < limit; i++) - { - if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1) - { - throw Exception(); - } - } - } - // Assignment acquires new ownership of pointer - - Tuple& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Tuple& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Tuple_Check (pyob); - } - - Tuple getSlice (int i, int j) const - { - return Tuple (PySequence_GetSlice (ptr(), i, j), true); - } - - }; - - // ================================================== - // class List - - class List: public Sequence - { - public: - // Constructor - explicit List (PyObject *pyob, bool owned = false): Sequence(pyob, owned) - { - validate(); - } - List (const Object& ob): Sequence(ob) - { - validate(); - } - // Creation at a fixed size - List (int size = 0) - { - set(PyList_New (size), true); - validate(); - for (sequence_index_type i=0; i < size; i++) - { - if(PyList_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1) - { - throw Exception(); - } - } - } - - // List from a sequence - List (const Sequence& s): Sequence() - { - int n = s.length(); - set(PyList_New (n), true); - validate(); - for (sequence_index_type i=0; i < n; i++) - { - if(PyList_SetItem (ptr(), i, new_reference_to(s[i])) == -1) - { - throw Exception(); - } - } - } - - virtual size_type capacity() const - { - return max_size(); - } - // Assignment acquires new ownership of pointer - - List& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - List& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_List_Check (pyob); - } - - List getSlice (int i, int j) const - { - return List (PyList_GetSlice (ptr(), i, j), true); - } - - void setSlice (int i, int j, const Object& v) - { - if(PyList_SetSlice (ptr(), i, j, *v) == -1) - { - throw Exception(); - } - } - - void append (const Object& ob) - { - if(PyList_Append (ptr(), *ob) == -1) - { - throw Exception(); - } - } - - void insert (int i, const Object& ob) - { - if(PyList_Insert (ptr(), i, *ob) == -1) - { - throw Exception(); - } - } - - void sort () - { - if(PyList_Sort(ptr()) == -1) - { - throw Exception(); - } - } - - void reverse () - { - if(PyList_Reverse(ptr()) == -1) - { - throw Exception(); - } - } - }; - - - // Mappings - // ================================================== - template<typename T> - class mapref - { - protected: - MapBase<T>& s; // the map - Object key; // item key - T the_item; - - public: - mapref<T> (MapBase<T>& map, const std::string& k) - : s(map), the_item() - { - key = String(k); - if(map.hasKey(key)) the_item = map.getItem(key); - }; - - mapref<T> (MapBase<T>& map, const Object& k) - : s(map), key(k), the_item() - { - if(map.hasKey(key)) the_item = map.getItem(key); - }; - - ~mapref() - {} - - // MapBase<T> stuff - // lvalue - mapref<T>& operator=(const mapref<T>& other) - { - if(this == &other) return *this; - the_item = other.the_item; - s.setItem(key, other.the_item); - return *this; - }; - - mapref<T>& operator= (const T& ob) - { - the_item = ob; - s.setItem (key, ob); - return *this; - } - - // rvalue - operator T() const - { - return the_item; - } - - // forward everything else to the_item - PyObject* ptr () const - { - return the_item.ptr(); - } - - int reference_count () const - { // the mapref count - return the_item.reference_count(); - } - - Type type () const - { - return the_item.type(); - } - - String str () const - { - return the_item.str(); - } - - String repr () const - { - return the_item.repr(); - } - - bool hasAttr (const std::string& attr_name) const - { - return the_item.hasAttr(attr_name); - } - - Object getAttr (const std::string& attr_name) const - { - return the_item.getAttr(attr_name); - } - - Object getItem (const Object& k) const - { - return the_item.getItem(k); - } - - long hashValue () const - { - return the_item.hashValue(); - } - - bool isCallable () const - { - return the_item.isCallable(); - } - - bool isList () const - { - return the_item.isList(); - } - - bool isMapping () const - { - return the_item.isMapping(); - } - - bool isNumeric () const - { - return the_item.isNumeric(); - } - - bool isSequence () const - { - return the_item.isSequence(); - } - - bool isTrue () const - { - return the_item.isTrue(); - } - - bool isType (const Type& t) const - { - return the_item.isType (t); - } - - bool isTuple() const - { - return the_item.isTuple(); - } - - bool isString() const - { - return the_item.isString(); - } - - // Commands - void setAttr (const std::string& attr_name, const Object& value) - { - the_item.setAttr(attr_name, value); - } - - void delAttr (const std::string& attr_name) - { - the_item.delAttr(attr_name); - } - - void delItem (const Object& k) - { - the_item.delItem(k); - } - }; // end of mapref - - // TMM: now for mapref<T> - template< class T > - bool operator==(const mapref<T>& left, const mapref<T>& right) - { - return true; // NOT completed. - } - - template< class T > - bool operator!=(const mapref<T>& left, const mapref<T>& right) - { - return true; // not completed. - } - - template<typename T> - class MapBase: public Object - { - protected: - explicit MapBase<T>() - {} - public: - // reference: proxy class for implementing [] - // TMM: 26Jun'01 - the types - // If you assume that Python mapping is a hash_map... - // hash_map::value_type is not assignable, but - // (*it).second = data must be a valid expression - typedef size_t size_type; - typedef Object key_type; - typedef mapref<T> data_type; - typedef std::pair< const T, T > value_type; - typedef std::pair< const T, mapref<T> > reference; - typedef const std::pair< const T, const T > const_reference; - typedef std::pair< const T, mapref<T> > pointer; - - // Constructor - explicit MapBase<T> (PyObject *pyob, bool owned = false): Object(pyob, owned) - { - validate(); - } - - // TMM: 02Jul'01 - changed MapBase<T> to Object in next line - MapBase<T> (const Object& ob): Object(ob) - { - validate(); - } - - // Assignment acquires new ownership of pointer - MapBase<T>& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - MapBase<T>& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && PyMapping_Check(pyob); - } - - // Clear -- PyMapping Clear is missing - // - - void clear () - { - List k = keys(); - for(List::iterator i = k.begin(); i != k.end(); i++) - { - delItem(*i); - } - } - - virtual size_type size() const - { - return PyMapping_Length (ptr()); - } - - // Element Access - T operator[](const std::string& key) const - { - return getItem(key); - } - - T operator[](const Object& key) const - { - return getItem(key); - } - - mapref<T> operator[](const std::string& key) - { - return mapref<T>(*this, key); - } - - mapref<T> operator[](const Object& key) - { - return mapref<T>(*this, key); - } - - int length () const - { - return PyMapping_Length (ptr()); - } - - bool hasKey (const std::string& s) const - { - return PyMapping_HasKeyString (ptr(),const_cast<char*>(s.c_str())) != 0; - } - - bool hasKey (const Object& s) const - { - return PyMapping_HasKey (ptr(), s.ptr()) != 0; - } - - T getItem (const std::string& s) const - { - return T( - asObject(PyMapping_GetItemString (ptr(),const_cast<char*>(s.c_str()))) - ); - } - - T getItem (const Object& s) const - { - return T( - asObject(PyObject_GetItem (ptr(), s.ptr())) - ); - } - - virtual void setItem (const char *s, const Object& ob) - { - if (PyMapping_SetItemString (ptr(), const_cast<char*>(s), *ob) == -1) - { - throw Exception(); - } - } - - virtual void setItem (const std::string& s, const Object& ob) - { - if (PyMapping_SetItemString (ptr(), const_cast<char*>(s.c_str()), *ob) == -1) - { - throw Exception(); - } - } - - virtual void setItem (const Object& s, const Object& ob) - { - if (PyObject_SetItem (ptr(), s.ptr(), ob.ptr()) == -1) - { - throw Exception(); - } - } - - void delItem (const std::string& s) - { - if (PyMapping_DelItemString (ptr(), const_cast<char*>(s.c_str())) == -1) - { - throw Exception(); - } - } - - void delItem (const Object& s) - { - if (PyMapping_DelItem (ptr(), *s) == -1) - { - throw Exception(); - } - } - // Queries - List keys () const - { - return List(PyMapping_Keys(ptr()), true); - } - - List values () const - { // each returned item is a (key, value) pair - return List(PyMapping_Values(ptr()), true); - } - - List items () const - { - return List(PyMapping_Items(ptr()), true); - } - - // iterators for MapBase<T> - // Added by TMM: 2Jul'01 - NOT COMPLETED - // There is still a bug. I decided to stop, before fixing the bug, because - // this can't be halfway efficient until Python gets built-in iterators. - // My current soln is to iterate over the map by getting a copy of its keys - // and iterating over that. Not a good solution. - - // The iterator holds a MapBase<T>* rather than a MapBase<T> because that's - // how the sequence iterator is implemented and it works. But it does seem - // odd to me - we are iterating over the map object, not the reference. - -#if 0 // here is the test code with which I found the (still existing) bug - typedef cxx::Dict d_t; - d_t d; - cxx::String s1("blah"); - cxx::String s2("gorf"); - d[ "one" ] = s1; - d[ "two" ] = s1; - d[ "three" ] = s2; - d[ "four" ] = s2; - - d_t::iterator it; - it = d.begin(); // this (using the assignment operator) is causing - // a problem; if I just use the copy ctor it works fine. - for( ; it != d.end(); ++it ) - { - d_t::value_type vt( *it ); - cxx::String rs = vt.second.repr(); - std::string ls = rs.operator std::string(); - fprintf( stderr, "%s\n", ls ); - } -#endif // 0 - - class iterator - { - // : public forward_iterator_parent( std::pair<const T,T> ) { - protected: - typedef std::forward_iterator_tag iterator_category; - typedef std::pair< const T, T > value_type; - typedef int difference_type; - typedef std::pair< const T, mapref<T> > pointer; - typedef std::pair< const T, mapref<T> > reference; - - friend class MapBase<T>; - // - MapBase<T>* map; - List keys; // for iterating over the map - List::iterator pos; // index into the keys - - public: - ~iterator () - {} - - iterator () - : map( 0 ) - , keys() - , pos() - {} - - iterator (MapBase<T>* m, bool end = false ) - : map( m ) - , keys( m->keys() ) - , pos( end ? keys.end() : keys.begin() ) - {} - - iterator (const iterator& other) - : map( other.map ) - , keys( other.keys ) - , pos( other.pos ) - {} - - reference operator*() - { - Object key = *pos; - return std::make_pair(key, mapref<T>(*map,key)); - } - - iterator& operator=(const iterator& other) - { - if (this == &other) - return *this; - map = other.map; - keys = other.keys; - pos = other.pos; - return *this; - } - - bool eql(const iterator& right) const - { - return *map == *right.map && pos == right.pos; - } - bool neq( const iterator& right ) const - { - return *map != *right.map || pos != right.pos; - } - - // pointer operator->() { - // return ; - // } - - // prefix ++ - iterator& operator++ () - { pos++; return *this;} - // postfix ++ - iterator operator++ (int) - { return iterator(map, keys, pos++);} - // prefix -- - iterator& operator-- () - { pos--; return *this;} - // postfix -- - iterator operator-- (int) - { return iterator(map, keys, pos--);} - - std::string diagnose() const - { - std::ostringstream oss; - oss << "iterator diagnosis " << map << ", " << pos << std::ends; - return std::string(oss.str()); - } - }; // end of class MapBase<T>::iterator - - iterator begin () - { - return iterator(this); - } - - iterator end () - { - return iterator(this, true); - } - - class const_iterator - { - protected: - typedef std::forward_iterator_tag iterator_category; - typedef const std::pair< const T, T > value_type; - typedef int difference_type; - typedef const std::pair< const T, T > pointer; - typedef const std::pair< const T, T > reference; - - friend class MapBase<T>; - const MapBase<T>* map; - List keys; // for iterating over the map - List::iterator pos; // index into the keys - - public: - ~const_iterator () - {} - - const_iterator () - : map( 0 ) - , keys() - , pos() - {} - - const_iterator (const MapBase<T>* m, List k, List::iterator p ) - : map( m ) - , keys( k ) - , pos( p ) - {} - - const_iterator(const const_iterator& other) - : map( other.map ) - , keys( other.keys ) - , pos( other.pos ) - {} - - bool eql(const const_iterator& right) const - { - return *map == *right.map && pos == right.pos; - } - bool neq( const const_iterator& right ) const - { - return *map != *right.map || pos != right.pos; - } - - - // const_reference operator*() { - // Object key = *pos; - // return std::make_pair( key, map->[key] ); - // GCC < 3 barfes on this line at the '['. - // } - - const_iterator& operator=(const const_iterator& other) - { - if (this == &other) return *this; - map = other.map; - keys = other.keys; - pos = other.pos; - return *this; - } - - // prefix ++ - const_iterator& operator++ () - { pos++; return *this;} - // postfix ++ - const_iterator operator++ (int) - { return const_iterator(map, keys, pos++);} - // prefix -- - const_iterator& operator-- () - { pos--; return *this;} - // postfix -- - const_iterator operator-- (int) - { return const_iterator(map, keys, pos--);} - }; // end of class MapBase<T>::const_iterator - - const_iterator begin () const - { - return const_iterator(this, 0); - } - - const_iterator end () const - { - return const_iterator(this, length()); - } - - }; // end of MapBase<T> - - typedef MapBase<Object> Mapping; - - template <typename T> bool operator==(const typename MapBase<T>::iterator& left, const typename MapBase<T>::iterator& right); - template <typename T> bool operator!=(const typename MapBase<T>::iterator& left, const typename MapBase<T>::iterator& right); - template <typename T> bool operator==(const typename MapBase<T>::const_iterator& left, const typename MapBase<T>::const_iterator& right); - template <typename T> bool operator!=(const typename MapBase<T>::const_iterator& left, const typename MapBase<T>::const_iterator& right); - - extern bool operator==(const Mapping::iterator& left, const Mapping::iterator& right); - extern bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right); - extern bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right); - extern bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right); - - - // ================================================== - // class Dict - class Dict: public Mapping - { - public: - // Constructor - explicit Dict (PyObject *pyob, bool owned=false): Mapping (pyob, owned) - { - validate(); - } - Dict (const Dict& ob): Mapping(ob) - { - validate(); - } - // Creation - Dict () - { - set(PyDict_New (), true); - validate(); - } - // Assignment acquires new ownership of pointer - - Dict& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Dict& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set(rhsp); - return *this; - } - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && Py::_Dict_Check (pyob); - } - }; - - class Callable: public Object - { - protected: - explicit Callable (): Object() - {} - public: - // Constructor - explicit Callable (PyObject *pyob, bool owned = false): Object (pyob, owned) - { - validate(); - } - - Callable (const Object& ob): Object(ob) - { - validate(); - } - - // Assignment acquires new ownership of pointer - - Callable& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Callable& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set (rhsp); - return *this; - } - - // Membership - virtual bool accepts (PyObject *pyob) const - { - return pyob && PyCallable_Check (pyob); - } - - // Call - Object apply(const Tuple& args) const - { - return asObject(PyObject_CallObject(ptr(), args.ptr())); - } - - // Call with keywords - Object apply(const Tuple& args, const Dict& kw) const - { - return asObject( PyEval_CallObjectWithKeywords( ptr(), args.ptr(), kw.ptr() ) ); - } - - Object apply(PyObject* pargs = 0) const - { - return apply (Tuple(pargs)); - } - }; - - class Module: public Object - { - public: - explicit Module (PyObject* pyob, bool owned = false): Object (pyob, owned) - { - validate(); - } - - // Construct from module name - explicit Module (const std::string&s): Object() - { - PyObject *m = PyImport_AddModule( const_cast<char *>(s.c_str()) ); - set( m, false ); - validate (); - } - - // Copy constructor acquires new ownership of pointer - Module (const Module& ob): Object(*ob) - { - validate(); - } - - Module& operator= (const Object& rhs) - { - return (*this = *rhs); - } - - Module& operator= (PyObject* rhsp) - { - if(ptr() == rhsp) return *this; - set(rhsp); - return *this; - } - - Dict getDict() - { - return Dict(PyModule_GetDict(ptr())); - // Caution -- PyModule_GetDict returns borrowed reference! - } - }; - - // Numeric interface - inline Object operator+ (const Object& a) - { - return asObject(PyNumber_Positive(*a)); - } - inline Object operator- (const Object& a) - { - return asObject(PyNumber_Negative(*a)); - } - - inline Object abs(const Object& a) - { - return asObject(PyNumber_Absolute(*a)); - } - - inline std::pair<Object,Object> coerce(const Object& a, const Object& b) - { - PyObject *p1, *p2; - p1 = *a; - p2 = *b; - if(PyNumber_Coerce(&p1,&p2) == -1) - { - throw Exception(); - } - return std::pair<Object,Object>(asObject(p1), asObject(p2)); - } - - inline Object operator+ (const Object& a, const Object& b) - { - return asObject(PyNumber_Add(*a, *b)); - } - inline Object operator+ (const Object& a, int j) - { - return asObject(PyNumber_Add(*a, *Int(j))); - } - inline Object operator+ (const Object& a, double v) - { - return asObject(PyNumber_Add(*a, *Float(v))); - } - inline Object operator+ (int j, const Object& b) - { - return asObject(PyNumber_Add(*Int(j), *b)); - } - inline Object operator+ (double v, const Object& b) - { - return asObject(PyNumber_Add(*Float(v), *b)); - } - - inline Object operator- (const Object& a, const Object& b) - { - return asObject(PyNumber_Subtract(*a, *b)); - } - inline Object operator- (const Object& a, int j) - { - return asObject(PyNumber_Subtract(*a, *Int(j))); - } - inline Object operator- (const Object& a, double v) - { - return asObject(PyNumber_Subtract(*a, *Float(v))); - } - inline Object operator- (int j, const Object& b) - { - return asObject(PyNumber_Subtract(*Int(j), *b)); - } - inline Object operator- (double v, const Object& b) - { - return asObject(PyNumber_Subtract(*Float(v), *b)); - } - - inline Object operator* (const Object& a, const Object& b) - { - return asObject(PyNumber_Multiply(*a, *b)); - } - inline Object operator* (const Object& a, int j) - { - return asObject(PyNumber_Multiply(*a, *Int(j))); - } - inline Object operator* (const Object& a, double v) - { - return asObject(PyNumber_Multiply(*a, *Float(v))); - } - inline Object operator* (int j, const Object& b) - { - return asObject(PyNumber_Multiply(*Int(j), *b)); - } - inline Object operator* (double v, const Object& b) - { - return asObject(PyNumber_Multiply(*Float(v), *b)); - } - - inline Object operator/ (const Object& a, const Object& b) - { - return asObject(PyNumber_Divide(*a, *b)); - } - inline Object operator/ (const Object& a, int j) - { - return asObject(PyNumber_Divide(*a, *Int(j))); - } - inline Object operator/ (const Object& a, double v) - { - return asObject(PyNumber_Divide(*a, *Float(v))); - } - inline Object operator/ (int j, const Object& b) - { - return asObject(PyNumber_Divide(*Int(j), *b)); - } - inline Object operator/ (double v, const Object& b) - { - return asObject(PyNumber_Divide(*Float(v), *b)); - } - - inline Object operator% (const Object& a, const Object& b) - { - return asObject(PyNumber_Remainder(*a, *b)); - } - inline Object operator% (const Object& a, int j) - { - return asObject(PyNumber_Remainder(*a, *Int(j))); - } - inline Object operator% (const Object& a, double v) - { - return asObject(PyNumber_Remainder(*a, *Float(v))); - } - inline Object operator% (int j, const Object& b) - { - return asObject(PyNumber_Remainder(*Int(j), *b)); - } - inline Object operator% (double v, const Object& b) - { - return asObject(PyNumber_Remainder(*Float(v), *b)); - } - - inline Object type(const Exception&) // return the type of the error - { - PyObject *ptype, *pvalue, *ptrace; - PyErr_Fetch(&ptype, &pvalue, &ptrace); - Object result(ptype); - PyErr_Restore(ptype, pvalue, ptrace); - return result; - } - - inline Object value(const Exception&) // return the value of the error - { - PyObject *ptype, *pvalue, *ptrace; - PyErr_Fetch(&ptype, &pvalue, &ptrace); - Object result; - if(pvalue) result = pvalue; - PyErr_Restore(ptype, pvalue, ptrace); - return result; - } - - inline Object trace(const Exception&) // return the traceback of the error - { - PyObject *ptype, *pvalue, *ptrace; - PyErr_Fetch(&ptype, &pvalue, &ptrace); - Object result; - if(ptrace) result = ptrace; - PyErr_Restore(ptype, pvalue, ptrace); - return result; - } - - - -template<typename T> -String seqref<T>::str () const - { - return the_item.str(); - } - -template<typename T> -String seqref<T>::repr () const - { - return the_item.repr(); - } - - - } // namespace Py -#endif // __CXX_Objects__h |