Code

change case
authorishmal <ishmal@users.sourceforge.net>
Sun, 15 Apr 2007 09:14:15 +0000 (09:14 +0000)
committerishmal <ishmal@users.sourceforge.net>
Sun, 15 Apr 2007 09:14:15 +0000 (09:14 +0000)
src/extension/script/CXX/Config.hxx [new file with mode: 0644]
src/extension/script/CXX/Exception.hxx [new file with mode: 0644]
src/extension/script/CXX/Extensions.hxx [new file with mode: 0644]
src/extension/script/CXX/IndirectPythonInterface.cxx [new file with mode: 0644]
src/extension/script/CXX/IndirectPythonInterface.hxx [new file with mode: 0644]
src/extension/script/CXX/Objects.hxx [new file with mode: 0644]
src/extension/script/CXX/Version.hxx [new file with mode: 0644]
src/extension/script/CXX/WrapPython.h [new file with mode: 0644]
src/extension/script/CXX/cxx_extensions.cxx [new file with mode: 0644]
src/extension/script/CXX/cxxextensions.c [new file with mode: 0644]
src/extension/script/CXX/cxxsupport.cxx [new file with mode: 0644]

diff --git a/src/extension/script/CXX/Config.hxx b/src/extension/script/CXX/Config.hxx
new file mode 100644 (file)
index 0000000..b27f9ba
--- /dev/null
@@ -0,0 +1,118 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __PyCXX_config_hh__
+#define __PyCXX_config_hh__
+
+//
+// Microsoft VC++ 6.0 has no traits
+//
+#if defined( _MSC_VER )
+
+#  define STANDARD_LIBRARY_HAS_ITERATOR_TRAITS 1
+
+#elif defined( __GNUC__ )
+#  if __GNUC__ >= 3
+#    define STANDARD_LIBRARY_HAS_ITERATOR_TRAITS 1
+#  else
+#    define STANDARD_LIBRARY_HAS_ITERATOR_TRAITS 0
+#endif
+
+//
+//     Assume all other compilers do
+//
+#else
+
+// Macros to deal with deficiencies in compilers
+#  define STANDARD_LIBRARY_HAS_ITERATOR_TRAITS 1
+#endif
+
+#if STANDARD_LIBRARY_HAS_ITERATOR_TRAITS
+#  define random_access_iterator_parent(itemtype) std::iterator<std::random_access_iterator_tag,itemtype,int>
+#else
+#  define random_access_iterator_parent(itemtype) std::random_access_iterator<itemtype, int>
+#endif
+
+//
+//     Which C++ standard is in use?
+//
+#if defined( _MSC_VER )
+#  if _MSC_VER <= 1200
+// MSVC++ 6.0
+#    define PYCXX_ISO_CPP_LIB 0
+#    define STR_STREAM <strstream>
+#    define TEMPLATE_TYPENAME class
+#  else
+#    define PYCXX_ISO_CPP_LIB 1
+#    define STR_STREAM <sstream>
+#    define TEMPLATE_TYPENAME typename
+#  endif
+#elif defined( __GNUC__ )
+#  if __GNUC__ >= 3
+#    define PYCXX_ISO_CPP_LIB 1
+#    define STR_STREAM <sstream>
+#    define TEMPLATE_TYPENAME typename
+#  else
+#    define PYCXX_ISO_CPP_LIB 0
+#    define STR_STREAM <strstream>
+#    define TEMPLATE_TYPENAME class
+#  endif
+#endif
+
+#if PYCXX_ISO_CPP_LIB
+#    define STR_STREAM <sstream>
+#    define OSTRSTREAM ostringstream
+#    define EXPLICIT_TYPENAME typename
+#    define EXPLICIT_CLASS class
+#    define TEMPLATE_TYPENAME typename
+#else
+#    define STR_STREAM <strstream>
+#    define OSTRSTREAM ostrstream
+#    define EXPLICIT_TYPENAME
+#    define EXPLICIT_CLASS
+#    define TEMPLATE_TYPENAME class
+#endif
+
+// before 2.5 Py_ssize_t was missing
+#ifndef PY_MAJOR_VERSION
+#error not defined PY_MAJOR_VERSION
+#endif
+#if PY_MAJOR_VERSION < 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5)
+typedef int Py_ssize_t;
+#endif
+
+#endif //  __PyCXX_config_hh__
diff --git a/src/extension/script/CXX/Exception.hxx b/src/extension/script/CXX/Exception.hxx
new file mode 100644 (file)
index 0000000..1ef087c
--- /dev/null
@@ -0,0 +1,249 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __CXX_Exception_h
+#define __CXX_Exception_h
+
+#include "CXX/WrapPython.h"
+#include "CXX/Version.hxx"
+#include "CXX/Config.hxx"
+#include "CXX/IndirectPythonInterface.hxx"
+
+#include <string>
+#include <iostream>
+
+// This mimics the Python structure, in order to minimize confusion
+namespace Py
+{
+    class ExtensionExceptionType;
+
+    class Object;
+
+    class Exception
+    {
+    public:
+        Exception( ExtensionExceptionType &exception, const std::string& reason );
+        Exception( ExtensionExceptionType &exception, Object &reason );
+
+        explicit Exception ()
+        {}
+        
+        Exception (const std::string& reason)
+        {
+            PyErr_SetString (Py::_Exc_RuntimeError(), reason.c_str());
+        }
+        
+        Exception (PyObject* exception, const std::string& reason)
+        {
+            PyErr_SetString (exception, reason.c_str());
+        }
+        
+        Exception (PyObject* exception, Object &reason);        
+
+        void clear() // clear the error
+        // technically but not philosophically const
+        {
+            PyErr_Clear();
+        }
+    };
+    
+    
+    // Abstract
+    class StandardError: public Exception
+    {
+    protected: 
+        explicit StandardError()
+        {}
+    };
+    
+    class LookupError: public StandardError
+    {
+    protected: 
+        explicit LookupError()
+        {}
+    };
+    
+    class ArithmeticError: public StandardError
+    {
+    protected: 
+        explicit ArithmeticError()
+        {}
+    };
+    
+    class EnvironmentError: public StandardError
+    {
+    protected: 
+        explicit EnvironmentError()
+        {}
+    };
+    
+    // Concrete
+    
+    class TypeError: public StandardError
+    {
+    public:
+        TypeError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_TypeError(),reason.c_str());
+        }
+    };
+    
+    class IndexError: public LookupError
+    {
+    public:
+        IndexError (const std::string& reason)
+            : LookupError()
+        {
+            PyErr_SetString (Py::_Exc_IndexError(), reason.c_str());
+        }
+    };
+    
+    class AttributeError: public StandardError
+    {
+    public:
+        AttributeError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_AttributeError(), reason.c_str());
+        }        
+    };
+    
+    class NameError: public StandardError
+    {
+    public:
+        NameError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_NameError(), reason.c_str());
+        }
+    };
+    
+    class RuntimeError: public StandardError
+    {
+    public:
+        RuntimeError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_RuntimeError(), reason.c_str());
+        }
+    };
+    
+    class SystemError: public StandardError
+    {
+    public:
+        SystemError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_SystemError(),reason.c_str());
+        }
+    };
+    
+    class KeyError: public LookupError
+    {
+    public:
+        KeyError (const std::string& reason)
+            : LookupError()
+        {
+            PyErr_SetString (Py::_Exc_KeyError(),reason.c_str());
+        }
+    };
+    
+    
+    class ValueError: public StandardError
+    {
+    public:
+        ValueError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_ValueError(), reason.c_str());
+        }
+    };
+    
+    class OverflowError: public ArithmeticError
+    {
+    public:
+        OverflowError (const std::string& reason)
+            : ArithmeticError()
+        {
+            PyErr_SetString (Py::_Exc_OverflowError(), reason.c_str());
+        }        
+    };
+    
+    class ZeroDivisionError: public ArithmeticError
+    {
+    public:
+        ZeroDivisionError (const std::string& reason)
+            : ArithmeticError() 
+        {
+            PyErr_SetString (Py::_Exc_ZeroDivisionError(), reason.c_str());
+        }
+    };
+    
+    class FloatingPointError: public ArithmeticError
+    {
+    public:
+        FloatingPointError (const std::string& reason)
+            : ArithmeticError() 
+        {
+            PyErr_SetString (Py::_Exc_FloatingPointError(), reason.c_str());
+        }
+    };
+    
+    class MemoryError: public StandardError
+    {
+    public:
+        MemoryError (const std::string& reason)
+            : StandardError()
+        {
+            PyErr_SetString (Py::_Exc_MemoryError(), reason.c_str());
+        }    
+    };
+    
+    class SystemExit: public StandardError
+    {
+    public:
+        SystemExit (const std::string& reason)
+            : StandardError() 
+        {
+            PyErr_SetString (Py::_Exc_SystemExit(),reason.c_str());
+        }
+    };
+
+}// Py
+
+#endif
diff --git a/src/extension/script/CXX/Extensions.hxx b/src/extension/script/CXX/Extensions.hxx
new file mode 100644 (file)
index 0000000..83738c9
--- /dev/null
@@ -0,0 +1,791 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __CXX_Extensions__h
+#define __CXX_Extensions__h
+
+
+#ifdef _MSC_VER
+// disable warning C4786: symbol greater than 255 character,
+// okay to ignore
+#pragma warning(disable: 4786)
+#endif
+
+#include "CXX/WrapPython.h"
+#include "CXX/Version.hxx"
+#include "CXX/Config.hxx"
+#include "CXX/Objects.hxx"
+
+extern "C"
+{
+    extern PyObject py_object_initializer;
+}
+
+#include <vector>
+#include <map>
+
+namespace Py
+{
+    class ExtensionModuleBase;
+    
+    // Make an Exception Type for use in raising custom exceptions
+    class ExtensionExceptionType : public Object
+    {
+    public:
+        ExtensionExceptionType();
+        virtual ~ExtensionExceptionType();
+
+        // call init to create the type
+        void init(  ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent );
+        void init(  ExtensionModuleBase &module, const std::string& name );
+    };
+
+    
+    class MethodTable 
+    {
+    public:
+        MethodTable();
+        virtual ~MethodTable();
+        
+        void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
+        PyMethodDef* table();
+        
+    protected:
+        std::vector<PyMethodDef> t;    // accumulator of PyMethodDef's
+        PyMethodDef *mt;        // Actual method table produced when full
+        
+        static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
+        
+    private:
+        //
+        // prevent the compiler generating these unwanted functions
+        //
+        MethodTable(const MethodTable& m);    //unimplemented
+        void operator=(const MethodTable& m);    //unimplemented
+        
+    }; // end class MethodTable
+    
+    extern "C"
+    {
+        typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
+        typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
+    };
+    
+    template<class T>
+    class MethodDefExt : public PyMethodDef
+    {
+    public:
+        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
+        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
+        
+        MethodDefExt
+        (
+        const char *_name,
+        method_varargs_function_t _function,
+        method_varargs_call_handler_t _handler,
+        const char *_doc
+        )
+        {
+            ext_meth_def.ml_name = const_cast<char *>(_name);
+            ext_meth_def.ml_meth = _handler;
+            ext_meth_def.ml_flags = METH_VARARGS;
+            ext_meth_def.ml_doc = const_cast<char *>(_doc);
+            
+            ext_varargs_function = _function;
+            ext_keyword_function = NULL;
+        }
+        
+        MethodDefExt
+        (
+        const char *_name,
+        method_keyword_function_t _function,
+        method_keyword_call_handler_t _handler,
+        const char *_doc
+        )
+        {
+            ext_meth_def.ml_name = const_cast<char *>(_name);
+            ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
+            ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
+            ext_meth_def.ml_doc = const_cast<char *>(_doc);
+            
+            ext_varargs_function = NULL;
+            ext_keyword_function = _function;
+        }
+        
+        ~MethodDefExt()
+        {}
+        
+        PyMethodDef ext_meth_def;
+        method_varargs_function_t ext_varargs_function;    
+        method_keyword_function_t ext_keyword_function;    
+    };
+    
+    class ExtensionModuleBase
+    {
+    public:
+        ExtensionModuleBase( const char *name );
+        virtual ~ExtensionModuleBase();
+        
+        Module module(void) const;        // only valid after initialize() has been called
+        Dict moduleDictionary(void) const;    // only valid after initialize() has been called
+        
+        virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
+        virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
+        
+        const std::string &name() const;
+        const std::string &fullName() const;
+    
+    protected:
+        // Initialize the module
+        void initialize( const char *module_doc );
+        
+        const std::string module_name;
+        const std::string full_module_name;
+        MethodTable method_table;
+        
+    private:
+        
+        //
+        // prevent the compiler generating these unwanted functions
+        //
+        ExtensionModuleBase( const ExtensionModuleBase & );    //unimplemented
+        void operator=( const ExtensionModuleBase & );        //unimplemented
+        
+    };
+    
+    extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
+    extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
+    extern "C" void do_not_dealloc( void * );
+    
+    
+    template<TEMPLATE_TYPENAME T>
+    class ExtensionModule : public ExtensionModuleBase
+    {
+    public:
+        ExtensionModule( const char *name )
+            : ExtensionModuleBase( name )
+        {}
+        virtual ~ExtensionModule()
+        {}
+        
+    protected:
+        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
+        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
+        typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
+        
+        static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
+        {
+            method_map_t &mm = methods();
+            
+            MethodDefExt<T> *method_definition = new MethodDefExt<T>
+            (
+            name,
+            function,
+            method_varargs_call_handler,
+            doc
+            );
+            
+            mm[std::string( name )] = method_definition;
+        }
+        
+        static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
+        {
+            method_map_t &mm = methods();
+            
+            MethodDefExt<T> *method_definition = new MethodDefExt<T>
+            (
+            name,
+            function,
+            method_keyword_call_handler,
+            doc
+            );
+            
+            mm[std::string( name )] = method_definition;
+        }
+
+        void initialize( const char *module_doc="" )
+        {
+            ExtensionModuleBase::initialize( module_doc );
+            Dict dict( moduleDictionary() );
+            
+            //
+            // put each of the methods into the modules dictionary
+            // so that we get called back at the function in T.
+            //
+            method_map_t &mm = methods();
+            EXPLICIT_TYPENAME method_map_t::iterator i;
+            
+            for( i=mm.begin(); i != mm.end(); ++i )
+            {
+                MethodDefExt<T> *method_definition = (*i).second;
+                
+                static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
+                
+                Tuple args( 2 );
+                args[0] = Object( self );
+                args[1] = String( (*i).first );
+                
+                PyObject *func = PyCFunction_New
+                (
+                &method_definition->ext_meth_def,
+                new_reference_to( args )
+                );
+                
+                dict[ (*i).first ] = Object( func );
+            }
+        }
+        
+    protected:    // Tom Malcolmson reports that derived classes need access to these
+        
+        static method_map_t &methods(void)
+        {
+            static method_map_t *map_of_methods = NULL;
+            if( map_of_methods == NULL )
+            map_of_methods = new method_map_t;
+            
+            return *map_of_methods;
+        }
+        
+        
+        // this invoke function must be called from within a try catch block
+        virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
+        {
+            method_map_t &mm = methods();
+            MethodDefExt<T> *meth_def = mm[ name ];
+            if( meth_def == NULL )
+            {
+                std::string error_msg( "CXX - cannot invoke keyword method named " );
+                error_msg += name;
+                throw RuntimeError( error_msg );
+            }
+            
+            // cast up to the derived class
+            T *self = static_cast<T *>(this);
+            
+            return (self->*meth_def->ext_keyword_function)( args, keywords );
+        }
+        
+        // this invoke function must be called from within a try catch block
+        virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
+        {
+            method_map_t &mm = methods();
+            MethodDefExt<T> *meth_def = mm[ name ];
+            if( meth_def == NULL )
+            {
+                std::string error_msg( "CXX - cannot invoke varargs method named " );
+                error_msg += name;
+                throw RuntimeError( error_msg );
+            }
+            
+            // cast up to the derived class
+            T *self = static_cast<T *>(this);
+            
+            return (self->*meth_def->ext_varargs_function)( args );
+        }
+        
+    private:
+        //
+        // prevent the compiler generating these unwanted functions
+        //
+        ExtensionModule( const ExtensionModule<T> & );    //unimplemented
+        void operator=( const ExtensionModule<T> & );    //unimplemented
+    };
+    
+    
+    class PythonType
+    {
+    public:
+        // if you define one sequence method you must define 
+        // all of them except the assigns
+        
+        PythonType (size_t base_size, int itemsize, const char *default_name );
+        virtual ~PythonType ();
+        
+        const char *getName () const;
+        const char *getDoc () const;
+
+        PyTypeObject* type_object () const;
+        PythonType & name (const char* nam);
+        PythonType & doc (const char* d);
+        PythonType & dealloc(void (*f)(PyObject*));
+        
+        PythonType & supportPrint(void);
+        PythonType & supportGetattr(void);
+        PythonType & supportSetattr(void);
+        PythonType & supportGetattro(void);
+        PythonType & supportSetattro(void);
+        PythonType & supportCompare(void);
+        PythonType & supportRepr(void);
+        PythonType & supportStr(void);
+        PythonType & supportHash(void);
+        PythonType & supportCall(void);
+        PythonType & supportIter(void);
+        
+        PythonType & supportSequenceType(void);
+        PythonType & supportMappingType(void);
+        PythonType & supportNumberType(void);
+        PythonType & supportBufferType(void);
+        
+    protected:
+        PyTypeObject        *table;
+        PySequenceMethods    *sequence_table;
+        PyMappingMethods    *mapping_table;
+        PyNumberMethods        *number_table;
+        PyBufferProcs        *buffer_table;
+        
+        void init_sequence();
+        void init_mapping();
+        void init_number();
+        void init_buffer();
+        
+    private:
+        //
+        // prevent the compiler generating these unwanted functions
+        //
+        PythonType (const PythonType& tb);    // unimplemented
+        void operator=(const PythonType& t);    // unimplemented
+        
+    }; // end of PythonType
+    
+    
+    
+    // Class PythonExtension is what you inherit from to create
+    // a new Python extension type. You give your class itself
+    // as the template paramter.
+    
+    // There are two ways that extension objects can get destroyed.
+    // 1. Their reference count goes to zero
+    // 2. Someone does an explicit delete on a pointer.
+    // In (1) the problem is to get the destructor called 
+    //        We register a special deallocator in the Python type object
+    //        (see behaviors()) to do this.
+    // In (2) there is no problem, the dtor gets called.
+    
+    // PythonExtension does not use the usual Python heap allocator, 
+    // instead using new/delete. We do the setting of the type object
+    // and reference count, usually done by PyObject_New, in the 
+    // base class ctor.
+    
+    // This special deallocator does a delete on the pointer.
+    
+    
+    class PythonExtensionBase : public PyObject
+    {
+    public:
+        PythonExtensionBase();
+        virtual ~PythonExtensionBase();
+        
+    public:
+        virtual int print( FILE *, int );
+        virtual Object getattr( const char * ) = 0;
+        virtual int setattr( const char *, const Object & );
+        virtual Object getattro( const Object & );
+        virtual int setattro( const Object &, const Object & );
+        virtual int compare( const Object & );
+        virtual Object repr();
+        virtual Object str();
+        virtual long hash();
+        virtual Object call( const Object &, const Object & );
+                virtual Object iter();
+                virtual PyObject* iternext();
+        
+        // Sequence methods
+        virtual int sequence_length();
+        virtual Object sequence_concat( const Object & );
+        virtual Object sequence_repeat( Py_ssize_t );
+        virtual Object sequence_item( Py_ssize_t );
+        virtual Object sequence_slice( Py_ssize_t, Py_ssize_t );
+        virtual int sequence_ass_item( Py_ssize_t, const Object & );
+        virtual int sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Object & );
+        
+        // Mapping
+        virtual int mapping_length();
+        virtual Object mapping_subscript( const Object & );
+        virtual int mapping_ass_subscript( const Object &, const Object & );
+        
+        // Number
+        virtual int number_nonzero();
+        virtual Object number_negative();
+        virtual Object number_positive();
+        virtual Object number_absolute();
+        virtual Object number_invert();
+        virtual Object number_int();
+        virtual Object number_float();
+        virtual Object number_long();
+        virtual Object number_oct();
+        virtual Object number_hex();
+        virtual Object number_add( const Object & );
+        virtual Object number_subtract( const Object & );
+        virtual Object number_multiply( const Object & );
+        virtual Object number_divide( const Object & );
+        virtual Object number_remainder( const Object & );
+        virtual Object number_divmod( const Object & );
+        virtual Object number_lshift( const Object & );
+        virtual Object number_rshift( const Object & );
+        virtual Object number_and( const Object & );
+        virtual Object number_xor( const Object & );
+        virtual Object number_or( const Object & );
+        virtual Object number_power( const Object &, const Object & );
+        
+        // Buffer
+        virtual Py_ssize_t buffer_getreadbuffer( Py_ssize_t, void** );
+        virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
+        virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );
+        
+    private:
+        void missing_method( void );
+        static PyObject *method_call_handler( PyObject *self, PyObject *args );
+    };
+    
+    template<TEMPLATE_TYPENAME T>
+    class PythonExtension: public PythonExtensionBase 
+    {
+    public:
+        static PyTypeObject* type_object() 
+        {
+            return behaviors().type_object();
+        }
+        
+        static int check( PyObject *p )
+        {
+            // is p like me?
+            return p->ob_type == type_object();
+        }
+        
+        static int check( const Object& ob )
+        {
+            return check( ob.ptr());
+        }
+        
+        
+        //
+        // every object needs getattr implemented
+        // to support methods
+        //
+        virtual Object getattr( const char *name )
+        {
+            return getattr_methods( name );
+        }
+        
+    protected:
+        explicit PythonExtension()
+            : PythonExtensionBase()
+        {
+            #ifdef PyObject_INIT
+            (void)PyObject_INIT( this, type_object() );
+            #else
+            ob_refcnt = 1;
+            ob_type = type_object();
+            #endif
+            
+            // every object must support getattr
+            behaviors().supportGetattr();
+        }
+        
+        virtual ~PythonExtension()
+        {} 
+        
+        static PythonType &behaviors()
+        {
+            static PythonType* p;
+            if( p == NULL ) 
+            {
+#if defined( _CPPRTTI ) || defined(__GNUG__)
+                const char *default_name = (typeid ( T )).name();
+#else
+                const char *default_name = "unknown";
+#endif
+                p = new PythonType( sizeof( T ), 0, default_name );
+                p->dealloc( extension_object_deallocator );
+            }
+            
+            return *p;
+        }
+        
+        
+        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
+        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
+        typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
+        
+        // support the default attributes, __name__, __doc__ and methods
+        virtual Object getattr_default( const char *_name )
+        {
+            std::string name( _name );
+
+            if( name == "__name__" && type_object()->tp_name != NULL )
+            {
+                return Py::String( type_object()->tp_name );
+            }
+            if( name == "__doc__" && type_object()->tp_doc != NULL )
+            {
+                return Py::String( type_object()->tp_doc );
+            }
+
+// trying to fake out being a class for help()
+//            else if( name == "__bases__"  )
+//            {
+//                return Py::Tuple(0);
+//            }
+//            else if( name == "__module__"  )
+//            {
+//                return Py::Nothing();
+//            }
+//            else if( name == "__dict__"  )
+//            {
+//                return Py::Dict();
+//            }
+
+            return getattr_methods( _name );
+        }
+
+        // turn a name into function object
+        virtual Object getattr_methods( const char *_name )
+        {
+            std::string name( _name );
+            
+            method_map_t &mm = methods();
+            
+            if( name == "__methods__" )
+            {
+                List methods;
+                
+                for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
+                    methods.append( String( (*i).first ) );
+                
+                return methods;
+            }
+            
+            // see if name exists
+            if( mm.find( name ) == mm.end() )
+                throw AttributeError( name );
+            
+            Tuple self( 2 );
+            
+            self[0] = Object( this );
+            self[1] = String( name );
+            
+            MethodDefExt<T> *method_definition = mm[ name ];
+            
+            PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
+            
+            return Object(func, true);
+        }
+        
+        static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
+        {
+            method_map_t &mm = methods();
+            
+            MethodDefExt<T> *method_definition = new MethodDefExt<T>
+            (
+            name,
+            function,
+            method_varargs_call_handler,
+            doc
+            );
+            
+            mm[std::string( name )] = method_definition;
+        }
+        
+        static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
+        {
+            method_map_t &mm = methods();
+            
+            MethodDefExt<T> *method_definition = new MethodDefExt<T>
+            (
+            name,
+            function,
+            method_keyword_call_handler,
+            doc
+            );
+            
+            mm[std::string( name )] = method_definition;
+        }
+        
+    private:
+        static method_map_t &methods(void)
+        {
+            static method_map_t *map_of_methods = NULL;
+            if( map_of_methods == NULL )
+            map_of_methods = new method_map_t;
+            
+            return *map_of_methods;
+        }
+        
+        static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
+        {
+            try
+            {
+                Tuple self_and_name_tuple( _self_and_name_tuple );
+                
+                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
+                T *self = static_cast<T *>( self_in_cobject );
+                
+                String name( self_and_name_tuple[1] );
+                
+                method_map_t &mm = methods();
+                MethodDefExt<T> *meth_def = mm[ name ];
+                if( meth_def == NULL )
+                    return 0;
+                
+                Tuple args( _args );
+
+                // _keywords may be NULL so be careful about the way the dict is created
+                Dict keywords;
+                if( _keywords != NULL )
+                    keywords = Dict( _keywords );
+                
+                Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
+                
+                return new_reference_to( result.ptr() );
+            }
+            catch( Exception & )
+            {
+                return 0;
+            }
+        }
+        
+        static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
+        {
+            try
+            {
+                Tuple self_and_name_tuple( _self_and_name_tuple );
+                
+                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
+                T *self = static_cast<T *>( self_in_cobject );
+                
+                String name( self_and_name_tuple[1] );
+                
+                method_map_t &mm = methods();
+                MethodDefExt<T> *meth_def = mm[ name ];
+                if( meth_def == NULL )
+                    return 0;
+                
+                Tuple args( _args );
+                
+                Object result;
+                
+                // TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
+                #ifdef _STLP_DEBUG
+                try
+                {
+                    result = (self->*meth_def->ext_varargs_function)( args );
+                }
+                catch (std::__stl_debug_exception)
+                {
+                    // throw cxx::RuntimeError( sErrMsg );
+                    throw cxx::RuntimeError( "Error message not set yet." );
+                }
+                #else
+                result = (self->*meth_def->ext_varargs_function)( args );
+                #endif // _STLP_DEBUG
+                
+                return new_reference_to( result.ptr() );
+            }
+            catch( Exception & )
+            {
+                return 0;
+            }
+        }
+        
+        static void extension_object_deallocator ( PyObject* t )
+        {
+            delete (T *)( t );
+        }
+        
+        //
+        // prevent the compiler generating these unwanted functions
+        //
+        explicit PythonExtension( const PythonExtension<T>& other );
+        void operator=( const PythonExtension<T>& rhs );
+    };
+    
+    //
+    // ExtensionObject<T> is an Object that will accept only T's.
+    //
+    template<TEMPLATE_TYPENAME T>
+    class ExtensionObject: public Object
+    {
+    public:
+        
+        explicit ExtensionObject ( PyObject *pyob )
+            : Object( pyob )
+        {
+            validate();
+        }
+        
+        ExtensionObject( const ExtensionObject<T>& other )
+            : Object( *other )
+        {
+            validate();
+        }
+        
+        ExtensionObject( const Object& other )
+            : Object( *other )
+        {
+            validate();
+        }
+        
+        ExtensionObject& operator= ( const Object& rhs )
+        {
+            return (*this = *rhs );
+        }
+        
+        ExtensionObject& operator= ( PyObject* rhsp )
+        {
+            if( ptr() == rhsp )
+            return *this;
+            set( rhsp );
+            return *this;
+        }
+        
+        virtual bool accepts ( PyObject *pyob ) const
+        {
+            return ( pyob && T::check( pyob ));
+        }       
+        
+        //
+        //    Obtain a pointer to the PythonExtension object
+        //
+        T *extensionObject(void)
+        {
+            return static_cast<T *>( ptr() );
+        }
+    };
+    
+} // Namespace Py
+// End of CXX_Extensions.h
+#endif
diff --git a/src/extension/script/CXX/IndirectPythonInterface.cxx b/src/extension/script/CXX/IndirectPythonInterface.cxx
new file mode 100644 (file)
index 0000000..1ab83bd
--- /dev/null
@@ -0,0 +1,583 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#include "CXX/IndirectPythonInterface.hxx"
+
+namespace Py
+{
+bool _Buffer_Check( PyObject *op ) { return (op)->ob_type == _Buffer_Type(); }
+bool _CFunction_Check( PyObject *op ) { return (op)->ob_type == _CFunction_Type(); }
+bool _Class_Check( PyObject *op ) { return (op)->ob_type == _Class_Type(); }
+bool _CObject_Check( PyObject *op ) { return (op)->ob_type == _CObject_Type(); }
+bool _Complex_Check( PyObject *op ) { return (op)->ob_type == _Complex_Type(); }
+bool _Dict_Check( PyObject *op ) { return (op)->ob_type == _Dict_Type(); }
+bool _File_Check( PyObject *op ) { return (op)->ob_type == _File_Type(); }
+bool _Float_Check( PyObject *op ) { return (op)->ob_type == _Float_Type(); }
+bool _Function_Check( PyObject *op ) { return (op)->ob_type == _Function_Type(); }
+bool _Instance_Check( PyObject *op ) { return (op)->ob_type == _Instance_Type(); }
+bool _Int_Check( PyObject *op ) { return (op)->ob_type == _Int_Type(); }
+bool _List_Check( PyObject *o ) { return o->ob_type == _List_Type(); }
+bool _Long_Check( PyObject *op ) { return (op)->ob_type == _Long_Type(); }
+bool _Method_Check( PyObject *op ) { return (op)->ob_type == _Method_Type(); }
+bool _Module_Check( PyObject *op ) { return (op)->ob_type == _Module_Type(); }
+bool _Range_Check( PyObject *op ) { return (op)->ob_type == _Range_Type(); }
+bool _Slice_Check( PyObject *op ) { return (op)->ob_type == _Slice_Type(); }
+bool _String_Check( PyObject *o ) { return o->ob_type == _String_Type(); }
+bool _TraceBack_Check( PyObject *v ) { return (v)->ob_type == _TraceBack_Type(); }
+bool _Tuple_Check( PyObject *op ) { return (op)->ob_type == _Tuple_Type(); }
+bool _Type_Check( PyObject *op ) { return (op)->ob_type == _Type_Type(); }
+
+#if PY_MAJOR_VERSION >= 2
+bool _Unicode_Check( PyObject *op ) { return (op)->ob_type == _Unicode_Type(); }
+#endif
+
+
+
+#if defined(PY_WIN32_DELAYLOAD_PYTHON_DLL)
+
+#if defined(MS_WINDOWS)
+#include <windows.h>
+
+
+static HMODULE python_dll;
+
+static PyObject *ptr__Exc_ArithmeticError = NULL;
+static PyObject *ptr__Exc_AssertionError = NULL;
+static PyObject *ptr__Exc_AttributeError = NULL;
+static PyObject *ptr__Exc_EnvironmentError = NULL;
+static PyObject *ptr__Exc_EOFError = NULL;
+static PyObject *ptr__Exc_Exception = NULL;
+static PyObject *ptr__Exc_FloatingPointError = NULL;
+static PyObject *ptr__Exc_ImportError = NULL;
+static PyObject *ptr__Exc_IndexError = NULL;
+static PyObject *ptr__Exc_IOError = NULL;
+static PyObject *ptr__Exc_KeyboardInterrupt = NULL;
+static PyObject *ptr__Exc_KeyError = NULL;
+static PyObject *ptr__Exc_LookupError = NULL;
+static PyObject *ptr__Exc_MemoryError = NULL;
+static PyObject *ptr__Exc_MemoryErrorInst = NULL;
+static PyObject *ptr__Exc_NameError = NULL;
+static PyObject *ptr__Exc_NotImplementedError = NULL;
+static PyObject *ptr__Exc_OSError = NULL;
+static PyObject *ptr__Exc_OverflowError = NULL;
+static PyObject *ptr__Exc_RuntimeError = NULL;
+static PyObject *ptr__Exc_StandardError = NULL;
+static PyObject *ptr__Exc_SyntaxError = NULL;
+static PyObject *ptr__Exc_SystemError = NULL;
+static PyObject *ptr__Exc_SystemExit = NULL;
+static PyObject *ptr__Exc_TypeError = NULL;
+static PyObject *ptr__Exc_ValueError = NULL;
+static PyObject *ptr__Exc_ZeroDivisionError = NULL;
+
+#ifdef MS_WINDOWS
+static PyObject *ptr__Exc_WindowsError = NULL;
+#endif
+
+#if PY_MAJOR_VERSION >= 2
+static PyObject *ptr__Exc_IndentationError = NULL;
+static PyObject *ptr__Exc_TabError = NULL;
+static PyObject *ptr__Exc_UnboundLocalError = NULL;
+static PyObject *ptr__Exc_UnicodeError = NULL;
+#endif
+
+static PyObject *ptr__PyNone = NULL;
+
+static PyTypeObject *ptr__Buffer_Type = NULL;
+static PyTypeObject *ptr__CFunction_Type = NULL;
+static PyTypeObject *ptr__Class_Type = NULL;
+static PyTypeObject *ptr__CObject_Type = NULL;
+static PyTypeObject *ptr__Complex_Type = NULL;
+static PyTypeObject *ptr__Dict_Type = NULL;
+static PyTypeObject *ptr__File_Type = NULL;
+static PyTypeObject *ptr__Float_Type = NULL;
+static PyTypeObject *ptr__Function_Type = NULL;
+static PyTypeObject *ptr__Instance_Type = NULL;
+static PyTypeObject *ptr__Int_Type = NULL;
+static PyTypeObject *ptr__List_Type = NULL;
+static PyTypeObject *ptr__Long_Type = NULL;
+static PyTypeObject *ptr__Method_Type = NULL;
+static PyTypeObject *ptr__Module_Type = NULL;
+static PyTypeObject *ptr__Range_Type = NULL;
+static PyTypeObject *ptr__Slice_Type = NULL;
+static PyTypeObject *ptr__String_Type = NULL;
+static PyTypeObject *ptr__TraceBack_Type = NULL;
+static PyTypeObject *ptr__Tuple_Type = NULL;
+static PyTypeObject *ptr__Type_Type = NULL;
+
+#if PY_MAJOR_VERSION >= 2
+static PyTypeObject *ptr__Unicode_Type = NULL;
+#endif
+
+static int *ptr_Py_DebugFlag = NULL;
+static int *ptr_Py_InteractiveFlag = NULL;
+static int *ptr_Py_OptimizeFlag = NULL;
+static int *ptr_Py_NoSiteFlag = NULL;
+static int *ptr_Py_TabcheckFlag = NULL;
+static int *ptr_Py_VerboseFlag = NULL;
+
+#if PY_MAJOR_VERSION >= 2
+static int *ptr_Py_UnicodeFlag = NULL;
+#endif
+
+static char **ptr__Py_PackageContext = NULL;
+
+#ifdef Py_REF_DEBUG
+int *ptr_Py_RefTotal;
+#endif
+
+
+//--------------------------------------------------------------------------------
+class GetAddressException
+{
+public:
+    GetAddressException( const char *_name )
+        : name( _name )
+    {}
+    virtual ~GetAddressException() {}
+    const char *name;
+};
+
+
+//--------------------------------------------------------------------------------
+static PyObject *GetPyObjectPointer_As_PyObjectPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return *(PyObject **)addr;
+}
+
+static PyObject *GetPyObject_As_PyObjectPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return (PyObject *)addr;
+}
+
+static PyTypeObject *GetPyTypeObjectPointer_As_PyTypeObjectPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return *(PyTypeObject **)addr;
+}
+
+static PyTypeObject *GetPyTypeObject_As_PyTypeObjectPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return (PyTypeObject *)addr;
+}
+
+static int *GetInt_as_IntPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return (int *)addr;
+}
+
+static char **GetCharPointer_as_CharPointerPointer( const char *name )
+{
+    FARPROC addr = GetProcAddress( python_dll, name );
+    if( addr == NULL )
+        throw GetAddressException( name );
+
+    return (char **)addr;
+}
+
+
+#ifdef _DEBUG
+static const char python_dll_name_format[] = "PYTHON%1.1d%1.1d_D.DLL";
+#else
+static const char python_dll_name_format[] = "PYTHON%1.1d%1.1d.DLL";
+#endif
+
+//--------------------------------------------------------------------------------
+bool InitialisePythonIndirectInterface()
+{
+    char python_dll_name[sizeof(python_dll_name_format)];
+
+    sprintf( python_dll_name, python_dll_name_format, PY_MAJOR_VERSION, PY_MINOR_VERSION );
+
+    python_dll = LoadLibrary( python_dll_name );
+    if( python_dll == NULL )
+        return false;
+
+    try
+{
+#ifdef Py_REF_DEBUG
+    ptr_Py_RefTotal            = GetInt_as_IntPointer( "_Py_RefTotal" );
+#endif
+    ptr_Py_DebugFlag        = GetInt_as_IntPointer( "Py_DebugFlag" );
+    ptr_Py_InteractiveFlag        = GetInt_as_IntPointer( "Py_InteractiveFlag" );
+    ptr_Py_OptimizeFlag        = GetInt_as_IntPointer( "Py_OptimizeFlag" );
+    ptr_Py_NoSiteFlag        = GetInt_as_IntPointer( "Py_NoSiteFlag" );
+    ptr_Py_TabcheckFlag        = GetInt_as_IntPointer( "Py_TabcheckFlag" );
+    ptr_Py_VerboseFlag        = GetInt_as_IntPointer( "Py_VerboseFlag" );
+#if PY_MAJOR_VERSION >= 2
+    ptr_Py_UnicodeFlag        = GetInt_as_IntPointer( "Py_UnicodeFlag" );
+#endif
+    ptr__Py_PackageContext        = GetCharPointer_as_CharPointerPointer( "_Py_PackageContext" );
+
+    ptr__Exc_ArithmeticError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_ArithmeticError" );
+    ptr__Exc_AssertionError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_AssertionError" );
+    ptr__Exc_AttributeError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_AttributeError" );
+    ptr__Exc_EnvironmentError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_EnvironmentError" );
+    ptr__Exc_EOFError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_EOFError" );
+    ptr__Exc_Exception        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_Exception" );
+    ptr__Exc_FloatingPointError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_FloatingPointError" );
+    ptr__Exc_ImportError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_ImportError" );
+    ptr__Exc_IndexError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_IndexError" );
+    ptr__Exc_IOError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_IOError" );
+    ptr__Exc_KeyboardInterrupt    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_KeyboardInterrupt" );
+    ptr__Exc_KeyError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_KeyError" );
+    ptr__Exc_LookupError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_LookupError" );
+    ptr__Exc_MemoryError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_MemoryError" );
+    ptr__Exc_MemoryErrorInst    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_MemoryErrorInst" );
+    ptr__Exc_NameError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_NameError" );
+    ptr__Exc_NotImplementedError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_NotImplementedError" );
+    ptr__Exc_OSError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_OSError" );
+    ptr__Exc_OverflowError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_OverflowError" );
+    ptr__Exc_RuntimeError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_RuntimeError" );
+    ptr__Exc_StandardError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_StandardError" );
+    ptr__Exc_SyntaxError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_SyntaxError" );
+    ptr__Exc_SystemError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_SystemError" );
+    ptr__Exc_SystemExit        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_SystemExit" );
+    ptr__Exc_TypeError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_TypeError" );
+    ptr__Exc_ValueError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_ValueError" );
+#ifdef MS_WINDOWS
+    ptr__Exc_WindowsError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_WindowsError" );
+#endif
+    ptr__Exc_ZeroDivisionError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_ZeroDivisionError" );
+
+#if PY_MAJOR_VERSION >= 2
+    ptr__Exc_IndentationError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_IndentationError" );
+    ptr__Exc_TabError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_TabError" );
+    ptr__Exc_UnboundLocalError    = GetPyObjectPointer_As_PyObjectPointer( "PyExc_UnboundLocalError" );
+    ptr__Exc_UnicodeError        = GetPyObjectPointer_As_PyObjectPointer( "PyExc_UnicodeError" );
+#endif
+    ptr__PyNone            = GetPyObject_As_PyObjectPointer( "_Py_NoneStruct" );
+
+    ptr__Buffer_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyBuffer_Type" );
+    ptr__CFunction_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyCFunction_Type" );
+    ptr__Class_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyClass_Type" );
+    ptr__CObject_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyCObject_Type" );
+    ptr__Complex_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyComplex_Type" );
+    ptr__Dict_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyDict_Type" );
+    ptr__File_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyFile_Type" );
+    ptr__Float_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyFloat_Type" );
+    ptr__Function_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyFunction_Type" );
+    ptr__Instance_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyInstance_Type" );
+    ptr__Int_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyInt_Type" );
+    ptr__List_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyList_Type" );
+    ptr__Long_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyLong_Type" );
+    ptr__Method_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyMethod_Type" );
+    ptr__Module_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyModule_Type" );
+    ptr__Range_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyRange_Type" );
+    ptr__Slice_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PySlice_Type" );
+    ptr__String_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyString_Type" );
+    ptr__TraceBack_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyTraceBack_Type" );
+    ptr__Tuple_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyTuple_Type" );
+    ptr__Type_Type            = GetPyTypeObject_As_PyTypeObjectPointer( "PyType_Type" );
+
+#if PY_MAJOR_VERSION >= 2
+    ptr__Unicode_Type        = GetPyTypeObject_As_PyTypeObjectPointer( "PyUnicode_Type" );
+#endif
+}
+    catch( GetAddressException &e )
+    {
+        OutputDebugString( python_dll_name );
+        OutputDebugString( " does not contain symbol ");
+        OutputDebugString( e.name );
+        OutputDebugString( "\n" );
+
+        return false;
+    }
+
+    return true;
+}
+
+//
+//    Wrap variables as function calls
+//
+PyObject * _Exc_ArithmeticError(){ return ptr__Exc_ArithmeticError; }
+PyObject * _Exc_AssertionError(){ return ptr__Exc_AssertionError; }
+PyObject * _Exc_AttributeError(){ return ptr__Exc_AttributeError; }
+PyObject * _Exc_EnvironmentError(){ return ptr__Exc_EnvironmentError; }
+PyObject * _Exc_EOFError()    { return ptr__Exc_EOFError; }
+PyObject * _Exc_Exception()    { return ptr__Exc_Exception; }
+PyObject * _Exc_FloatingPointError(){ return ptr__Exc_FloatingPointError; }
+PyObject * _Exc_ImportError()    { return ptr__Exc_ImportError; }
+PyObject * _Exc_IndexError()    { return ptr__Exc_IndexError; }
+PyObject * _Exc_IOError()    { return ptr__Exc_IOError; }
+PyObject * _Exc_KeyboardInterrupt(){ return ptr__Exc_KeyboardInterrupt; }
+PyObject * _Exc_KeyError()    { return ptr__Exc_KeyError; }
+PyObject * _Exc_LookupError()    { return ptr__Exc_LookupError; }
+PyObject * _Exc_MemoryError()    { return ptr__Exc_MemoryError; }
+PyObject * _Exc_MemoryErrorInst(){ return ptr__Exc_MemoryErrorInst; }
+PyObject * _Exc_NameError()    { return ptr__Exc_NameError; }
+PyObject * _Exc_NotImplementedError(){ return ptr__Exc_NotImplementedError; }
+PyObject * _Exc_OSError()    { return ptr__Exc_OSError; }
+PyObject * _Exc_OverflowError()    { return ptr__Exc_OverflowError; }
+PyObject * _Exc_RuntimeError()    { return ptr__Exc_RuntimeError; }
+PyObject * _Exc_StandardError()    { return ptr__Exc_StandardError; }
+PyObject * _Exc_SyntaxError()    { return ptr__Exc_SyntaxError; }
+PyObject * _Exc_SystemError()    { return ptr__Exc_SystemError; }
+PyObject * _Exc_SystemExit()    { return ptr__Exc_SystemExit; }
+PyObject * _Exc_TypeError()    { return ptr__Exc_TypeError; }
+PyObject * _Exc_ValueError()    { return ptr__Exc_ValueError; }
+#ifdef MS_WINDOWS
+PyObject * _Exc_WindowsError()    { return ptr__Exc_WindowsError; }
+#endif
+PyObject * _Exc_ZeroDivisionError(){ return ptr__Exc_ZeroDivisionError; }
+
+#if PY_MAJOR_VERSION >= 2
+PyObject * _Exc_IndentationError(){ return ptr__Exc_IndentationError; }
+PyObject * _Exc_TabError()    { return ptr__Exc_TabError; }
+PyObject * _Exc_UnboundLocalError(){ return ptr__Exc_UnboundLocalError; }
+PyObject * _Exc_UnicodeError()    { return ptr__Exc_UnicodeError; }
+#endif
+
+//
+//    wrap items in Object.h
+//
+PyObject * _None() { return ptr__PyNone; }
+
+
+PyTypeObject * _Buffer_Type()    { return ptr__Buffer_Type; }
+PyTypeObject * _CFunction_Type(){ return ptr__CFunction_Type; }
+PyTypeObject * _Class_Type()    { return ptr__Class_Type; }
+PyTypeObject * _CObject_Type()    { return ptr__CObject_Type; }
+PyTypeObject * _Complex_Type()    { return ptr__Complex_Type; }
+PyTypeObject * _Dict_Type()    { return ptr__Dict_Type; }
+PyTypeObject * _File_Type()    { return ptr__File_Type; }
+PyTypeObject * _Float_Type()    { return ptr__Float_Type; }
+PyTypeObject * _Function_Type()    { return ptr__Function_Type; }
+PyTypeObject * _Instance_Type()    { return ptr__Instance_Type; }
+PyTypeObject * _Int_Type()    { return ptr__Int_Type; }
+PyTypeObject * _List_Type()    { return ptr__List_Type; }
+PyTypeObject * _Long_Type()    { return ptr__Long_Type; }
+PyTypeObject * _Method_Type()    { return ptr__Method_Type; }
+PyTypeObject * _Module_Type()    { return ptr__Module_Type; }
+PyTypeObject * _Range_Type()    { return ptr__Range_Type; }
+PyTypeObject * _Slice_Type()    { return ptr__Slice_Type; }
+PyTypeObject * _String_Type()    { return ptr__String_Type; }
+PyTypeObject * _TraceBack_Type(){ return ptr__TraceBack_Type; }
+PyTypeObject * _Tuple_Type()    { return ptr__Tuple_Type; }
+PyTypeObject * _Type_Type()    { return ptr__Type_Type; }
+
+#if PY_MAJOR_VERSION >= 2
+PyTypeObject * _Unicode_Type()    { return ptr__Unicode_Type; }
+#endif
+
+char *__Py_PackageContext()    { return *ptr__Py_PackageContext; }
+
+
+//
+//    wrap the Python Flag variables
+//
+int &_Py_DebugFlag() { return *ptr_Py_DebugFlag; }
+int &_Py_InteractiveFlag() { return *ptr_Py_InteractiveFlag; }
+int &_Py_OptimizeFlag() { return *ptr_Py_OptimizeFlag; }
+int &_Py_NoSiteFlag() { return *ptr_Py_NoSiteFlag; }
+int &_Py_TabcheckFlag() { return *ptr_Py_TabcheckFlag; }
+int &_Py_VerboseFlag() { return *ptr_Py_VerboseFlag; }
+#if PY_MAJOR_VERSION >= 2
+int &_Py_UnicodeFlag() { return *ptr_Py_UnicodeFlag; }
+#endif
+
+void _XINCREF( PyObject *op )
+{
+    // This function must match the contents of Py_XINCREF(op)
+    if( op == NULL )
+        return;
+
+#ifdef Py_REF_DEBUG
+    (*ptr_Py_RefTotal)++;
+#endif
+    (op)->ob_refcnt++;
+
+}
+
+void _XDECREF( PyObject *op )
+{
+    // This function must match the contents of Py_XDECREF(op);
+    if( op == NULL )
+        return;
+
+#ifdef Py_REF_DEBUG
+    (*ptr_Py_RefTotal)--;
+#endif
+
+    if (--(op)->ob_refcnt == 0)
+        _Py_Dealloc((PyObject *)(op));
+}
+
+
+#else
+#error "Can only delay load under Win32"
+#endif
+
+#else
+
+//
+//    Duplicated these declarations from rangeobject.h which is missing the
+//    extern "C". This has been reported as a bug upto and include 2.1
+//
+extern "C" DL_IMPORT(PyTypeObject) PyRange_Type;
+extern "C" DL_IMPORT(PyObject *) PyRange_New(long, long, long, int);
+
+
+//================================================================================
+//
+//    Map onto Macros
+//
+//================================================================================
+
+//
+//    Wrap variables as function calls
+//
+
+PyObject * _Exc_ArithmeticError() { return ::PyExc_ArithmeticError; }
+PyObject * _Exc_AssertionError() { return ::PyExc_AssertionError; }
+PyObject * _Exc_AttributeError() { return ::PyExc_AttributeError; }
+PyObject * _Exc_EnvironmentError() { return ::PyExc_EnvironmentError; }
+PyObject * _Exc_EOFError() { return ::PyExc_EOFError; }
+PyObject * _Exc_Exception() { return ::PyExc_Exception; }
+PyObject * _Exc_FloatingPointError() { return ::PyExc_FloatingPointError; }
+PyObject * _Exc_ImportError() { return ::PyExc_ImportError; }
+PyObject * _Exc_IndexError() { return ::PyExc_IndexError; }
+PyObject * _Exc_IOError() { return ::PyExc_IOError; }
+PyObject * _Exc_KeyboardInterrupt() { return ::PyExc_KeyboardInterrupt; }
+PyObject * _Exc_KeyError() { return ::PyExc_KeyError; }
+PyObject * _Exc_LookupError() { return ::PyExc_LookupError; }
+PyObject * _Exc_MemoryError() { return ::PyExc_MemoryError; }
+PyObject * _Exc_MemoryErrorInst() { return ::PyExc_MemoryErrorInst; }
+PyObject * _Exc_NameError() { return ::PyExc_NameError; }
+PyObject * _Exc_NotImplementedError() { return ::PyExc_NotImplementedError; }
+PyObject * _Exc_OSError() { return ::PyExc_OSError; }
+PyObject * _Exc_OverflowError() { return ::PyExc_OverflowError; }
+PyObject * _Exc_RuntimeError() { return ::PyExc_RuntimeError; }
+PyObject * _Exc_StandardError() { return ::PyExc_StandardError; }
+PyObject * _Exc_SyntaxError() { return ::PyExc_SyntaxError; }
+PyObject * _Exc_SystemError() { return ::PyExc_SystemError; }
+PyObject * _Exc_SystemExit() { return ::PyExc_SystemExit; }
+PyObject * _Exc_TypeError() { return ::PyExc_TypeError; }
+PyObject * _Exc_ValueError() { return ::PyExc_ValueError; }
+PyObject * _Exc_ZeroDivisionError() { return ::PyExc_ZeroDivisionError; }
+
+#ifdef MS_WINDOWS
+PyObject * _Exc_WindowsError() { return ::PyExc_WindowsError; }
+#endif
+
+
+#if PY_MAJOR_VERSION >= 2
+PyObject * _Exc_IndentationError() { return ::PyExc_IndentationError; }
+PyObject * _Exc_TabError() { return ::PyExc_TabError; }
+PyObject * _Exc_UnboundLocalError() { return ::PyExc_UnboundLocalError; }
+PyObject * _Exc_UnicodeError() { return ::PyExc_UnicodeError; }
+#endif
+
+
+//
+//    wrap items in Object.h
+//
+PyObject * _None() { return &::_Py_NoneStruct; }
+
+PyTypeObject * _Buffer_Type() { return &PyBuffer_Type; }
+PyTypeObject * _CFunction_Type() { return &PyCFunction_Type; }
+PyTypeObject * _Class_Type() { return &PyClass_Type; }
+PyTypeObject * _CObject_Type() { return &PyCObject_Type; }
+PyTypeObject * _Complex_Type() { return &PyComplex_Type; }
+PyTypeObject * _Dict_Type() { return &PyDict_Type; }
+PyTypeObject * _File_Type() { return &PyFile_Type; }
+PyTypeObject * _Float_Type() { return &PyFloat_Type; }
+PyTypeObject * _Function_Type() { return &PyFunction_Type; }
+PyTypeObject * _Instance_Type() { return &PyInstance_Type; }
+PyTypeObject * _Int_Type() { return &PyInt_Type; }
+PyTypeObject * _List_Type() { return &PyList_Type; }
+PyTypeObject * _Long_Type() { return &PyLong_Type; }
+PyTypeObject * _Method_Type() { return &PyMethod_Type; }
+PyTypeObject * _Module_Type() { return &PyModule_Type; }
+PyTypeObject * _Range_Type() { return &PyRange_Type; }
+PyTypeObject * _Slice_Type() { return &PySlice_Type; }
+PyTypeObject * _String_Type() { return &PyString_Type; }
+PyTypeObject * _TraceBack_Type() { return &PyTraceBack_Type; }
+PyTypeObject * _Tuple_Type() { return &PyTuple_Type; }
+PyTypeObject * _Type_Type() { return &PyType_Type; }
+
+#if PY_MAJOR_VERSION >= 2
+PyTypeObject * _Unicode_Type() { return &PyUnicode_Type; }
+#endif
+
+//
+//    wrap flags
+//
+int &_Py_DebugFlag()    { return Py_DebugFlag; }
+int &_Py_InteractiveFlag(){ return Py_InteractiveFlag; }
+int &_Py_OptimizeFlag()    { return Py_OptimizeFlag; }
+int &_Py_NoSiteFlag()    { return Py_NoSiteFlag; }
+int &_Py_TabcheckFlag()    { return Py_TabcheckFlag; }
+int &_Py_VerboseFlag()    { return Py_VerboseFlag; }
+#if PY_MAJOR_VERSION >= 2
+int &_Py_UnicodeFlag()    { return Py_UnicodeFlag; }
+#endif
+char *__Py_PackageContext(){ return _Py_PackageContext; }
+
+//
+//    Needed to keep the abstactions for delayload interface
+//
+void _XINCREF( PyObject *op )
+{
+    Py_XINCREF(op);
+}
+
+void _XDECREF( PyObject *op )
+{
+    Py_XDECREF(op);
+}
+
+#endif
+}
diff --git a/src/extension/script/CXX/IndirectPythonInterface.hxx b/src/extension/script/CXX/IndirectPythonInterface.hxx
new file mode 100644 (file)
index 0000000..e8fccf5
--- /dev/null
@@ -0,0 +1,193 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
+#define __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
+
+#include "CXX/WrapPython.h"
+
+namespace Py
+{
+bool InitialisePythonIndirectInterface();
+
+//
+//    Wrap Exception variables as function calls
+//
+PyObject * _Exc_Exception();
+PyObject * _Exc_StandardError();
+PyObject * _Exc_ArithmeticError();
+PyObject * _Exc_LookupError();
+
+PyObject * _Exc_AssertionError();
+PyObject * _Exc_AttributeError();
+PyObject * _Exc_EOFError();
+PyObject * _Exc_FloatingPointError();
+PyObject * _Exc_EnvironmentError();
+PyObject * _Exc_IOError();
+PyObject * _Exc_OSError();
+PyObject * _Exc_ImportError();
+PyObject * _Exc_IndexError();
+PyObject * _Exc_KeyError();
+PyObject * _Exc_KeyboardInterrupt();
+PyObject * _Exc_MemoryError();
+PyObject * _Exc_NameError();
+PyObject * _Exc_OverflowError();
+PyObject * _Exc_RuntimeError();
+PyObject * _Exc_NotImplementedError();
+PyObject * _Exc_SyntaxError();
+PyObject * _Exc_SystemError();
+PyObject * _Exc_SystemExit();
+PyObject * _Exc_TypeError();
+PyObject * _Exc_ValueError();
+PyObject * _Exc_ZeroDivisionError();
+#ifdef MS_WINDOWS
+PyObject * _Exc_WindowsError();
+#endif
+
+PyObject * _Exc_MemoryErrorInst();
+
+#if PY_MAJOR_VERSION >= 2
+PyObject * _Exc_IndentationError();
+PyObject * _Exc_TabError();
+PyObject * _Exc_UnboundLocalError();
+PyObject * _Exc_UnicodeError();
+#endif
+
+//
+//    Wrap Object variables as function calls
+//
+PyObject * _None();
+
+
+//
+//    Wrap Type variables as function calls
+//
+PyTypeObject * _List_Type();
+bool _List_Check( PyObject *o );
+
+PyTypeObject * _Buffer_Type();
+bool _Buffer_Check( PyObject *op );
+
+PyTypeObject * _Class_Type();
+bool _Class_Check( PyObject *op );
+
+PyTypeObject * _Instance_Type();
+bool _Instance_Check( PyObject *op );
+
+PyTypeObject * _Method_Type();
+bool _Method_Check( PyObject *op );
+
+PyTypeObject * _CObject_Type();
+bool _CObject_Check( PyObject *op );
+
+PyTypeObject * _Complex_Type();
+bool _Complex_Check( PyObject *op );
+
+PyTypeObject * _Dict_Type();
+bool _Dict_Check( PyObject *op );
+
+PyTypeObject * _File_Type();
+bool _File_Check( PyObject *op );
+
+PyTypeObject * _Float_Type();
+bool _Float_Check( PyObject *op );
+
+PyTypeObject * _Frame_Type();
+bool _Frame_Check( PyObject *op );
+
+PyTypeObject * _Function_Type();
+bool _Function_Check( PyObject *op );
+
+PyTypeObject * _Int_Type();
+bool _Int_Check( PyObject *op );
+
+PyTypeObject * _List_Type();
+bool _List_Check( PyObject *op );
+
+PyTypeObject * _Long_Type();
+bool _Long_Check( PyObject *op );
+
+PyTypeObject * _CFunction_Type();
+bool _CFunction_Check( PyObject *op );
+
+PyTypeObject * _Module_Type();
+bool _Module_Check( PyObject *op );
+
+PyTypeObject * _Type_Type();
+bool _Type_Check( PyObject *op );
+
+PyTypeObject * _Range_Type();
+bool _Range_Check( PyObject *op );
+
+PyTypeObject * _Slice_Type();
+bool _Slice_Check( PyObject *op );
+
+PyTypeObject * _String_Type();
+bool _String_Check( PyObject *op );
+
+PyTypeObject * _Unicode_Type();
+bool _Unicode_Check( PyObject *op );
+
+PyTypeObject * _TraceBack_Type();
+bool _TraceBack_Check( PyObject *v );
+
+PyTypeObject * _Tuple_Type();
+bool _Tuple_Check( PyObject *op );
+
+#if PY_MAJOR_VERSION >= 2
+PyTypeObject * _Unicode_Type();
+bool _Unicode_Check( PyObject *op );
+#endif
+
+int &_Py_DebugFlag();
+int &_Py_InteractiveFlag();
+int &_Py_OptimizeFlag();
+int &_Py_NoSiteFlag();
+int &_Py_TabcheckFlag();
+int &_Py_VerboseFlag();
+
+#if PY_MAJOR_VERSION >= 2
+int &_Py_UnicodeFlag();
+#endif
+
+void _XINCREF( PyObject *op );
+void _XDECREF( PyObject *op );
+
+char *__Py_PackageContext();
+};
+
+#endif    // __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
diff --git a/src/extension/script/CXX/Objects.hxx b/src/extension/script/CXX/Objects.hxx
new file mode 100644 (file)
index 0000000..30dc085
--- /dev/null
@@ -0,0 +1,3019 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __CXX_Objects__h
+#define __CXX_Objects__h
+
+#include "CXX/WrapPython.h"
+#include "CXX/Version.hxx"
+#include "CXX/Config.hxx"
+#include "CXX/Exception.hxx"
+
+#include <iostream>
+#include STR_STREAM
+#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<TEMPLATE_TYPENAME T> class SeqBase;
+    class String;
+    class List;
+    template<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 ) || defined(__GNUG__)
+                std::string s("CXX : 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);
+        }
+
+        Py_ssize_t 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 isNone() const
+        {
+            return p == Py_None;
+        }
+
+        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
+        Int (PyObject *pyob, bool owned = false): Object (pyob, owned)
+        {
+            validate();
+        }
+
+        Int (const Int& ob): Object(*ob)
+        {
+            validate();
+        }
+
+        // create from long
+        Int (long v = 0L): Object(PyInt_FromLong(v), true)
+        {
+            validate();
+        }
+
+#ifdef HAVE_LONG_LONG
+        // create from long long
+        Int (PY_LONG_LONG v): Object(PyLong_FromLongLong(v), true)
+        {
+            validate();
+        }
+        // create from unsigned long long
+        Int (unsigned PY_LONG_LONG v): Object(PyLong_FromUnsignedLongLong(v), true)
+        {
+            validate();
+        }
+#endif
+
+        // create from int
+        Int (int v)
+        {
+            long w = v;
+            set(PyInt_FromLong(w), true);
+            validate();
+        }
+
+        // create from bool
+        Int (bool v)
+        {
+            long w = v ? 1 : 0;
+            set(PyInt_FromLong(w), true);
+            validate();
+        }
+
+        explicit 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());
+        }
+
+#ifdef HAVE_LONG_LONG
+        // convert to long long
+        PY_LONG_LONG asLongLong() const
+        {
+            return PyLong_AsLongLong (ptr());
+        }
+        // convert to unsigned long long
+        unsigned PY_LONG_LONG asUnsignedLongLong() const
+        {
+            return PyLong_AsUnsignedLongLong (ptr());
+        }
+#endif
+
+        // 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;
+        }
+
+#ifdef HAVE_LONG_LONG
+        // assign from long long
+        Int& operator= (PY_LONG_LONG v)
+        {
+            set (PyLong_FromLongLong (v), true);
+            return *this;
+        }
+        // assign from unsigned long long
+        Int& operator= (unsigned PY_LONG_LONG v)
+        {
+            set (PyLong_FromUnsignedLongLong (v), true);
+            return *this;
+        }
+#endif
+    };
+
+    // ===============================================
+    // 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 unsigned long
+        explicit Long (unsigned long v)
+            : Object(PyLong_FromUnsignedLong(v), true)
+        {
+            validate();
+        }
+        // create from int
+        explicit Long (int v)
+            : Object(PyLong_FromLong(static_cast<long>(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());
+        }
+        // convert to unsigned
+        operator unsigned long() const
+        {
+            return PyLong_AsUnsignedLong (ptr());
+        }
+        operator double() const
+        {
+            return PyLong_AsDouble (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;
+        }
+    };
+
+#ifdef HAVE_LONG_LONG
+    // ===============================================
+    // class LongLong
+    class LongLong: public Object
+    {
+    public:
+        // Constructor
+        explicit LongLong (PyObject *pyob, bool owned = false): Object (pyob, owned)
+        {
+            validate();
+        }
+
+        LongLong (const LongLong& ob): Object(ob.ptr())
+        {
+            validate();
+        }
+        // create from long long
+        explicit LongLong (long long v = 0L)
+            : Object(PyLong_FromLongLong(v), true)
+        {
+            validate();
+        }
+        // create from unsigned long long
+        explicit LongLong (unsigned long long v)
+            : Object(PyLong_FromUnsignedLongLong(v), true)
+        {
+            validate();
+        }
+        // create from long
+        explicit LongLong (long v)
+            : Object(PyLong_FromLongLong(v), true)
+        {
+            validate();
+        }
+        // create from unsigned long
+        explicit LongLong (unsigned long v)
+            : Object(PyLong_FromUnsignedLongLong(v), true)
+        {
+            validate();
+        }
+        // create from int
+        explicit LongLong (int v)
+            : Object(PyLong_FromLongLong(static_cast<long long>(v)), true)
+        {
+            validate();
+        }
+
+        // try to create from any object
+        LongLong (const Object& ob)
+            : Object(PyNumber_Long(*ob), true)
+        {
+            validate();
+        }
+
+        // Assignment acquires new ownership of pointer
+
+        LongLong& operator= (const Object& rhs)
+        {
+            return (*this = *rhs);
+        }
+
+        LongLong& 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 long
+        operator long long() const
+        {
+            return PyLong_AsLongLong (ptr());
+        }
+        // convert to unsigned long
+        operator unsigned long long() const
+        {
+            return PyLong_AsUnsignedLongLong (ptr());
+        }
+        // convert to long
+        operator long() const
+        {
+            return PyLong_AsLong (ptr());
+        }
+        // convert to unsigned
+        operator unsigned long() const
+        {
+            return PyLong_AsUnsignedLong (ptr());
+        }
+        operator double() const
+        {
+            return PyLong_AsDouble (ptr());
+        }
+        // assign from an int
+        LongLong& operator= (int v)
+        {
+            set(PyLong_FromLongLong (long(v)), true);
+            return *this;
+        }
+        // assign from long long
+        LongLong& operator= (long long v)
+        {
+            set(PyLong_FromLongLong (v), true);
+            return *this;
+        }
+        // assign from unsigned long long
+        LongLong& operator= (unsigned long long v)
+        {
+            set(PyLong_FromUnsignedLongLong (v), true);
+            return *this;
+        }
+        // assign from long
+        LongLong& operator= (long v)
+        {
+            set(PyLong_FromLongLong (v), true);
+            return *this;
+        }
+        // assign from unsigned long
+        LongLong& operator= (unsigned long v)
+        {
+            set(PyLong_FromUnsignedLongLong (v), true);
+            return *this;
+        }
+    };
+#endif
+
+    // ===============================================
+    // 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<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<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::OSTRSTREAM 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 <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
+
+    template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_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 = (int)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<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);
+        }
+
+        virtual ~mapref<T>()
+        {}
+
+        // 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 isInstance () const
+        {
+            return the_item.isInstance();
+        }
+
+        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<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::OSTRSTREAM 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 <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
+    template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_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
+    {
+    public:
+        // Constructor
+        explicit Callable (): Object()  {}
+        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;
+        if(ptype) 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<TEMPLATE_TYPENAME T>
+String seqref<T>::str () const
+{
+    return the_item.str();
+}
+
+template<TEMPLATE_TYPENAME T>
+String seqref<T>::repr () const
+{
+    return the_item.repr();
+}
+
+} // namespace Py
+#endif    // __CXX_Objects__h
diff --git a/src/extension/script/CXX/Version.hxx b/src/extension/script/CXX/Version.hxx
new file mode 100644 (file)
index 0000000..8286e2f
--- /dev/null
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __PyCXX_version_hxx__
+#define __PyCXX_version_hxx__
+
+#define PYCXX_VERSION_MAJOR 5
+#define PYCXX_VERSION_MINOR 4
+#define PYCXX_VERSION_PATCH 0
+#define PYCXX_MAKEVERSION( major, minor, patch ) ((major<<16)|(minor<<8)|(patch))
+#define PYCXX_VERSION PYCXX_MAKEVERSION( PYCXX_VERSION_MAJOR, PYCXX_VERSION_MINOR, PYCXX_VERSION_PATCH )
+#endif
diff --git a/src/extension/script/CXX/WrapPython.h b/src/extension/script/CXX/WrapPython.h
new file mode 100644 (file)
index 0000000..51b9391
--- /dev/null
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __PyCXX_wrap_python_hxx__
+#define __PyCXX_wrap_python_hxx__
+
+// On some platforms we have to include time.h to get select defined
+#if !defined(__WIN32__) && !defined(WIN32) && !defined(_WIN32) && !defined(_WIN64)
+#include <sys/time.h>
+#endif
+
+// pull in python definitions
+#include <Python.h>
+
+#endif
diff --git a/src/extension/script/CXX/cxx_extensions.cxx b/src/extension/script/CXX/cxx_extensions.cxx
new file mode 100644 (file)
index 0000000..102dc26
--- /dev/null
@@ -0,0 +1,1400 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+#include "CXX/Extensions.hxx"
+#include "CXX/Exception.hxx"
+
+#include <assert.h>
+
+namespace Py 
+{
+//================================================================================
+//
+//    Implementation of MethodTable
+//
+//================================================================================
+
+PyMethodDef MethodTable::method( const char* method_name, PyCFunction f, int flags, const char* doc ) 
+{
+    PyMethodDef m;
+    m.ml_name = const_cast<char*>( method_name );
+    m.ml_meth = f;
+    m.ml_flags = flags;
+    m.ml_doc = const_cast<char*>( doc );
+    return m;
+}
+
+MethodTable::MethodTable()
+{
+    t.push_back( method( 0, 0, 0, 0 ) );
+    mt = 0;
+}
+
+MethodTable::~MethodTable()
+{
+    delete [] mt;
+}
+
+void MethodTable::add( const char* method_name, PyCFunction f, const char* doc, int flag )
+{
+    if( !mt )
+    {
+        t.insert( t.end()-1, method( method_name, f, flag, doc ) );
+    }
+    else
+    {
+        throw RuntimeError( "Too late to add a module method!" );
+    }
+}
+
+PyMethodDef* MethodTable::table()
+{    
+    if( !mt )
+    {
+        Py_ssize_t t1size = t.size();
+        mt = new PyMethodDef[t1size];
+        int j = 0;
+        for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
+        {
+            mt[j++] = *i;
+        }
+    }
+    return mt;
+}
+
+//================================================================================
+//
+//    Implementation of ExtensionModule
+//
+//================================================================================
+ExtensionModuleBase::ExtensionModuleBase( const char *name )
+    : module_name( name )
+    , full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : module_name )
+    , method_table()
+{}
+
+ExtensionModuleBase::~ExtensionModuleBase()
+{}
+
+const std::string &ExtensionModuleBase::name() const
+{
+    return module_name;
+}
+
+const std::string &ExtensionModuleBase::fullName() const
+{
+    return full_module_name;
+}
+
+class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
+{
+public:
+    ExtensionModuleBasePtr( ExtensionModuleBase *_module )
+        : module( _module )
+    {}
+    virtual ~ExtensionModuleBasePtr()
+    {}
+
+    ExtensionModuleBase *module;
+};
+
+
+void ExtensionModuleBase::initialize( const char *module_doc )
+{
+    PyObject *module_ptr = new ExtensionModuleBasePtr( this );
+
+    Py_InitModule4
+    (
+    const_cast<char *>( module_name.c_str() ),    // name
+    method_table.table(),                // methods
+    const_cast<char *>( module_doc ),        // docs
+    module_ptr,                    // pass to functions as "self"
+    PYTHON_API_VERSION                // API version
+    );
+}
+
+Py::Module ExtensionModuleBase::module(void) const
+{
+    return Module( full_module_name );
+}
+
+Py::Dict ExtensionModuleBase::moduleDictionary(void) const
+{
+    return module().getDict();
+}
+
+//--------------------------------------------------------------------------------
+
+//================================================================================
+//
+//    Implementation of PythonType
+//
+//================================================================================
+
+extern "C"
+{
+    static void standard_dealloc(PyObject* p);
+    //
+    // All the following functions redirect the call from Python
+    // onto the matching virtual function in PythonExtensionBase
+    //
+    static int print_handler (PyObject*, FILE *, int);
+    static PyObject* getattr_handler (PyObject*, char*);
+    static int setattr_handler (PyObject*, char*, PyObject*);
+    static PyObject* getattro_handler (PyObject*, PyObject*);
+    static int setattro_handler (PyObject*, PyObject*, PyObject*);
+    static int compare_handler (PyObject*, PyObject*);
+    static PyObject* repr_handler (PyObject*);
+    static PyObject* str_handler (PyObject*);
+    static long hash_handler (PyObject*);
+    static PyObject* call_handler (PyObject*, PyObject*, PyObject*);
+    static PyObject* iter_handler (PyObject*);
+    static PyObject* iternext_handler (PyObject*);
+
+    // Sequence methods
+    static Py_ssize_t sequence_length_handler(PyObject*);
+    static PyObject* sequence_concat_handler(PyObject*,PyObject*);
+    static PyObject* sequence_repeat_handler(PyObject*, Py_ssize_t);
+    static PyObject* sequence_item_handler(PyObject*, Py_ssize_t);
+    static PyObject* sequence_slice_handler(PyObject*, Py_ssize_t, Py_ssize_t);
+    static int sequence_ass_item_handler(PyObject*, Py_ssize_t, PyObject*);
+    static int sequence_ass_slice_handler(PyObject*, Py_ssize_t, Py_ssize_t, PyObject*);
+    // Mapping
+    static Py_ssize_t mapping_length_handler(PyObject*);
+    static PyObject* mapping_subscript_handler(PyObject*, PyObject*);
+    static int mapping_ass_subscript_handler(PyObject*, PyObject*, PyObject*);
+
+    // Numeric methods
+    static int number_nonzero_handler (PyObject*);
+    static PyObject* number_negative_handler (PyObject*);
+    static PyObject* number_positive_handler (PyObject*);
+    static PyObject* number_absolute_handler (PyObject*);
+    static PyObject* number_invert_handler (PyObject*);
+    static PyObject* number_int_handler (PyObject*);
+    static PyObject* number_float_handler (PyObject*);
+    static PyObject* number_long_handler (PyObject*);
+    static PyObject* number_oct_handler (PyObject*);
+    static PyObject* number_hex_handler (PyObject*);
+    static PyObject* number_add_handler (PyObject*, PyObject*);
+    static PyObject* number_subtract_handler (PyObject*, PyObject*);
+    static PyObject* number_multiply_handler (PyObject*, PyObject*);
+    static PyObject* number_divide_handler (PyObject*, PyObject*);
+    static PyObject* number_remainder_handler (PyObject*, PyObject*);
+    static PyObject* number_divmod_handler (PyObject*, PyObject*);
+    static PyObject* number_lshift_handler (PyObject*, PyObject*);
+    static PyObject* number_rshift_handler (PyObject*, PyObject*);
+    static PyObject* number_and_handler (PyObject*, PyObject*);
+    static PyObject* number_xor_handler (PyObject*, PyObject*);
+    static PyObject* number_or_handler (PyObject*, PyObject*);
+    static PyObject* number_power_handler(PyObject*, PyObject*, PyObject*);
+
+    // Buffer
+    static Py_ssize_t buffer_getreadbuffer_handler (PyObject*, Py_ssize_t, void**);
+    static Py_ssize_t buffer_getwritebuffer_handler (PyObject*, Py_ssize_t, void**);
+    static Py_ssize_t buffer_getsegcount_handler (PyObject*, Py_ssize_t*);
+}
+
+
+extern "C" void standard_dealloc( PyObject* p )
+{
+    PyMem_DEL( p );
+}
+
+PythonType & PythonType::supportSequenceType()
+{
+    if( !sequence_table )
+    {
+        sequence_table = new PySequenceMethods;
+        memset( sequence_table, 0, sizeof( PySequenceMethods ) );   // ensure new fields are 0
+        table->tp_as_sequence = sequence_table;
+        sequence_table->sq_length = sequence_length_handler;
+        sequence_table->sq_concat = sequence_concat_handler;
+        sequence_table->sq_repeat = sequence_repeat_handler;
+        sequence_table->sq_item = sequence_item_handler;
+        sequence_table->sq_slice = sequence_slice_handler;
+
+        sequence_table->sq_ass_item = sequence_ass_item_handler;    // BAS setup seperately?
+        sequence_table->sq_ass_slice = sequence_ass_slice_handler;  // BAS setup seperately?
+    }
+    return *this;
+}
+
+PythonType & PythonType::supportMappingType()
+{
+    if( !mapping_table )
+    {
+        mapping_table = new PyMappingMethods;
+        memset( mapping_table, 0, sizeof( PyMappingMethods ) );   // ensure new fields are 0
+        table->tp_as_mapping = mapping_table;
+        mapping_table->mp_length = mapping_length_handler;
+        mapping_table->mp_subscript = mapping_subscript_handler;
+        mapping_table->mp_ass_subscript = mapping_ass_subscript_handler;    // BAS setup seperately?
+    }
+    return *this;
+}
+
+PythonType & PythonType::supportNumberType()
+{
+    if( !number_table )
+    {
+        number_table = new PyNumberMethods;
+        memset( number_table, 0, sizeof( PyNumberMethods ) );   // ensure new fields are 0
+        table->tp_as_number = number_table;
+        number_table->nb_add = number_add_handler;
+        number_table->nb_subtract = number_subtract_handler;
+        number_table->nb_multiply = number_multiply_handler;
+        number_table->nb_divide = number_divide_handler;
+        number_table->nb_remainder = number_remainder_handler;
+        number_table->nb_divmod = number_divmod_handler;
+        number_table->nb_power = number_power_handler;
+        number_table->nb_negative = number_negative_handler;
+        number_table->nb_positive = number_positive_handler;
+        number_table->nb_absolute = number_absolute_handler;
+        number_table->nb_nonzero = number_nonzero_handler;
+        number_table->nb_invert = number_invert_handler;
+        number_table->nb_lshift = number_lshift_handler;
+        number_table->nb_rshift = number_rshift_handler;
+        number_table->nb_and = number_and_handler;
+        number_table->nb_xor = number_xor_handler;
+        number_table->nb_or = number_or_handler;
+        number_table->nb_coerce = 0;
+        number_table->nb_int = number_int_handler;
+        number_table->nb_long = number_long_handler;
+        number_table->nb_float = number_float_handler;
+        number_table->nb_oct = number_oct_handler;
+        number_table->nb_hex = number_hex_handler;
+    }
+    return *this;
+}
+
+PythonType & PythonType::supportBufferType()
+{
+    if( !buffer_table )
+    {
+        buffer_table = new PyBufferProcs;
+        memset( buffer_table, 0, sizeof( PyBufferProcs ) );   // ensure new fields are 0
+        table->tp_as_buffer = buffer_table;
+        buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
+        buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
+        buffer_table->bf_getsegcount = buffer_getsegcount_handler;
+    }
+    return *this;
+}
+
+// if you define one sequence method you must define 
+// all of them except the assigns
+
+PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
+    : table( new PyTypeObject )
+    , sequence_table( NULL )
+    , mapping_table( NULL )
+    , number_table( NULL )
+    , buffer_table( NULL )
+{
+    memset( table, 0, sizeof( PyTypeObject ) );   // ensure new fields are 0
+    *reinterpret_cast<PyObject*>( table ) = py_object_initializer;
+    table->ob_type = _Type_Type();
+    table->ob_size = 0;
+    table->tp_name = const_cast<char *>( default_name );
+    table->tp_basicsize = basic_size;
+    table->tp_itemsize = itemsize;
+    table->tp_dealloc = ( destructor ) standard_dealloc;
+    table->tp_print = 0;
+    table->tp_getattr = 0;
+    table->tp_setattr = 0;
+    table->tp_compare = 0;
+    table->tp_repr = 0;
+    table->tp_as_number = 0;
+    table->tp_as_sequence = 0;
+    table->tp_as_mapping =  0;
+    table->tp_hash = 0;
+    table->tp_call = 0;
+    table->tp_str = 0;
+    table->tp_getattro = 0;
+    table->tp_setattro = 0;
+    table->tp_as_buffer = 0;
+    table->tp_flags = Py_TPFLAGS_DEFAULT;
+    table->tp_doc = 0;
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
+    // first use in 2.0
+    table->tp_traverse = 0L;
+    table->tp_clear = 0L;
+#else
+    table->tp_xxx5 = 0L;
+    table->tp_xxx6 = 0L;
+#endif
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
+    // first defined in 2.1
+    table->tp_richcompare = 0L;
+    table->tp_weaklistoffset = 0L;
+#else
+    table->tp_xxx7 = 0L;
+    table->tp_xxx8 = 0L;
+#endif
+
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 2)
+    // first defined in 2.3
+    table->tp_iter = 0L;
+    table->tp_iternext = 0L;
+#endif
+
+#ifdef COUNT_ALLOCS
+    table->tp_alloc = 0;
+    table->tp_free = 0;
+    table->tp_maxalloc = 0;
+    table->tp_next = 0;
+#endif
+}
+
+PythonType::~PythonType( )
+{
+    delete table;
+    delete sequence_table;
+    delete mapping_table;
+    delete number_table;
+    delete buffer_table;
+}
+
+PyTypeObject* PythonType::type_object( ) const
+{return table;}
+
+PythonType & PythonType::name( const char* nam )
+{
+    table->tp_name = const_cast<char *>( nam );
+    return *this;
+}
+
+const char *PythonType::getName() const
+{
+    return table->tp_name;
+}
+
+PythonType & PythonType::doc( const char* d )
+{
+    table->tp_doc = const_cast<char *>( d );
+    return *this;
+}
+
+const char *PythonType::getDoc() const
+{
+    return table->tp_doc;
+}
+
+PythonType & PythonType::dealloc( void( *f )( PyObject* ))
+{
+    table->tp_dealloc = f;
+    return *this;
+}
+
+PythonType & PythonType::supportPrint()
+{
+    table->tp_print = print_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportGetattr()
+{
+    table->tp_getattr = getattr_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportSetattr()
+{
+    table->tp_setattr = setattr_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportGetattro()
+{
+    table->tp_getattro = getattro_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportSetattro()
+{
+    table->tp_setattro = setattro_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportCompare()
+{
+    table->tp_compare = compare_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportRepr()
+{
+    table->tp_repr = repr_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportStr()
+{
+    table->tp_str = str_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportHash()
+{
+    table->tp_hash = hash_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportCall()
+{
+    table->tp_call = call_handler;
+    return *this;
+}
+
+PythonType & PythonType::supportIter()
+{
+    table->tp_iter = iter_handler;
+    table->tp_iternext = iternext_handler;
+    return *this;
+}
+
+//--------------------------------------------------------------------------------
+//
+//    Handlers
+//
+//--------------------------------------------------------------------------------
+extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->print( fp, flags );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* getattr_handler( PyObject *self, char *name )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->getattr( name ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->setattr( name, Py::Object( value ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* getattro_handler( PyObject *self, PyObject *name )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->getattro( Py::Object( name ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->setattro( Py::Object( name ), Py::Object( value ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" int compare_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->compare( Py::Object( other ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* repr_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->repr() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* str_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->str() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" long hash_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->hash();
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* call_handler( PyObject *self, PyObject *args, PyObject *kw )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        if( kw != NULL )
+            return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
+        else
+            return new_reference_to( p->call( Py::Object( args ), Py::Object() ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* iter_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->iter() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* iternext_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->iternext();  // might be a NULL ptr on end of iteration
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+
+// Sequence methods
+extern "C" Py_ssize_t sequence_length_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->sequence_length();
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* sequence_concat_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->sequence_concat( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* sequence_repeat_handler( PyObject *self, Py_ssize_t count )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->sequence_repeat( count ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* sequence_item_handler( PyObject *self, Py_ssize_t index )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->sequence_item( index ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* sequence_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->sequence_slice( first, last ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->sequence_ass_item( index, Py::Object( value ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" int sequence_ass_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *value )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->sequence_ass_slice( first, last, Py::Object( value ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+// Mapping
+extern "C" Py_ssize_t mapping_length_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->mapping_length();
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* mapping_subscript_handler( PyObject *self, PyObject *key )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->mapping_subscript( Py::Object( key ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->mapping_ass_subscript( Py::Object( key ), Py::Object( value ) );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+// Number
+extern "C" int number_nonzero_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->number_nonzero();
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_negative_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_negative() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_positive_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_positive() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_absolute_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_absolute() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_invert_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_invert() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_int_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_int() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_float_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_float() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_long_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_long() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_oct_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_oct() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_hex_handler( PyObject *self )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_hex() );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_add_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_add( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_subtract_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_subtract( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_multiply_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_multiply( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_divide_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_divide( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_remainder_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_remainder( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_divmod_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_divmod( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_lshift_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_lshift( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_rshift_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_rshift( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_and_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_and( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_xor_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_xor( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_or_handler( PyObject *self, PyObject *other )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_or( Py::Object( other ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+extern "C" PyObject* number_power_handler( PyObject *self, PyObject *x1, PyObject *x2 )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return new_reference_to( p->number_power( Py::Object( x1 ), Py::Object( x2 ) ) );
+    }
+    catch( Py::Exception & )
+    {
+        return NULL;    // indicate error
+    }
+}
+
+// Buffer
+extern "C" Py_ssize_t buffer_getreadbuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->buffer_getreadbuffer( index, pp );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" Py_ssize_t buffer_getwritebuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->buffer_getwritebuffer( index, pp );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+extern "C" Py_ssize_t buffer_getsegcount_handler( PyObject *self, Py_ssize_t *count )
+{
+    try
+    {
+        PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+        return p->buffer_getsegcount( count );
+    }
+    catch( Py::Exception & )
+    {
+        return -1;    // indicate error
+    }
+}
+
+
+//================================================================================
+//
+//    Implementation of PythonExtensionBase
+//
+//================================================================================
+#define missing_method( method ) \
+throw RuntimeError( "Extension object does not support method " #method );
+
+PythonExtensionBase::PythonExtensionBase()
+{
+}
+
+PythonExtensionBase::~PythonExtensionBase()
+{
+    assert( ob_refcnt == 0 );
+}
+
+int PythonExtensionBase::print( FILE *, int )
+{ missing_method( print ); return -1; }
+
+int PythonExtensionBase::setattr( const char*, const Py::Object & )
+{ missing_method( setattr ); return -1; }
+
+Py::Object PythonExtensionBase::getattro( const Py::Object & )
+{ missing_method( getattro ); return Py::Nothing(); }
+
+int PythonExtensionBase::setattro( const Py::Object &, const Py::Object & )
+{ missing_method( setattro ); return -1; }
+
+int PythonExtensionBase::compare( const Py::Object & )
+{ missing_method( compare ); return -1; }
+
+Py::Object PythonExtensionBase::repr()
+{ missing_method( repr ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::str()
+{ missing_method( str ); return Py::Nothing(); }
+
+long PythonExtensionBase::hash()
+{ missing_method( hash ); return -1; }
+
+Py::Object PythonExtensionBase::call( const Py::Object &, const Py::Object & )
+{ missing_method( call ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::iter()
+{ missing_method( iter ); return Py::Nothing(); }
+
+PyObject* PythonExtensionBase::iternext()
+{ missing_method( iternext ); return NULL; }
+
+
+// Sequence methods
+int PythonExtensionBase::sequence_length()
+{ missing_method( sequence_length ); return -1; }
+
+Py::Object PythonExtensionBase::sequence_concat( const Py::Object & )
+{ missing_method( sequence_concat ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::sequence_repeat( Py_ssize_t )
+{ missing_method( sequence_repeat ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::sequence_item( Py_ssize_t )
+{ missing_method( sequence_item ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::sequence_slice( Py_ssize_t, Py_ssize_t )
+{ missing_method( sequence_slice ); return Py::Nothing(); }
+
+int PythonExtensionBase::sequence_ass_item( Py_ssize_t, const Py::Object & )
+{ missing_method( sequence_ass_item ); return -1; }
+
+int PythonExtensionBase::sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Py::Object & )
+{ missing_method( sequence_ass_slice ); return -1; }
+
+
+// Mapping
+int PythonExtensionBase::mapping_length()
+{ missing_method( mapping_length ); return -1; }
+
+Py::Object PythonExtensionBase::mapping_subscript( const Py::Object & )
+{ missing_method( mapping_subscript ); return Py::Nothing(); }
+
+int PythonExtensionBase::mapping_ass_subscript( const Py::Object &, const Py::Object & )
+{ missing_method( mapping_ass_subscript ); return -1; }
+
+
+// Number
+int PythonExtensionBase::number_nonzero()
+{ missing_method( number_nonzero ); return -1; }
+
+Py::Object PythonExtensionBase::number_negative()
+{ missing_method( number_negative ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_positive()
+{ missing_method( number_positive ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_absolute()
+{ missing_method( number_absolute ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_invert()
+{ missing_method( number_invert ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_int()
+{ missing_method( number_int ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_float()
+{ missing_method( number_float ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_long()
+{ missing_method( number_long ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_oct()
+{ missing_method( number_oct ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_hex()
+{ missing_method( number_hex ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_add( const Py::Object & )
+{ missing_method( number_add ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_subtract( const Py::Object & )
+{ missing_method( number_subtract ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_multiply( const Py::Object & )
+{ missing_method( number_multiply ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_divide( const Py::Object & )
+{ missing_method( number_divide ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_remainder( const Py::Object & )
+{ missing_method( number_remainder ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_divmod( const Py::Object & )
+{ missing_method( number_divmod ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_lshift( const Py::Object & )
+{ missing_method( number_lshift ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_rshift( const Py::Object & )
+{ missing_method( number_rshift ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_and( const Py::Object & )
+{ missing_method( number_and ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_xor( const Py::Object & )
+{ missing_method( number_xor ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_or( const Py::Object & )
+{ missing_method( number_or ); return Py::Nothing(); }
+
+Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Object & )
+{ missing_method( number_power ); return Py::Nothing(); }
+
+
+// Buffer
+Py_ssize_t PythonExtensionBase::buffer_getreadbuffer( Py_ssize_t, void** )
+{ missing_method( buffer_getreadbuffer ); return -1; }
+
+Py_ssize_t PythonExtensionBase::buffer_getwritebuffer( Py_ssize_t, void** )
+{ missing_method( buffer_getwritebuffer ); return -1; }
+
+Py_ssize_t PythonExtensionBase::buffer_getsegcount( Py_ssize_t* )
+{ missing_method( buffer_getsegcount ); return -1; }
+
+//--------------------------------------------------------------------------------
+//
+//    Method call handlers for
+//        PythonExtensionBase
+//        ExtensionModuleBase
+//
+//--------------------------------------------------------------------------------
+
+extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
+{
+    try
+    {
+        Tuple self_and_name_tuple( _self_and_name_tuple );
+
+        PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
+        void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
+        if( self_as_void == NULL )
+            return NULL;
+
+        ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
+
+        String py_name( self_and_name_tuple[1] );
+        std::string name( py_name.as_std_string() );
+
+        Tuple args( _args );
+        if( _keywords == NULL )
+        {
+            Dict keywords;    // pass an empty dict
+
+            Object result( self->invoke_method_keyword( name, args, keywords ) );
+            return new_reference_to( result.ptr() );
+        }
+
+        Dict keywords( _keywords );
+
+        Object result( self->invoke_method_keyword( name, args, keywords ) );
+        return new_reference_to( result.ptr() );
+    }
+    catch( Exception & )
+    {
+        return 0;
+    }
+}
+
+extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
+{
+    try
+    {
+        Tuple self_and_name_tuple( _self_and_name_tuple );
+
+        PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
+        void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
+        if( self_as_void == NULL )
+        return NULL;
+
+        ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
+
+        String py_name( self_and_name_tuple[1] );
+        std::string name( py_name.as_std_string() );
+
+        Tuple args( _args );
+
+        Object result( self->invoke_method_varargs( name, args ) );
+
+        return new_reference_to( result.ptr() );
+    }
+    catch( Exception & )
+    {
+        return 0;
+    }
+}
+
+extern "C" void do_not_dealloc( void * )
+{}
+
+
+//--------------------------------------------------------------------------------
+//
+//    ExtensionExceptionType
+//
+//--------------------------------------------------------------------------------
+ExtensionExceptionType::ExtensionExceptionType()
+    : Py::Object()
+{
+}
+
+void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
+{
+    std::string module_name( module.fullName() );
+    module_name += ".";
+    module_name += name;
+
+    set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
+}
+
+void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent)
+ {
+     std::string module_name( module.fullName() );
+     module_name += ".";
+     module_name += name;
+
+    set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
+}
+ExtensionExceptionType::~ExtensionExceptionType()
+{
+}
+
+Exception::Exception( ExtensionExceptionType &exception, const std::string& reason )
+{
+    PyErr_SetString (exception.ptr(), reason.c_str());
+}
+
+Exception::Exception( ExtensionExceptionType &exception, Object &reason )
+{
+    PyErr_SetObject (exception.ptr(), reason.ptr());
+}
+
+Exception::Exception( PyObject* exception, Object &reason )
+{
+    PyErr_SetObject (exception, reason.ptr());
+}        
+
+}    // end of namespace Py
diff --git a/src/extension/script/CXX/cxxextensions.c b/src/extension/script/CXX/cxxextensions.c
new file mode 100644 (file)
index 0000000..edae3be
--- /dev/null
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//---------------------------------------------------------------------------*/
+
+#include "CXX/WrapPython.h"
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+PyObject py_object_initializer = {PyObject_HEAD_INIT(0)};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/extension/script/CXX/cxxsupport.cxx b/src/extension/script/CXX/cxxsupport.cxx
new file mode 100644 (file)
index 0000000..1dfba5a
--- /dev/null
@@ -0,0 +1,174 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 1998 - 2007, The Regents of the University of California
+// Produced at the Lawrence Livermore National Laboratory
+// All rights reserved.
+//
+// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
+// full copyright notice is contained in the file COPYRIGHT located at the root
+// of the PyCXX distribution.
+//
+// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
+// modification, are permitted provided that the following conditions are met:
+//
+//  - Redistributions of  source code must  retain the above  copyright notice,
+//    this list of conditions and the disclaimer below.
+//  - Redistributions in binary form must reproduce the above copyright notice,
+//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
+//    documentation and/or materials provided with the distribution.
+//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
+//    used to  endorse or  promote products derived from  this software without
+//    specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
+// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
+// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
+// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
+// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
+// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
+// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+//-----------------------------------------------------------------------------
+
+#include "CXX/Objects.hxx"
+namespace Py {
+
+Py_UNICODE unicode_null_string[1] = { 0 };
+
+Type Object::type () const
+{ 
+    return Type (PyObject_Type (p), true);
+}
+
+String Object::str () const
+{
+    return String (PyObject_Str (p), true);
+}
+
+String Object::repr () const
+{ 
+    return String (PyObject_Repr (p), true);
+}
+
+std::string Object::as_string() const
+{
+    return static_cast<std::string>(str());
+}
+
+List Object::dir () const
+        {
+        return List (PyObject_Dir (p), true);
+        }
+
+bool Object::isType (const Type& t) const
+{ 
+    return type ().ptr() == t.ptr();
+}
+
+Char::operator String() const
+{
+    return String(ptr());
+}
+
+// TMM: non-member operaters for iterators - see above
+// I've also made a bug fix in respect to the cxx code
+// (dereffed the left.seq and right.seq comparison)
+bool operator==(const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.eql( right );
+}
+
+bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.neq( right );
+}
+
+bool operator< (const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.lss( right );
+}
+
+bool operator> (const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.gtr( right );
+}
+
+bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.leq( right );
+}
+
+bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right)
+{
+    return left.geq( right );
+}
+
+// now for const_iterator
+bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.eql( right );
+}
+
+bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.neq( right );
+}
+
+bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.lss( right );
+}
+
+bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.gtr( right );
+}
+
+bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.leq( right );
+}
+
+bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right)
+{
+    return left.geq( right );
+}
+
+// For mappings:
+bool operator==(const Mapping::iterator& left, const Mapping::iterator& right)
+{
+    return left.eql( right );
+}
+
+bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right)
+{
+    return left.neq( right );
+}
+
+// now for const_iterator
+bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right)
+{
+    return left.eql( right );
+}
+
+bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right)
+{
+    return left.neq( right );
+}
+
+// TMM: 31May'01 - Added the #ifndef so I can exclude iostreams.
+#ifndef CXX_NO_IOSTREAMS
+// output
+
+std::ostream& operator<< (std::ostream& os, const Object& ob)
+{
+    return (os << static_cast<std::string>(ob.str()));
+}  
+#endif
+
+} // Py