mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
467 lines
15 KiB
C++
467 lines
15 KiB
C++
#ifndef _CoreBoostPy_Callback_h_
|
|
#define _CoreBoostPy_Callback_h_
|
|
|
|
#include "Common.h"
|
|
|
|
namespace boost { namespace python {
|
|
|
|
template <
|
|
class R
|
|
>
|
|
typename detail::returnable<R>::type
|
|
invoke(PyObject* callable
|
|
, PyObject* args
|
|
, boost::type<R>* = 0
|
|
)
|
|
{
|
|
PyObject* const result =
|
|
PyObject_CallObject(
|
|
callable
|
|
, args
|
|
);
|
|
|
|
// This conversion *must not* be done in the same expression as
|
|
// the call, because, in the special case where the result is a
|
|
// reference a Python object which was created by converting a C++
|
|
// argument for passing to PyEval_CallFunction, its reference
|
|
// count will be 2 until the end of the full expression containing
|
|
// the conversion, and that interferes with dangling
|
|
// pointer/reference detection.
|
|
converter::return_from_python<R> converter;
|
|
return converter(result);
|
|
}
|
|
|
|
}} //ns
|
|
|
|
NAMESPACE_UPP
|
|
|
|
void* call_convertible(PyObject* po);
|
|
|
|
//1
|
|
#define def_export_Callback1(P1) \
|
|
\
|
|
struct Callback1Action_##P1##_Py : public Callback1Action<P1> { \
|
|
object o; \
|
|
virtual void Execute(P1 p1) \
|
|
{ \
|
|
tuple args = make_tuple(p1); \
|
|
invoke<void>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Callback1Action_##P1##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Callback1_##P1##_from_python \
|
|
{ \
|
|
Callback1_##P1##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Callback1<P1> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Callback1<P1> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Callback1<P1>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Callback1<P1>(new Callback1Action_##P1##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Callback1<P1>(new Callback1Action_##P1##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Callback1_##P1() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Callback1_##P1##_from_python(); \
|
|
class_<Callback1<P1> >("Callback1_"#P1, "Upp Callback1<"#P1">") \
|
|
.def(init<const Callback1<P1>&>()) \
|
|
.def("clear", &Callback1<P1>::Clear) \
|
|
.def("valid", &Callback1<P1>::operator bool) \
|
|
.def("__call__", &Callback1<P1>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Callback1(P1) \
|
|
void export_Callback1_##P1() \
|
|
|
|
|
|
#define export_Callback1(P1) \
|
|
export_Callback1_##P1() \
|
|
|
|
|
|
#define def_export_Gate1(P1) \
|
|
\
|
|
struct Gate1Action_##P1##_Py : public Gate1Action<P1> { \
|
|
object o; \
|
|
virtual bool Execute(P1 p1) \
|
|
{ \
|
|
tuple args = make_tuple(p1); \
|
|
return invoke<bool>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Gate1Action_##P1##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Gate1_##P1##_from_python \
|
|
{ \
|
|
Gate1_##P1##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Gate1<P1> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Gate1<P1> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Gate1<P1>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Gate1<P1>(new Gate1Action_##P1##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Gate1<P1>(new Gate1Action_##P1##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Gate1_##P1() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Gate1_##P1##_from_python(); \
|
|
class_<Gate1<P1> >("Gate1_"#P1, "Upp Gate1<"#P1">") \
|
|
.def(init<const Gate1<P1>&>()) \
|
|
.def("clear", &Gate1<P1>::Clear) \
|
|
.def("valid", &Gate1<P1>::operator bool) \
|
|
.def("__call__", &Gate1<P1>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Gate1(P1) \
|
|
void export_Gate1_##P1() \
|
|
|
|
|
|
#define export_Gate1(P1) \
|
|
export_Gate1_##P1() \
|
|
|
|
|
|
//2
|
|
#define def_export_Callback2(P1, P2) \
|
|
\
|
|
struct Callback2Action_##P1##_##P2##_Py : public Callback2Action<P1, P2> { \
|
|
object o; \
|
|
virtual void Execute(P1 p1, P2 p2) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2); \
|
|
invoke<void>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Callback2Action_##P1##_##P2##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Callback2_##P1##_##P2##_from_python \
|
|
{ \
|
|
Callback2_##P1##_##P2##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Callback2<P1, P2> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Callback2<P1, P2> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Callback2<P1, P2>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Callback2<P1, P2>(new Callback2Action_##P1##_##P2##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Callback2<P1, P2>(new Callback2Action_##P1##_##P2##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Callback2_##P1##_##P2() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Callback2_##P1##_##P2##_from_python(); \
|
|
class_<Callback2<P1, P2> >("Callback2_"#P1"_"#P2, "Upp Callback2<"#P1","#P2">") \
|
|
.def(init<const Callback2<P1, P2>&>()) \
|
|
.def("clear", &Callback2<P1, P2>::Clear) \
|
|
.def("valid", &Callback2<P1, P2>::operator bool) \
|
|
.def("__call__", &Callback2<P1, P2>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Callback2(P1, P2) \
|
|
void export_Callback2_##P1##_##P2() \
|
|
|
|
|
|
#define export_Callback2(P1, P2) \
|
|
export_Callback2_##P1##_##P2() \
|
|
|
|
|
|
#define def_export_Gate2(P1, P2) \
|
|
\
|
|
struct Gate2Action_##P1##_##P2##_Py : public Gate2Action<P1, P2> { \
|
|
object o; \
|
|
virtual bool Execute(P1 p1, P2 p2) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2); \
|
|
return invoke<bool>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Gate2Action_##P1##_##P2##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Gate2_##P1##_##P2##_from_python \
|
|
{ \
|
|
Gate2_##P1##_##P2##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Gate2<P1, P2> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Gate2<P1, P2> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Gate2<P1, P2>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Gate2<P1, P2>(new Gate2Action_##P1##_##P2##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Gate2<P1, P2>(new Gate2Action_##P1##_##P2##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Gate2_##P1##_##P2() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Gate2_##P1##_##P2##_from_python(); \
|
|
class_<Gate2<P1, P2> >("Gate2_"#P1"_"#P2, "Upp Gate2<"#P1","#P2">") \
|
|
.def(init<const Gate2<P1, P2>&>()) \
|
|
.def("clear", &Gate2<P1, P2>::Clear) \
|
|
.def("valid", &Gate2<P1, P2>::operator bool) \
|
|
.def("__call__", &Gate2<P1, P2>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Gate2(P1, P2) \
|
|
void export_Gate2_##P1##_##P2() \
|
|
|
|
|
|
#define export_Gate2(P1, P2) \
|
|
export_Gate2_##P1##_##P2() \
|
|
|
|
|
|
//3
|
|
#define def_export_Callback3(P1, P2, P3) \
|
|
\
|
|
struct Callback3Action_##P1##_##P2##_##P3##_Py : public Callback3Action<P1, P2, P3> { \
|
|
object o; \
|
|
virtual void Execute(P1 p1, P2 p2, P3 p3) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2, p3); \
|
|
invoke<void>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Callback3Action_##P1##_##P2##_##P3##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Callback3_##P1##_##P2##_##P3##_from_python \
|
|
{ \
|
|
Callback3_##P1##_##P2##_##P3##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Callback3<P1, P2, P3> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Callback3<P1, P2, P3> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Callback3<P1, P2, P3>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Callback3<P1, P2, P3>(new Callback3Action_##P1##_##P2##_##P3##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Callback3<P1, P2, P3>(new Callback3Action_##P1##_##P2##_##P3##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Callback3_##P1##_##P2##_##P3() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Callback3_##P1##_##P2##_##P3##_from_python(); \
|
|
class_<Callback3<P1, P2, P3> >("Callback3_"#P1"_"#P2"_"#P3, "Upp Callback3<"#P1","#P2","#P3">") \
|
|
.def(init<const Callback3<P1, P2, P3>&>()) \
|
|
.def("clear", &Callback3<P1, P2, P3>::Clear) \
|
|
.def("valid", &Callback3<P1, P2, P3>::operator bool) \
|
|
.def("__call__", &Callback3<P1, P2, P3>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Callback3(P1, P2, P3) \
|
|
void export_Callback3_##P1##_##P2##_##P3() \
|
|
|
|
|
|
#define export_Callback3(P1, P2, P3) \
|
|
export_Callback3_##P1##_##P2##_##P3() \
|
|
|
|
|
|
#define def_export_Gate3(P1, P2, P3) \
|
|
\
|
|
struct Gate3Action_##P1##_##P2##_##P3##_Py : public Gate3Action<P1, P2, P3> { \
|
|
object o; \
|
|
virtual bool Execute(P1 p1, P2 p2, P3 p3) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2, p3); \
|
|
return invoke<bool>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Gate3Action_##P1##_##P2##_##P3##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Gate3_##P1##_##P2##_##P3##_from_python \
|
|
{ \
|
|
Gate3_##P1##_##P2##_##P3##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Gate3<P1, P2, P3> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Gate3<P1, P2, P3> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Gate3<P1, P2, P3>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Gate3<P1, P2, P3>(new Gate3Action_##P1##_##P2##_##P3##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Gate3<P1, P2, P3>(new Gate3Action_##P1##_##P2##_##P3##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Gate3_##P1##_##P2##_##P3() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Gate3_##P1##_##P2##_##P3##_from_python(); \
|
|
class_<Gate3<P1, P2, P3> >("Gate3_"#P1"_"#P2"_"#P3, "Upp Gate3<"#P1","#P2","#P3">") \
|
|
.def(init<const Gate3<P1, P2, P3>&>()) \
|
|
.def("clear", &Gate3<P1, P2, P3>::Clear) \
|
|
.def("valid", &Gate3<P1, P2, P3>::operator bool) \
|
|
.def("__call__", &Gate3<P1, P2, P3>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Gate3(P1, P2, P3) \
|
|
void export_Gate3_##P1##_##P2##_##P3() \
|
|
|
|
|
|
#define export_Gate3(P1, P2, P3) \
|
|
export_Gate3_##P1##_##P2##_##P3() \
|
|
|
|
|
|
//4
|
|
#define def_export_Callback4(P1, P2, P3, P4) \
|
|
\
|
|
struct Callback4Action_##P1##_##P2##_##P3##_##P4##_Py : public Callback4Action<P1, P2, P3, P4> { \
|
|
object o; \
|
|
virtual void Execute(P1 p1, P2 p2, P3 p3, P4 p4) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2, p3, p4); \
|
|
invoke<void>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Callback4Action_##P1##_##P2##_##P3##_##P4##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Callback4_##P1##_##P2##_##P3##_##P4##_from_python \
|
|
{ \
|
|
Callback4_##P1##_##P2##_##P3##_##P4##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Callback4<P1, P2, P3, P4> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Callback4<P1, P2, P3, P4> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Callback4<P1, P2, P3, P4>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Callback4<P1, P2, P3, P4>(new Callback4Action_##P1##_##P2##_##P3##_##P4##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Callback4<P1, P2, P3, P4>(new Callback4Action_##P1##_##P2##_##P3##_##P4##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Callback4_##P1##_##P2##_##P3##_##P4() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Callback4_##P1##_##P2##_##P3##_##P4##_from_python(); \
|
|
class_<Callback4<P1, P2, P3, P4> >("Callback4_"#P1"_"#P2"_"#P3"_"#P4, "Upp Callback4<"#P1","#P2","#P3","#P4">") \
|
|
.def(init<const Callback4<P1, P2, P3, P4>&>()) \
|
|
.def("clear", &Callback4<P1, P2, P3, P4>::Clear) \
|
|
.def("valid", &Callback4<P1, P2, P3, P4>::operator bool) \
|
|
.def("__call__", &Callback4<P1, P2, P3, P4>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Callback4(P1, P2, P3, P4) \
|
|
void export_Callback4_##P1##_##P2##_##P3##_##P4() \
|
|
|
|
|
|
#define export_Callback4(P1, P2, P3, P4) \
|
|
export_Callback4_##P1##_##P2##_##P3##_##P4() \
|
|
|
|
|
|
#define def_export_Gate4(P1, P2, P3, P4) \
|
|
\
|
|
struct Gate4Action_##P1##_##P2##_##P3##_##P4##_Py : public Gate4Action<P1, P2, P3, P4> { \
|
|
object o; \
|
|
virtual bool Execute(P1 p1, P2 p2, P3 p3, P4 p4) \
|
|
{ \
|
|
tuple args = make_tuple(p1, p2, p3, p4); \
|
|
return invoke<bool>(o.ptr(), args.ptr()); \
|
|
} \
|
|
Gate4Action_##P1##_##P2##_##P3##_##P4##_Py(PyObject *callable) : o(handle<>(borrowed(callable))) {} \
|
|
}; \
|
|
\
|
|
struct Gate4_##P1##_##P2##_##P3##_##P4##_from_python \
|
|
{ \
|
|
Gate4_##P1##_##P2##_##P3##_##P4##_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Gate4<P1, P2, P3, P4> >()); } \
|
|
\
|
|
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data) \
|
|
{ \
|
|
void* d = ((converter::rvalue_from_python_storage<Gate4<P1, P2, P3, P4> >*)data)->storage.bytes; \
|
|
\
|
|
if(po == Py_None) { new(d) Gate4<P1, P2, P3, P4>(); } \
|
|
else if(PyFunction_Check(po)) { new(d) Gate4<P1, P2, P3, P4>(new Gate4Action_##P1##_##P2##_##P3##_##P4##_Py(po)); } \
|
|
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Gate4<P1, P2, P3, P4>(new Gate4Action_##P1##_##P2##_##P3##_##P4##_Py(po)); } \
|
|
else { throw_error_already_set(); } \
|
|
\
|
|
data->convertible = d; \
|
|
} \
|
|
}; \
|
|
\
|
|
void export_Gate4_##P1##_##P2##_##P3##_##P4() \
|
|
{ \
|
|
ONCELOCK \
|
|
{ \
|
|
Gate4_##P1##_##P2##_##P3##_##P4##_from_python(); \
|
|
class_<Gate4<P1, P2, P3, P4> >("Gate4_"#P1"_"#P2"_"#P3"_"#P4, "Upp Gate4<"#P1","#P2","#P3","#P4">") \
|
|
.def(init<const Gate4<P1, P2, P3, P4>&>()) \
|
|
.def("clear", &Gate4<P1, P2, P3, P4>::Clear) \
|
|
.def("valid", &Gate4<P1, P2, P3, P4>::operator bool) \
|
|
.def("__call__", &Gate4<P1, P2, P3, P4>::Execute) \
|
|
; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define decl_export_Gate4(P1, P2, P3, P4) \
|
|
void export_Gate4_##P1##_##P2##_##P3##_##P4() \
|
|
|
|
|
|
#define export_Gate4(P1, P2, P3, P4) \
|
|
export_Gate4_##P1##_##P2##_##P3##_##P4() \
|
|
|
|
|
|
//
|
|
|
|
void export_Callback();
|
|
void export_Gate();
|
|
|
|
END_UPP_NAMESPACE
|
|
|
|
#endif
|