55inline bool IsTemplatedSTLClass(
const std::string&
name,
const std::string& klass) {
57 auto pos =
name.find(klass);
58 return (pos == 0 || pos == 5) &&
name.find(
"::",
name.rfind(
">")) == std::string::npos;
66 PyObject* result = PyObject_CallMethod(obj,
const_cast<char*
>(meth),
const_cast<char*
>(
""));
76 PyObject* result = PyObject_CallMethod(
77 obj,
const_cast<char*
>(meth),
const_cast<char*
>(
"O"), arg1);
91 if (idx >= size || (idx < 0 && idx < -size)) {
92 PyErr_SetString(PyExc_IndexError,
"index out of range");
101 pyindex = PyLong_FromSsize_t(size+idx);
110 if ((step > 0 && stop <= start) || (step < 0 && start <= stop))
113 if (start < 0) start = 0;
114 if (start >= nlen) start = nlen-1;
115 if (step >= nlen) step = nlen;
117 stop = step > 0 ? std::min(nlen, stop) : (stop >= 0 ? stop : -1);
132 PyObject* result = PyObject_CallMethodObjArgs((
PyObject*)self, pymeth, pyindex,
nullptr);
152 PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
160 PyObject* val1 = PyObject_Str(self);
162 PyErr_Format(PyExc_AttributeError,
"%s has no attribute \'%s\'",
182 PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
195#if PY_VERSION_HEX < 0x03040000
196#define PyObject_LengthHint _PyObject_LengthHint
201 ItemGetter(
PyObject* pyobj) : fPyObject(pyobj) { Py_INCREF(fPyObject); }
202 virtual ~ItemGetter() { Py_DECREF(fPyObject); }
208struct CountedItemGetter :
public ItemGetter {
209 CountedItemGetter(
PyObject* pyobj) : ItemGetter(pyobj), fCur(0) {}
213struct TupleItemGetter :
public CountedItemGetter {
214 using CountedItemGetter::CountedItemGetter;
215 virtual Py_ssize_t size() {
return PyTuple_GET_SIZE(fPyObject); }
217 if (fCur < PyTuple_GET_SIZE(fPyObject)) {
218 PyObject* item = PyTuple_GET_ITEM(fPyObject, fCur++);
222 PyErr_SetString(PyExc_StopIteration,
"end of tuple");
227struct ListItemGetter :
public CountedItemGetter {
228 using CountedItemGetter::CountedItemGetter;
229 virtual Py_ssize_t size() {
return PyList_GET_SIZE(fPyObject); }
231 if (fCur < PyList_GET_SIZE(fPyObject)) {
232 PyObject* item = PyList_GET_ITEM(fPyObject, fCur++);
236 PyErr_SetString(PyExc_StopIteration,
"end of list");
241struct SequenceItemGetter :
public CountedItemGetter {
242 using CountedItemGetter::CountedItemGetter;
251 virtual PyObject* get() {
return PySequence_GetItem(fPyObject, fCur++); }
254struct IterItemGetter :
public ItemGetter {
255 using ItemGetter::ItemGetter;
257 virtual PyObject* get() {
return (*(
Py_TYPE(fPyObject)->tp_iternext))(fPyObject); }
268 ItemGetter* getter =
nullptr;
269 if (PyTuple_GET_SIZE(args) == 1) {
270 PyObject* fi = PyTuple_GET_ITEM(args, 0);
272 PyErr_SetString(PyExc_TypeError,
"can not convert string to vector");
278 if (!PyObject_CheckBuffer(fi)) {
279 if (PyTuple_CheckExact(fi))
280 getter =
new TupleItemGetter(fi);
281 else if (PyList_CheckExact(fi))
282 getter =
new ListItemGetter(fi);
283 else if (PySequence_Check(fi))
284 getter =
new SequenceItemGetter(fi);
286 PyObject* iter = PyObject_GetIter(fi);
288 getter =
new IterItemGetter{iter};
299 PyObject* result = PyObject_CallMethodObjArgs(self, mname,
nullptr);
314 PyObject* res = PyObject_CallMethod(self, (
char*)
"reserve", (
char*)
"n", sz);
325 PyObject* fi = PySequence_GetItem(PyTuple_GET_ITEM(args, 0), 0);
326 if (!fi) PyErr_Clear();
327 if (fi && (PyTuple_CheckExact(fi) || PyList_CheckExact(fi))) {
329 PyObject* eb_call = PyObject_GetAttrString(self, (
char*)
"emplace_back");
331 bool value_is_vector =
false;
335 value_is_vector =
true;
342 for (
int i = 0; ; ++i) {
345 if (value_is_vector && PySequence_Check(item)) {
346 eb_args = PyTuple_New(1);
347 PyTuple_SET_ITEM(eb_args, 0, item);
348 }
else if (PyTuple_CheckExact(item)) {
350 }
else if (PyList_CheckExact(item)) {
352 eb_args = PyTuple_New(isz);
354 PyObject* iarg = PyList_GET_ITEM(item, j);
356 PyTuple_SET_ITEM(eb_args, j, iarg);
361 PyErr_Format(PyExc_TypeError,
"argument %d is not a tuple or list", i);
365 PyObject* ebres = PyObject_CallObject(eb_call, eb_args);
373 if (PyErr_Occurred()) {
374 if (!(PyErr_ExceptionMatches(PyExc_IndexError) ||
375 PyErr_ExceptionMatches(PyExc_StopIteration)))
377 else { PyErr_Clear(); }
386 PyObject* pb_call = PyObject_GetAttrString(self, (
char*)
"push_back");
391 PyObject* pbres = PyObject_CallFunctionObjArgs(pb_call, item,
nullptr);
399 if (PyErr_Occurred()) {
400 if (!(PyErr_ExceptionMatches(PyExc_IndexError) ||
401 PyErr_ExceptionMatches(PyExc_StopIteration)))
403 else { PyErr_Clear(); }
423 PyObject* realInit = PyObject_GetAttrString(self,
"__real_init");
425 PyObject* result = PyObject_Call(realInit, args,
nullptr);
445 long clen = PyInt_AsLong(pylen);
450 bi.len = clen * bi.itemsize;
451 if (bi.ndim == 1 && bi.shape)
461 if (!vi)
return nullptr;
465 vi->
vi_flags =
v->ob_refcnt <= 2 ? 1 : 0;
471 if (pyvalue_type && pyvalue_size) {
483 vi->
vi_stride = PyLong_AsLong(pyvalue_size);
491 Py_XDECREF(pyvalue_size);
492 Py_XDECREF(pyvalue_type);
495 vi->
ii_len = PySequence_Size(
v);
497 PyObject_GC_Track(vi);
504 if (PySlice_Check(index)) {
506 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
511 PyObject* nseq = PyObject_CallObject(pyclass,
nullptr);
517 if (!AdjustSlice(nlen, start, stop, step))
521 for (
Py_ssize_t i = start; i*sign < stop*sign; i += step) {
543 PyErr_Format(PyExc_TypeError,
544 "require object of type std::vector<bool>, but %s given",
550 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
554 if (PySlice_Check(idx)) {
556 PyObject* nseq = PyObject_CallObject(pyclass,
nullptr);
561 if (!AdjustSlice(nlen, start, stop, step))
565 for (
Py_ssize_t i = start; i*sign < stop*sign; i += step) {
580 int index = (
int)PyLong_AsLong(pyindex);
584 std::vector<bool>* vb = (std::vector<bool>*)self->
GetObject();
587 if (
bool((*vb)[index]))
597 PyErr_Format(PyExc_TypeError,
598 "require object of type std::vector<bool>, but %s given",
604 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
608 int bval = 0;
PyObject* idx =
nullptr;
609 if (!PyArg_ParseTuple(args,
const_cast<char*
>(
"Oi:__setitem__"), &idx, &bval))
616 int index = (
int)PyLong_AsLong(pyindex);
620 std::vector<bool>* vb = (std::vector<bool>*)self->
GetObject();
623 (*vb)[index] = (
bool)bval;
638 if (!PyObject_RichCompareBool(iter, end, Py_EQ)) {
677 if (!ii)
return nullptr;
682 ii->
ii_len = PySequence_Size(
c);
684 PyObject_GC_Track(ii);
721 long idx = PyLong_AsLong(pyindex);
722 if (idx == -1 && PyErr_Occurred())
726 PyErr_SetString(PyExc_TypeError,
"unsubscriptable object");
732 else if ((
int)idx == 1)
736 PyErr_SetString(PyExc_IndexError,
"out of bounds");
750 PyObject* realInit = PyObject_GetAttrString(self,
"__real_init");
752 PyObject* result = PyObject_Call(realInit, args,
nullptr);
754 if (result && PyTuple_GET_SIZE(args) == 1 &&
CPPInstance_Check(PyTuple_GET_ITEM(args, 0)))
755 PyObject_SetAttrString(PyTuple_GET_ITEM(args, 0),
"__python_owns__", Py_False);
763#if PY_VERSION_HEX >= 0x03000000
766 return !PyObject_RichCompareBool(one, other, Py_EQ);
769static inline PyObject* CPyCppyy_PyString_FromCppString(std::string*
s) {
773static inline PyObject* CPyCppyy_PyString_FromCppString(std::wstring*
s) {
774 return PyUnicode_FromWideChar(
s->c_str(),
s->size());
777#define CPPYY_IMPL_STRING_PYTHONIZATION(type, name) \
778static PyObject* name##StringGetData(PyObject* self) \
780 if (CPyCppyy::CPPInstance_Check(self)) { \
781 type* obj = ((type*)((CPPInstance*)self)->GetObject()); \
783 return CPyCppyy_PyString_FromCppString(obj); \
785 return CPPInstance_Type.tp_str(self); \
788 PyErr_Format(PyExc_TypeError, "object mismatch (%s expected)", #type); \
792PyObject* name##StringRepr(PyObject* self) \
794 PyObject* data = name##StringGetData(self); \
796 PyObject* repr = PyObject_Repr(data); \
803PyObject* name##StringIsEqual(PyObject* self, PyObject* obj) \
805 PyObject* data = name##StringGetData(self); \
807 PyObject* result = PyObject_RichCompare(data, obj, Py_EQ); \
814PyObject* name##StringIsNotEqual(PyObject* self, PyObject* obj) \
816 PyObject* data = name##StringGetData(self); \
818 PyObject* result = PyObject_RichCompare(data, obj, Py_NE); \
826#define CPPYY_IMPL_STRING_PYTHONIZATION_CMP(type, name) \
827CPPYY_IMPL_STRING_PYTHONIZATION(type, name) \
828PyObject* name##StringCompare(PyObject* self, PyObject* obj) \
830 PyObject* data = name##StringGetData(self); \
833 result = PyObject_Compare(data, obj); \
836 if (PyErr_Occurred()) \
838 return PyInt_FromLong(result); \
854 if (PyObject_RichCompareBool(last, self, Py_EQ) == 0) {
858 if (!next) PyErr_Clear();
873 int isNotEnd = PyObject_RichCompareBool(last, iter, Py_NE);
874 if (isNotEnd && !next) {
886 PyErr_SetString(PyExc_StopIteration,
"");
891 if (!next) PyErr_SetString(PyExc_StopIteration,
"");
897#define COMPLEX_METH_GETSET(name, cppname) \
898static PyObject* name##ComplexGet(PyObject* self, void*) { \
899 return PyObject_CallMethodObjArgs(self, cppname, nullptr); \
901static int name##ComplexSet(PyObject* self, PyObject* value, void*) { \
902 PyObject* result = PyObject_CallMethodObjArgs(self, cppname, value, nullptr);\
909PyGetSetDef name##Complex{(char*)#name, (getter)name##ComplexGet, (setter)name##ComplexSet, nullptr, nullptr};
916 if (!real)
return nullptr;
919 if (
r == -1. && PyErr_Occurred())
923 if (!imag)
return nullptr;
926 if (i == -1. && PyErr_Occurred())
929 return PyComplex_FromDoubles(
r, i);
934 if (!real)
return nullptr;
937 if (
r == -1. && PyErr_Occurred())
941 if (!imag)
return nullptr;
944 if (i == -1. && PyErr_Occurred())
947 std::ostringstream
s;
948 s <<
'(' <<
r <<
'+' << i <<
"j)";
960 if (
d == -1.0 && PyErr_Occurred())
962 ((std::complex<double>*)self->
GetObject())->real(
d);
966PyGetSetDef ComplexDReal{(
char*)
"real", (getter)ComplexDRealGet, (setter)ComplexDRealSet,
nullptr,
nullptr};
977 if (
d == -1.0 && PyErr_Occurred())
979 ((std::complex<double>*)self->
GetObject())->imag(
d);
983PyGetSetDef ComplexDImag{(
char*)
"imag", (getter)ComplexDImagGet, (setter)ComplexDImagSet,
nullptr,
nullptr};
987 double r = ((std::complex<double>*)self->
GetObject())->real();
988 double i = ((std::complex<double>*)self->
GetObject())->imag();
989 return PyComplex_FromDoubles(
r, i);
1025 if (!IsTemplatedSTLClass(
name,
"vector") &&
1026 !((PyTypeObject*)pyclass)->tp_iter) {
1036 if (resname.find(
"iterator") == std::string::npos)
1040 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)StlSequenceIter;
1045 if (!((PyTypeObject*)pyclass)->tp_iter &&
1051 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter;
1093 if (IsTemplatedSTLClass(
name,
"vector")) {
1097 if (klass->
fCppType == sVectorBoolTypeID) {
1103 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)VectorInit, METH_VARARGS | METH_KEYWORDS);
1116 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter;
1122 PyObject* pyvalue_size = PyLong_FromSsize_t(typesz);
1123 PyObject_SetAttrString(pyclass,
"value_size", pyvalue_size);
1124 Py_DECREF(pyvalue_size);
1127 PyObject_SetAttrString(pyclass,
"value_type", pyvalue_type);
1128 Py_DECREF(pyvalue_type);
1133 else if (IsTemplatedSTLClass(
name,
"map")) {
1137 else if (IsTemplatedSTLClass(
name,
"pair")) {
1142 if (IsTemplatedSTLClass(
name,
"shared_ptr")) {
1144 Utility::AddToClass(pyclass,
"__init__", (PyCFunction)SharedPtrInit, METH_VARARGS | METH_KEYWORDS);
1148 ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)StlIterNext;
1150 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter;
1154 else if (
name ==
"string" ||
name ==
"std::string") {
1162 else if (
name ==
"basic_string<wchar_t,char_traits<wchar_t>,allocator<wchar_t> >" || \
1163 name ==
"std::basic_string<wchar_t,char_traits<wchar_t>,allocator<wchar_t> >") {
1171 else if (
name ==
"complex<double>" ||
name ==
"std::complex<double>") {
1173 PyObject_SetAttrString(pyclass,
"real", PyDescr_NewGetSet((PyTypeObject*)pyclass, &ComplexDReal));
1175 PyObject_SetAttrString(pyclass,
"imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &ComplexDImag));
1180 else if (IsTemplatedSTLClass(
name,
"complex")) {
1182 PyObject_SetAttrString(pyclass,
"real", PyDescr_NewGetSet((PyTypeObject*)pyclass, &realComplex));
1184 PyObject_SetAttrString(pyclass,
"imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &imagComplex));
1192 bool bUserOk =
true;
PyObject* res =
nullptr;
1196 bUserOk = (
bool)res;
1200 res = PyObject_CallFunctionObjArgs(func, pyclass,
pyname,
nullptr);
1202 bUserOk = (
bool)res;
1217 PyTuple_SET_ITEM(args, 0, pyclass);
1221 bool pstatus =
true;
1225 PyTuple_SET_ITEM(args, 1,
pyname);
1228 name.substr(outer_scope.size()+2, std::string::npos).c_str()));
1233 for (
auto pythonizor : p->second) {
1234 PyObject* result = PyObject_CallObject(pythonizor, args);
#define PyInt_FromSsize_t
#define CPyCppyy_PyText_FromStringAndSize
#define CPyCppyy_PySliceCast
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_FromString
#define CPyCppyy_PyText_Check
#define CPPYY_IMPL_STRING_PYTHONIZATION_CMP(type, name)
#define COMPLEX_METH_GETSET(name, cppname)
#define PyObject_LengthHint
PyObject * CallPyObjMethod(PyObject *obj, const char *meth)
Set of helper functions that are invoked from the C++ implementation of pythonizations.
static RooMathCoreReg dummy
static PyObject * PyStyleIndex(PyObject *self, PyObject *index)
Cppyy::TCppType_t ObjectIsA(bool check_smart=true) const
Utility::PyOperators * fOperators
Cppyy::TCppType_t fCppType
std::string extract_namespace(const std::string &name)
Py_ssize_t GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, bool check=true)
bool AddToClass(PyObject *pyclass, const char *label, PyCFunction cfunc, int flags=METH_VARARGS)
PyTypeObject VectorIter_Type
bool Pythonize(PyObject *pyclass, const std::string &name)
bool CPPOverload_Check(T *object)
std::map< std::string, std::vector< PyObject * > > gPythonizations
bool LowLevelView_Check(T *object)
bool CPPInstance_Check(T *object)
PyTypeObject IndexIter_Type
std::set< std::string > gIteratorTypes
CPYCPPYY_EXTERN Converter * CreateConverter(const std::string &name, Py_ssize_t *dims=nullptr)
RPY_EXPORTED std::vector< TCppIndex_t > GetMethodIndicesFromName(TCppScope_t scope, const std::string &name)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
RPY_EXPORTED size_t SizeOf(TCppType_t klass)
RPY_EXPORTED std::string GetScopedFinalName(TCppType_t type)
RPY_EXPORTED bool IsSmartPtr(TCppType_t type)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
RPY_EXPORTED std::string GetMethodResultType(TCppMethod_t)
static constexpr double s
PyObject_HEAD PyObject * ii_container
Cppyy::TCppType_t vi_klass
CPyCppyy::Converter * vi_converter