/*========================================================================= Program: Visualization Toolkit Module: PyVTKTemplate.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /*----------------------------------------------------------------------- The PyVTKTemplate was created in May 2011 by David Gobbi. This object is a container for instantiations of templated types. Essentially, it is a "dict" that accepts template args as keys, and provides the corresponding instantiation of the template. It is implemented as a subclass of PyModule. -----------------------------------------------------------------------*/ #include "PyVTKTemplate.h" #include "vtkPythonUtil.h" #include // Silence warning like // "dereferencing type-punned pointer will break strict-aliasing rules" // it happens because this kind of expression: (long *)&ptr #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif //-------------------------------------------------------------------- static const char *PyVTKTemplate_Doc = "A container for instantiations of class and function templates.\n\n" "This is a dictionary for templates, provide the template args\n" "in square brackets to get the desired kind of class.\n"; //-------------------------------------------------------------------- // Methods to help with name mangling and unmangling PyObject *PyVTKTemplate_KeyFromName(PyObject *self, PyObject *arg); PyObject *PyVTKTemplate_NameFromKey(PyObject *self, PyObject *key); //-------------------------------------------------------------------- // Methods for python static PyObject *PyVTKTemplate_HasKey(PyObject *ob, PyObject *args) { PyObject *key = nullptr; if (PyArg_ParseTuple(args, "O:has_key", &key)) { PyObject *rval = nullptr; PyObject *name = PyVTKTemplate_NameFromKey(ob, key); if (name) { PyObject *dict = PyModule_GetDict(ob); rval = PyDict_GetItem(dict, name); Py_DECREF(name); } if (rval) { Py_DECREF(rval); Py_INCREF(Py_True); return Py_True; } else if (!PyErr_Occurred()) { Py_INCREF(Py_False); return Py_False; } } return nullptr; } static PyObject *PyVTKTemplate_Keys(PyObject *ob, PyObject *args) { if (PyArg_ParseTuple(args, ":keys")) { PyObject *dict = PyModule_GetDict(ob); PyObject *l = PyList_New(0); Py_ssize_t pos = 0; PyObject *key, *value; while (PyDict_Next(dict, &pos, &key, &value)) { key = PyVTKTemplate_KeyFromName(ob, key); if (key) { PyList_Append(l, key); Py_DECREF(key); } } return l; } return nullptr; } static PyObject *PyVTKTemplate_Values(PyObject *ob, PyObject *args) { if (PyArg_ParseTuple(args, ":values")) { PyObject *dict = PyModule_GetDict(ob); PyObject *l = PyList_New(0); Py_ssize_t pos = 0; PyObject *key, *value; while (PyDict_Next(dict, &pos, &key, &value)) { key = PyVTKTemplate_KeyFromName(ob, key); if (key) { PyList_Append(l, value); Py_DECREF(key); } } return l; } return nullptr; } static PyObject *PyVTKTemplate_Items(PyObject *ob, PyObject *args) { if (PyArg_ParseTuple(args, ":items")) { PyObject *dict = PyModule_GetDict(ob); PyObject *l = PyList_New(0); Py_ssize_t pos = 0; PyObject *key, *value; while (PyDict_Next(dict, &pos, &key, &value)) { key = PyVTKTemplate_KeyFromName(ob, key); if (key) { Py_INCREF(value); PyObject *t = PyTuple_New(2); PyTuple_SET_ITEM(t, 0, key); PyTuple_SET_ITEM(t, 1, value); PyList_Append(l, t); Py_DECREF(t); } } return l; } return nullptr; } static PyObject *PyVTKTemplate_Get(PyObject *ob, PyObject *args) { PyObject *key = nullptr; PyObject *def = Py_None; if (PyArg_ParseTuple(args, "O|O:get", &key, &def)) { PyObject *rval = nullptr; PyObject *dict = PyModule_GetDict(ob); key = PyVTKTemplate_NameFromKey(ob, key); if (key) { rval = PyDict_GetItem(dict, key); Py_DECREF(key); } if (rval) { return rval; } else if (!PyErr_Occurred()) { Py_INCREF(def); return def; } } return nullptr; } static PyMethodDef PyVTKTemplate_Methods[] = { {"has_key", PyVTKTemplate_HasKey, METH_VARARGS, "T.has_key(args) -> True only the template args are allowed."}, {"keys", PyVTKTemplate_Keys, METH_VARARGS, "T.keys() -> list of allowed template args."}, {"values", PyVTKTemplate_Values, METH_VARARGS, "T.values() -> list of provided template instantiations."}, {"items", PyVTKTemplate_Items, METH_VARARGS, "T.items() -> list of (args,types) pairs."}, {"get", PyVTKTemplate_Get, METH_VARARGS, "T.get(args) -> get instantiated template type or None."}, { nullptr, nullptr, 0, nullptr } }; //-------------------------------------------------------------------- // Mapping protocol static Py_ssize_t PyVTKTemplate_Size(PyObject *ob) { Py_ssize_t l = 0; PyObject *dict = PyModule_GetDict(ob); Py_ssize_t pos = 0; PyObject *key, *value; while (PyDict_Next(dict, &pos, &key, &value)) { key = PyVTKTemplate_KeyFromName(ob, key); if (key) { Py_DECREF(key); l++; } } return l; } static PyObject * PyVTKTemplate_GetItem(PyObject *ob, PyObject *key) { PyObject *r = nullptr; PyObject *dict = PyModule_GetDict(ob); PyObject *name = PyVTKTemplate_NameFromKey(ob, key); if (name) { // see if the named class is present r = PyObject_GetItem(dict, name); Py_DECREF(name); if (r == nullptr) { // clear the error (it will be set below) PyErr_Clear(); } } if (r == nullptr) { // set a key error PyObject *t = PyTuple_Pack(1, key); PyErr_SetObject(PyExc_KeyError, t); Py_DECREF(t); } return r; } //-------------------------------------------------------------------- static PyMappingMethods PyVTKTemplate_AsMapping = { PyVTKTemplate_Size, // mp_length PyVTKTemplate_GetItem, // mp_subscript nullptr, // mp_ass_subscript }; //-------------------------------------------------------------------- static PyObject *PyVTKTemplate_Repr(PyObject *self) { return PyString_FromFormat("