-
Notifications
You must be signed in to change notification settings - Fork 0
/
extension.hh
145 lines (136 loc) · 4.83 KB
/
extension.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef CAPY_EXTENSION_HH
#define CAPY_EXTENSION_HH
namespace Capy
{
class Extension
{
public:
const char *const mod_name;
Extension(const char *mod_name_, const char *mod_doc_ = 0)
: mod_name(mod_name_),
mod_doc(mod_doc_),
functions(new std::vector<PyMethodDef>)
{
PyMethodDef func = {0};
functions->push_back(func);
}
~Extension()
{
if (PyErr_Occurred())
return;
PyObject *module =
Py_InitModule3(mod_name, &functions->front(), mod_doc);
if (!module)
return;
for (unsigned i = 0; i < objects.size(); ++i)
if (PyModule_AddObject(module, obj_names[i],
objects[i].new_reference()) == -1)
return;
}
template <typename RT, RT (*func)()>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<RT, func> >, doc);
}
template <void (*func)()>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<func> >, doc);
}
template <typename RT, typename T, RT (*func)(T)>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<RT, T, func> >, doc);
}
template <typename T, void (*func)(T)>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<T, func> >, doc);
}
template <typename RT, typename T1, typename T2, RT (*func)(T1, T2)>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<RT, T1, T2, func> >, doc);
}
template <typename T1, typename T2, void (*func)(T1, T2)>
void add_function(const char *name, const char *doc = 0)
{
add_function_def(name, check_call<call_function<T1, T2, func> >, doc);
}
void add_object(const char *name, Object obj)
{
obj_names.push_back(name);
objects.push_back(obj);
}
private:
void add_function_def(const char *name, PyCFunction func,
const char *doc)
{
PyMethodDef def = {name, func, METH_VARARGS, doc};
functions->insert(functions->end() - 1, def);
}
template <typename RT, RT (*func)()>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return 0;
return Object(func()).new_reference();
}
template <void (*func)()>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return 0;
func();
Py_RETURN_NONE;
}
template <typename RT, typename T, RT (*func)(T)>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
PyObject *py_arg1;
if (!PyArg_ParseTuple(args, "O", &py_arg1))
return 0;
return Object(func(Object(py_arg1).new_reference())).new_reference();
}
template <typename T, void (*func)(T)>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
PyObject *py_arg1;
if (!PyArg_ParseTuple(args, "O", &py_arg1))
return 0;
func(Object(py_arg1).new_reference());
Py_RETURN_NONE;
}
template <typename RT, typename T1, typename T2, RT (*func)(T1, T2)>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
PyObject *py_arg1;
PyObject *py_arg2;
if (!PyArg_ParseTuple(args, "OO", &py_arg1, &py_arg2))
return 0;
return Object(func(Object(py_arg1).new_reference(),
Object(py_arg2).new_reference())).new_reference();
}
template <typename T1, typename T2, void (*func)(T1, T2)>
static PyObject *
call_function(PyObject *self, PyObject *args)
{
PyObject *py_arg1;
PyObject *py_arg2;
if (!PyArg_ParseTuple(args, "OO", &py_arg1, &py_arg2))
return 0;
func(Object(py_arg1).new_reference(), Object(py_arg2).new_reference());
Py_RETURN_NONE;
}
const char *mod_doc;
std::vector<PyMethodDef> *functions;
std::vector<const char *> obj_names;
std::vector<Object> objects;
};
}
#endif