summaryrefslogtreecommitdiffstats
path: root/lib/kross/python/cxx/Objects.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kross/python/cxx/Objects.hxx')
-rw-r--r--lib/kross/python/cxx/Objects.hxx2804
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