Program Listing for File PyTemplates.h¶
↰ Return to documentation for file (PyTemplates.h
)
// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details
#ifndef NECSIM_PYTEMPLATES_H
#define NECSIM_PYTEMPLATES_H
#include <Python.h>
#include <structmember.h>
#include <memory>
#include "PyImports.h"
using namespace necsim;
template<class T>
class PyTemplate
{
public:
PyObject_HEAD
PyObject *logger = nullptr;
PyObject *log_function = nullptr;
std::unique_ptr<T> base_object = nullptr;
virtual ~PyTemplate();
};
template<class T>
static int
PyTemplate_traverse(PyTemplate<T> *self, visitproc visit, void *arg)
{
Py_VISIT(self->logger);
Py_VISIT(self->log_function);
return 0;
}
template<class T>
static int
PyTemplate_clear(PyTemplate<T> *self)
{
Py_CLEAR(self->logger);
Py_CLEAR(self->log_function);
return 0;
}
template<class T>
static void
PyTemplate_dealloc(PyTemplate<T> *self)
{
if(self->base_object != nullptr)
{
self->base_object.reset();
self->base_object = nullptr;
}
removeGlobalLogger();
PyObject_GC_UnTrack(self);
PyTemplate_clear(self);
Py_TYPE(self)->tp_free((PyObject *) self);
}
template<class T>
static PyObject *
PyTemplate_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyTemplate<T> *self;
self = (PyTemplate<T> *) type->tp_alloc(type, 0);
if(self != nullptr)
{
self->logger = nullptr;
self->log_function = nullptr;
}
return (PyObject *) self;
}
template<class T>
void initialise_logger(PyTemplate<T> *self)
{
if(self->logger == nullptr)
{
throw runtime_error("Logger has not been set");
}
PyObject *l;
Py_INCREF(self->logger);
l = self->logger;
PyObject *c;
Py_INCREF(self->log_function);
c = self->log_function;
getGlobalLogger(l, c);
}
template<class T>
static int
PyTemplate_init(PyTemplate<T> *self, PyObject *args, PyObject *kwds)
{
PyObject *tmp_logger;
PyObject *tmp_call_back;
PyObject *tmp;
// static char *kwlist[] = {const_cast<char *>("logger"), const_cast<char *>("logging_function"), NULL};
if(PyArg_ParseTuple(args, "OO", &tmp_logger, &tmp_call_back))
{
if(!PyCallable_Check(tmp_call_back))
{
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return -1;
}
// Dispose of previous references
if(tmp_logger)
{
tmp = self->logger;
Py_INCREF(tmp_logger);
self->logger = tmp_logger;
Py_XDECREF(tmp);
}
if(tmp_call_back)
{
tmp = self->log_function;
Py_INCREF(tmp_call_back);
self->log_function = tmp_call_back;
Py_XDECREF(tmp);
}
try
{
initialise_logger(self);
self->base_object = make_unique<T>();
// self->init();
}
catch(exception &e)
{
removeGlobalLogger();
string errmsg = "error initialising PyTemplate object: ";
errmsg += e.what();
PyErr_SetString(PyExc_TypeError, errmsg.c_str());
return -1;
}
/* Boilerplate to return "None" */
return 0;
}
return -1;
}
template<class T>
static PyObject *
PyTemplate_getLogging(PyTemplate<T> *self, void *closure)
{
Py_INCREF(self->logger);
return self->logger;
}
template<class T>
static int
PyTemplate_setLogging(PyTemplate<T> *self, PyObject *value, void *closure)
{
PyObject *tmp;
if(value == nullptr)
{
PyErr_SetString(PyExc_TypeError, "Cannot delete the logger attribute");
return -1;
}
tmp = self->logger;
Py_INCREF(value);
self->logger = value;
Py_XDECREF(tmp);
return 0;
}
template<class T>
static PyObject *
PyTemplate_getCallLogger(PyTemplate<T> *self, void *closure)
{
Py_INCREF(self->log_function);
return self->log_function;
}
template<class T>
static int
PyTemplate_setCallLogger(PyTemplate<T> *self, PyObject *value, void *closure)
{
PyObject *tmp;
if(value == nullptr)
{
PyErr_SetString(PyExc_TypeError, "Cannot delete the logger attribute");
return -1;
}
tmp = self->log_function;
Py_INCREF(value);
self->log_function = value;
Py_XDECREF(tmp);
return 0;
}
template<typename T>
PyGetSetDef *PyTemplate_gen_getsetters()
{
static PyGetSetDef PyTemplate_getsetters[] = {
{const_cast<char *>("logger"), (getter) PyTemplate_getLogging<T>, (setter) PyTemplate_setLogging<T>,
const_cast<char *>("the reference to the logger module"), nullptr},
{const_cast<char *>("log_function"), (getter) PyTemplate_getCallLogger<T>, (setter) PyTemplate_setCallLogger<T>,
const_cast<char *>("the logger call function to use"), nullptr},
{nullptr} /* Sentinel */
};
return PyTemplate_getsetters;
}
#endif // NECSIM_PYTEMPLATES_H