summaryrefslogtreecommitdiff
path: root/python/generic.h
diff options
context:
space:
mode:
Diffstat (limited to 'python/generic.h')
-rw-r--r--python/generic.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/python/generic.h b/python/generic.h
new file mode 100644
index 00000000..3cbe374b
--- /dev/null
+++ b/python/generic.h
@@ -0,0 +1,132 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: generic.h,v 1.1 2001/02/20 06:32:01 jgg Exp $
+/* ######################################################################
+
+ generic - Some handy functions to make integration a tad simpler
+
+ Python needs this little _HEAD tacked onto the front of the object..
+ This complicates the integration with C++. We use some templates to
+ make that quite transparent to us. It would have been nice if Python
+ internally used a page from the C++ ref counting book to hide its little
+ header from the world, but it doesn't.
+
+ The CppPyObject has the target object and the Python header, this is
+ needed to ensure proper alignment.
+ GetCpp returns the C++ object from a PyObject.
+ CppPyObject_NEW creates the Python object and then uses placement new
+ to init the C++ class.. This is good for simple situations and as an
+ example on how to do it in other more specific cases.
+ CppPyObject_Dealloc should be used in the Type as the destructor
+ function.
+ HandleErrors converts errors from the internal _error stack into Python
+ exceptions and makes sure the _error stack is empty.
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef GENERIC_H
+#define GENERIC_H
+
+#include <python/Python.h>
+#include <string>
+
+template <class T> struct CppPyObject : public PyObject
+{
+ T Object;
+};
+
+template <class T> struct CppOwnedPyObject : public CppPyObject<T>
+{
+ PyObject *Owner;
+};
+
+template <class T>
+inline T &GetCpp(PyObject *Obj)
+{
+ return ((CppPyObject<T> *)Obj)->Object;
+}
+
+template <class T>
+inline PyObject *GetOwner(PyObject *Obj)
+{
+ return ((CppOwnedPyObject<T> *)Obj)->Owner;
+}
+
+// Generic 'new' functions
+template <class T>
+inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type)
+{
+ CppPyObject<T> *New = PyObject_NEW(CppPyObject<T>,Type);
+ new (&New->Object) T;
+ return New;
+}
+
+template <class T,class A>
+inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type,A const &Arg)
+{
+ CppPyObject<T> *New = PyObject_NEW(CppPyObject<T>,Type);
+ new (&New->Object) T(Arg);
+ return New;
+}
+
+template <class T>
+inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
+ PyTypeObject *Type)
+{
+ CppOwnedPyObject<T> *New = PyObject_NEW(CppOwnedPyObject<T>,Type);
+ new (&New->Object) T;
+ New->Owner = Owner;
+ Py_INCREF(Owner);
+ return New;
+}
+
+template <class T,class A>
+inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
+ PyTypeObject *Type,A const &Arg)
+{
+ CppOwnedPyObject<T> *New = PyObject_NEW(CppOwnedPyObject<T>,Type);
+ new (&New->Object) T(Arg);
+ New->Owner = Owner;
+ if (Owner != 0)
+ Py_INCREF(Owner);
+ return New;
+}
+
+// Generic Dealloc type functions
+template <class T>
+void CppDealloc(PyObject *Obj)
+{
+ GetCpp<T>(Obj).~T();
+ PyMem_DEL(Obj);
+}
+
+template <class T>
+void CppOwnedDealloc(PyObject *iObj)
+{
+ CppOwnedPyObject<T> *Obj = (CppOwnedPyObject<T> *)iObj;
+ Obj->Object.~T();
+ if (Obj->Owner != 0)
+ Py_DECREF(Obj->Owner);
+ PyMem_DEL(Obj);
+}
+
+inline PyObject *CppPyString(string Str)
+{
+ return PyString_FromStringAndSize(Str.begin(),Str.length());
+}
+
+inline PyObject *Safe_FromString(const char *Str)
+{
+ if (Str == 0)
+ return PyString_FromString("");
+ return PyString_FromString(Str);
+}
+
+// Convert _error into Python exceptions
+PyObject *HandleErrors(PyObject *Res = 0);
+
+// Convert a list of strings to a char **
+const char **ListToCharChar(PyObject *List,bool NullTerm = false);
+PyObject *CharCharToList(const char **List,unsigned long Size = 0);
+
+#endif