25#if __cplusplus > 201402L
30#define UNKNOWN_SIZE -1
31#define UNKNOWN_ARRAY_SIZE -2
44#if PY_VERSION_HEX < 0x03000000
55struct CPyCppyy_tagCDataObject {
61struct CPyCppyy_tagPyCArgObject {
92#define ct_c_longlong 13
93#define ct_c_ulonglong 14
96#define ct_c_longdouble 17
98#define ct_c_wchar_p 19
100#define ct_c_complex 21
104 "c_bool",
"c_char",
"c_wchar",
"c_byte",
"c_ubyte",
"c_short",
"c_ushort",
"c_uint16",
105 "c_int",
"c_uint",
"c_uint32",
"c_long",
"c_ulong",
"c_longlong",
"c_ulonglong",
106 "c_float",
"c_double",
"c_longdouble",
107 "c_char_p",
"c_wchar_p",
"c_void_p",
"c_complex" };
117 static PyObject* ctmod = PyImport_ImportModule(
"ctypes");
124 ct_t = (PyTypeObject*)PyObject_GetAttrString(ctmod,
gCTypesNames[nidx]);
125 if (!ct_t) PyErr_Clear();
136 static PyObject* ctmod = PyImport_ImportModule(
"ctypes");
144 cpt_t = (PyTypeObject*)PyObject_GetAttrString(ctmod,
"c_char_p");
148 PyObject* ptrcreat = PyObject_GetAttrString(ctmod,
"POINTER");
149 cpt_t = (PyTypeObject*)PyObject_CallFunctionObjArgs(ptrcreat, ct_t, NULL);
163 static PyTypeObject* pycarg_type =
nullptr;
165 PyObject* ctmod = PyImport_ImportModule(
"ctypes");
166 if (!ctmod) PyErr_Clear();
168 PyTypeObject* ct_t = (PyTypeObject*)PyObject_GetAttrString(ctmod,
"c_int");
169 PyObject* cobj = ct_t->tp_new(ct_t,
nullptr,
nullptr);
170 PyObject* byref = PyObject_GetAttrString(ctmod,
"byref");
171 PyObject* pyptr = PyObject_CallFunctionObjArgs(byref, cobj, NULL);
172 Py_DECREF(byref); Py_DECREF(cobj); Py_DECREF(ct_t);
178 return Py_TYPE(pyobject) == pycarg_type;
183 static PyTypeObject* cstgdict_type =
nullptr;
184 if (!cstgdict_type) {
187 if (ct_int && ct_int->tp_dict) {
188 cstgdict_type =
Py_TYPE(ct_int->tp_dict);
192 PyTypeObject* pytype =
Py_TYPE(pyobject);
193 if (pytype->tp_dict &&
Py_TYPE(pytype->tp_dict) == cstgdict_type)
215 long l = PyLong_AsLong(pyobject);
217 if (!(
l == 0||
l == 1) || PyFloat_Check(pyobject)) {
218 PyErr_SetString(PyExc_ValueError,
"boolean value should be bool, or integer 1 or 0");
233 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
234 PyErr_SetString(PyExc_TypeError,
"short int conversion expects an integer object");
237 long l = PyLong_AsLong(pyobject);
238 if (
l < 0 || UCHAR_MAX <
l) {
239 PyErr_Format(PyExc_ValueError,
"integer %ld out of range for uint8_t",
l);
250 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
251 PyErr_SetString(PyExc_TypeError,
"short int conversion expects an integer object");
254 long l = PyLong_AsLong(pyobject);
255 if (
l < SCHAR_MIN || SCHAR_MAX <
l) {
256 PyErr_Format(PyExc_ValueError,
"integer %ld out of range for int8_t",
l);
268 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
269 PyErr_SetString(PyExc_TypeError,
"unsigned short conversion expects an integer object");
270 return (
unsigned short)-1;
272 long l = PyLong_AsLong(pyobject);
273 if (
l < 0 || USHRT_MAX <
l) {
274 PyErr_Format(PyExc_ValueError,
"integer %ld out of range for unsigned short",
l);
275 return (
unsigned short)-1;
278 return (
unsigned short)
l;
285 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
286 PyErr_SetString(PyExc_TypeError,
"short int conversion expects an integer object");
289 long l = PyLong_AsLong(pyobject);
290 if (
l < SHRT_MIN || SHRT_MAX <
l) {
291 PyErr_Format(PyExc_ValueError,
"integer %ld out of range for short int",
l);
305 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
306 PyErr_SetString(PyExc_TypeError,
"int/long conversion expects an integer object");
309 long l = PyLong_AsLong(pyobject);
310 if (
l < INT_MIN || INT_MAX <
l) {
311 PyErr_Format(PyExc_ValueError,
"integer %ld out of range for int",
l);
323 if (!(PyLong_Check(pyobject) || PyInt_Check(pyobject))) {
324 PyErr_SetString(PyExc_TypeError,
"int/long conversion expects an integer object");
327 return (
long)PyLong_AsLong(pyobject);
344 PyErr_Format(PyExc_TypeError,
345 "could not convert argument to buffer or nullptr");
369 PyTypeObject* pytype = (PyTypeObject*)
Py_TYPE(pyobject);
370 if (!(pytype == &PyList_Type || pytype == &PyTuple_Type)) {
387 Py_INCREF(pyobject); PyTuple_SET_ITEM(args, 0, pyobject);
391 if (!pytmp && PyTuple_CheckExact(pyobject)) {
395 pytmp = (
CPPInstance*)PyObject_Call(pyscope, pyobject, kwds);
425 PyErr_SetString(PyExc_TypeError,
"C++ type cannot be converted from memory");
433 PyErr_SetString(PyExc_TypeError,
"C++ type cannot be converted to memory");
439#define CPPYY_IMPL_BASIC_CONVERTER(name, type, stype, ctype, F1, F2, tc) \
440bool CPyCppyy::name##Converter::SetArg( \
441 PyObject* pyobject, Parameter& para, CallContext* ) \
444 type val = (type)F2(pyobject); \
445 if (val == (type)-1 && PyErr_Occurred()) { \
446 static PyTypeObject* ctypes_type = nullptr; \
447 if (!ctypes_type) { \
448 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0; \
449 PyErr_Fetch(&pytype, &pyvalue, &pytrace); \
450 ctypes_type = GetCTypesType(ct_##ctype); \
451 PyErr_Restore(pytype, pyvalue, pytrace); \
453 if (Py_TYPE(pyobject) == ctypes_type) { \
455 val = *((type*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr); \
459 para.fValue.f##name = val; \
460 para.fTypeCode = tc; \
464PyObject* CPyCppyy::name##Converter::FromMemory(void* address) \
466 return F1((stype)*((type*)address)); \
469bool CPyCppyy::name##Converter::ToMemory(PyObject* value, void* address) \
471 type s = (type)F2(value); \
472 if (s == (type)-1 && PyErr_Occurred()) \
474 *((type*)address) = (type)s; \
486 PyErr_Format(PyExc_ValueError,
"%s expected, got string of size " PY_SSIZE_T_FORMAT,
488 }
else if (!PyFloat_Check(pyobject)) {
489 lchar = (
int)PyLong_AsLong(pyobject);
490 if (lchar == -1 && PyErr_Occurred())
492 else if (!(low <= lchar && lchar <= high)) {
493 PyErr_Format(PyExc_ValueError,
494 "integer to character: value %d not in range [%d,%d]", lchar, low, high);
498 PyErr_SetString(PyExc_TypeError,
"char or small int type expected");
504#define CPPYY_IMPL_REFCONVERTER_FROM_MEMORY(name, ctype) \
505PyObject* CPyCppyy::name##RefConverter::FromMemory(void* ptr) \
508 PyTypeObject* ctypes_type = GetCTypesType(ct_##ctype); \
509 if (!ctypes_type) { \
510 PyErr_SetString(PyExc_RuntimeError, "no ctypes available"); \
513 PyObject* ref = ctypes_type->tp_new(ctypes_type, nullptr, nullptr); \
514 ((CPyCppyy_tagCDataObject*)ref)->b_ptr = (char*)ptr; \
515 ((CPyCppyy_tagCDataObject*)ref)->b_needsfree = 0; \
520#define CPPYY_IMPL_BASIC_CONST_REFCONVERTER(name, type, ctype, F1) \
521bool CPyCppyy::Const##name##RefConverter::SetArg( \
522 PyObject* pyobject, Parameter& para, CallContext* ) \
524 type val = (type)F1(pyobject); \
525 if (val == (type)-1 && PyErr_Occurred()) \
527 para.fValue.f##name = val; \
528 para.fRef = ¶.fValue.f##name; \
529 para.fTypeCode = 'r'; \
532CPPYY_IMPL_REFCONVERTER_FROM_MEMORY(Const##name, ctype)
535#define CPPYY_IMPL_BASIC_CONST_CHAR_REFCONVERTER(name, type, ctype, low, high)\
536bool CPyCppyy::Const##name##RefConverter::SetArg( \
537 PyObject* pyobject, Parameter& para, CallContext* ) \
540 type val = (type)ExtractChar(pyobject, #type, low, high); \
541 if (val == (type)-1 && PyErr_Occurred()) \
543 para.fValue.fLong = val; \
544 para.fTypeCode = 'l'; \
547CPPYY_IMPL_REFCONVERTER_FROM_MEMORY(Const##name, ctype)
551#define CPPYY_IMPL_BASIC_CHAR_CONVERTER(name, type, low, high) \
552bool CPyCppyy::name##Converter::SetArg( \
553 PyObject* pyobject, Parameter& para, CallContext* ) \
556 long val = ExtractChar(pyobject, #type, low, high); \
557 if (val == -1 && PyErr_Occurred()) \
559 para.fValue.fLong = val; \
560 para.fTypeCode = 'l'; \
564PyObject* CPyCppyy::name##Converter::FromMemory(void* address) \
566 return CPyCppyy_PyText_FromFormat("%c", *((type*)address)); \
569bool CPyCppyy::name##Converter::ToMemory(PyObject* value, void* address) \
572 const char* cstr = CPyCppyy_PyText_AsStringAndSize(value, &len); \
575 PyErr_Format(PyExc_TypeError, #type" expected, got string of size %zd", len);\
578 *((type*)address) = (type)cstr[0]; \
581 long l = PyLong_AsLong(value); \
582 if (l == -1 && PyErr_Occurred()) \
584 if (!(low <= l && l <= high)) { \
585 PyErr_Format(PyExc_ValueError, \
586 "integer to character: value %ld not in range [%d,%d]", l, low, high);\
589 *((type*)address) = (type)l; \
603#if PY_VERSION_HEX < 0x03000000
605 para.fValue.fVoidp = (
void*)&((PyIntObject*)pyobject)->ob_ival;
606 para.fTypeCode =
'V';
612 para.fValue.fVoidp = (
void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
613 para.fTypeCode =
'V';
618 para.fTypeCode =
'V';
622 PyErr_SetString(PyExc_TypeError,
"use ctypes.c_long for pass-by-ref of longs");
643bool CPyCppyy::IntRefConverter::SetArg(
647#if PY_VERSION_HEX < 0x03000000
649 para.
fValue.
fVoidp = (
void*)&((PyIntObject*)pyobject)->ob_ival;
655#if PY_VERSION_HEX >= 0x02050000
657 para.
fValue.
fVoidp = (
void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
670#if PY_VERSION_HEX < 0x02050000
671 PyErr_SetString(PyExc_TypeError,
"use cppyy.Long for pass-by-ref of ints");
673 PyErr_SetString(PyExc_TypeError,
"use ctypes.c_int for pass-by-ref of ints");
679#define CPPYY_IMPL_REFCONVERTER(name, ctype, type, code) \
680bool CPyCppyy::name##RefConverter::SetArg( \
681 PyObject* pyobject, Parameter& para, CallContext* ) \
684 if (Py_TYPE(pyobject) == GetCTypesType(ct_##ctype)) { \
685 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
686 para.fTypeCode = 'V'; \
689 bool res = CArraySetArg(pyobject, para, code, sizeof(type)); \
691 PyErr_SetString(PyExc_TypeError, "use ctypes."#ctype" for pass-by-ref of "#type);\
694 para.fTypeCode = 'V'; \
697CPPYY_IMPL_REFCONVERTER_FROM_MEMORY(name, ctype)
738bool CPyCppyy::WCharConverter::SetArg(
742 if (!PyUnicode_Check(pyobject) || PyUnicode_GET_SIZE(pyobject) != 1) {
743 PyErr_SetString(PyExc_ValueError,
"single wchar_t character expected");
755PyObject* CPyCppyy::WCharConverter::FromMemory(
void* address)
757 return PyUnicode_FromWideChar((
const wchar_t*)address, 1);
760bool CPyCppyy::WCharConverter::ToMemory(
PyObject* value,
void* address)
762 if (!PyUnicode_Check(value) || PyUnicode_GET_SIZE(value) != 1) {
763 PyErr_SetString(PyExc_ValueError,
"single wchar_t character expected");
770 *((
wchar_t*)address) = val;
775bool CPyCppyy::Char16Converter::SetArg(
779 if (!PyUnicode_Check(pyobject) || PyUnicode_GET_SIZE(pyobject) != 1) {
780 PyErr_SetString(PyExc_ValueError,
"single char16_t character expected");
784 PyObject* bstr = PyUnicode_AsUTF16String(pyobject);
785 if (!bstr)
return false;
794PyObject* CPyCppyy::Char16Converter::FromMemory(
void* address)
796 return PyUnicode_DecodeUTF16((
const char*)address,
sizeof(
char16_t),
nullptr,
nullptr);
799bool CPyCppyy::Char16Converter::ToMemory(
PyObject* value,
void* address)
801 if (!PyUnicode_Check(value) || PyUnicode_GET_SIZE(value) != 1) {
802 PyErr_SetString(PyExc_ValueError,
"single char16_t character expected");
806 PyObject* bstr = PyUnicode_AsUTF16String(value);
807 if (!bstr)
return false;
809 *((
char16_t*)address) = *(
char16_t*)(
PyBytes_AS_STRING(bstr) +
sizeof(char16_t) );
815bool CPyCppyy::Char32Converter::SetArg(
819 if (!PyUnicode_Check(pyobject) || 2 < PyUnicode_GET_SIZE(pyobject)) {
820 PyErr_SetString(PyExc_ValueError,
"single char32_t character expected");
824 PyObject* bstr = PyUnicode_AsUTF32String(pyobject);
825 if (!bstr)
return false;
834PyObject* CPyCppyy::Char32Converter::FromMemory(
void* address)
836 return PyUnicode_DecodeUTF32((
const char*)address,
sizeof(
char32_t),
nullptr,
nullptr);
839bool CPyCppyy::Char32Converter::ToMemory(
PyObject* value,
void* address)
841 if (!PyUnicode_Check(value) || 2 < PyUnicode_GET_SIZE(value)) {
842 PyErr_SetString(PyExc_ValueError,
"single char32_t character expected");
846 PyObject* bstr = PyUnicode_AsUTF32String(value);
847 if (!bstr)
return false;
849 *((
char32_t*)address) = *(
char32_t*)(
PyBytes_AS_STRING(bstr) +
sizeof(char32_t) );
867bool CPyCppyy::ULongConverter::SetArg(
872 if (para.fValue.fULong == (
unsigned long)-1 && PyErr_Occurred())
874 para.fTypeCode =
'L';
878PyObject* CPyCppyy::ULongConverter::FromMemory(
void* address)
881 return PyLong_FromUnsignedLong(*((
unsigned long*)address));
884bool CPyCppyy::ULongConverter::ToMemory(
PyObject* value,
void* address)
888 if (u == (
unsigned long)-1 && PyErr_Occurred())
890 *((
unsigned long*)address) = u;
895PyObject* CPyCppyy::UIntConverter::FromMemory(
void* address)
898 return PyLong_FromUnsignedLong(*((
UInt_t*)address));
901bool CPyCppyy::UIntConverter::ToMemory(
PyObject* value,
void* address)
905 if (u == (
unsigned long)-1 && PyErr_Occurred())
909 PyErr_SetString(PyExc_OverflowError,
"value too large for unsigned int");
926CPyCppyy::ComplexDConverter::ComplexDConverter(
bool keepControl) :
927 InstanceConverter(
Cppyy::
GetScope("std::complex<
double>"), keepControl) {}
930bool CPyCppyy::ComplexDConverter::SetArg(
933 const Py_complex&
pc = PyComplex_AsCComplex(pyobject);
934 if (
pc.real != -1.0 || !PyErr_Occurred()) {
942 return this->InstanceConverter::SetArg(pyobject, para, ctxt);
945PyObject* CPyCppyy::ComplexDConverter::FromMemory(
void* address)
947 std::complex<double>* dc = (std::complex<double>*)address;
948 return PyComplex_FromDoubles(dc->real(), dc->imag());
951bool CPyCppyy::ComplexDConverter::ToMemory(
PyObject* value,
void* address)
953 const Py_complex&
pc = PyComplex_AsCComplex(value);
954 if (
pc.real != -1.0 || !PyErr_Occurred()) {
955 std::complex<double>* dc = (std::complex<double>*)address;
960 return this->InstanceConverter::ToMemory(value, address);
964bool CPyCppyy::DoubleRefConverter::SetArg(
969 para.
fValue.
fVoidp = (
void*)&((PyFloatObject*)pyobject)->ob_fval;
981#if PY_VERSION_HEX < 0x02050000
982 PyErr_SetString(PyExc_TypeError,
"use cppyy.Double for pass-by-ref of doubles");
984 PyErr_SetString(PyExc_TypeError,
"use ctypes.c_double for pass-by-ref of doubles");
998 PyErr_SetString(PyExc_SystemError,
"void/unknown arguments can\'t be set");
1003bool CPyCppyy::LLongConverter::SetArg(
1007 if (PyFloat_Check(pyobject)) {
1010 PyErr_SetString(PyExc_ValueError,
"cannot convert float to long long");
1015 if (PyErr_Occurred())
1021PyObject* CPyCppyy::LLongConverter::FromMemory(
void* address)
1024 return PyLong_FromLongLong(*(
Long64_t*)address);
1027bool CPyCppyy::LLongConverter::ToMemory(
PyObject* value,
void* address)
1030 Long64_t ll = PyLong_AsLongLong(value);
1031 if (ll == -1 && PyErr_Occurred())
1038bool CPyCppyy::ULLongConverter::SetArg(
1043 if (PyErr_Occurred())
1049PyObject* CPyCppyy::ULLongConverter::FromMemory(
void* address)
1052 return PyLong_FromUnsignedLongLong(*(
ULong64_t*)address);
1055bool CPyCppyy::ULLongConverter::ToMemory(
PyObject* value,
void* address)
1059 if (PyErr_Occurred())
1066bool CPyCppyy::CStringConverter::SetArg(
1074 PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
1075 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
1077 para.
fValue.
fVoidp = (
void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
1079 Py_XDECREF(pytype); Py_XDECREF(pyvalue); Py_XDECREF(pytrace);
1082 PyErr_Restore(pytype, pyvalue, pytrace);
1086 fBuffer = std::string(cstr, len);
1090 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"string too long for char array (truncated)");
1100PyObject* CPyCppyy::CStringConverter::FromMemory(
void* address)
1103 if (address && *(
char**)address) {
1105 std::string buf(*(
char**)address,
fMaxSize);
1117bool CPyCppyy::CStringConverter::ToMemory(
PyObject* value,
void* address)
1122 if (!cstr)
return false;
1126 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"string too long for char array (truncated)");
1129 strncpy(*(
char**)address, cstr,
fMaxSize);
1132 strcpy(*(
char**)address, cstr);
1138bool CPyCppyy::WCStringConverter::SetArg(
1142 Py_ssize_t len = PyUnicode_GetSize(pyobject);
1143 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1158PyObject* CPyCppyy::WCStringConverter::FromMemory(
void* address)
1161 if (address && *(
wchar_t**)address) {
1163 return PyUnicode_FromWideChar(*(
wchar_t**)address,
fMaxSize);
1165 return PyUnicode_FromWideChar(*(
wchar_t**)address, wcslen(*(
wchar_t**)address));
1170 return PyUnicode_FromWideChar(&w, 0);
1173bool CPyCppyy::WCStringConverter::ToMemory(
PyObject* value,
void* address)
1177 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1182 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"string too long for wchar_t array (truncated)");
1191 if (res == -1)
return false;
1196bool CPyCppyy::CString16Converter::SetArg(
1200 Py_ssize_t len = PyUnicode_GetSize(pyobject);
1201 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1204 PyObject* bstr = PyUnicode_AsUTF16String(pyobject);
1205 if (!bstr)
return false;
1218PyObject* CPyCppyy::CString16Converter::FromMemory(
void* address)
1221 if (address && *(
char16_t**)address) {
1223 return PyUnicode_DecodeUTF16(*(
const char**)address,
fMaxSize,
nullptr,
nullptr);
1225 return PyUnicode_DecodeUTF16(*(
const char**)address,
1226 std::char_traits<char16_t>::length(*(
char16_t**)address)*
sizeof(
char16_t),
nullptr,
nullptr);
1231 return PyUnicode_DecodeUTF16((
const char*)&w, 0,
nullptr,
nullptr);
1234bool CPyCppyy::CString16Converter::ToMemory(
PyObject* value,
void* address)
1238 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1243 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"string too long for char16_t array (truncated)");
1247 PyObject* bstr = PyUnicode_AsUTF16String(value);
1248 if (!bstr)
return false;
1250 memcpy(*((
void**)address),
PyBytes_AS_STRING(bstr) +
sizeof(
char16_t) , len*
sizeof(
char16_t));
1252 *((
char16_t**)address)[len] = u
'\0';
1257bool CPyCppyy::CString32Converter::SetArg(
1261 Py_ssize_t len = PyUnicode_GetSize(pyobject);
1262 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1265 PyObject* bstr = PyUnicode_AsUTF32String(pyobject);
1266 if (!bstr)
return false;
1279PyObject* CPyCppyy::CString32Converter::FromMemory(
void* address)
1282 if (address && *(
char32_t**)address) {
1284 return PyUnicode_DecodeUTF32(*(
const char**)address,
fMaxSize,
nullptr,
nullptr);
1286 return PyUnicode_DecodeUTF32(*(
const char**)address,
1287 std::char_traits<char32_t>::length(*(
char32_t**)address)*
sizeof(
char32_t),
nullptr,
nullptr);
1292 return PyUnicode_DecodeUTF32((
const char*)&w, 0,
nullptr,
nullptr);
1295bool CPyCppyy::CString32Converter::ToMemory(
PyObject* value,
void* address)
1299 if (len == (
Py_ssize_t)-1 && PyErr_Occurred())
1304 PyErr_Warn(PyExc_RuntimeWarning, (
char*)
"string too long for char32_t array (truncated)");
1308 PyObject* bstr = PyUnicode_AsUTF32String(value);
1309 if (!bstr)
return false;
1311 memcpy(*((
void**)address),
PyBytes_AS_STRING(bstr) +
sizeof(
char32_t) , len*
sizeof(
char32_t));
1313 *((
char32_t**)address)[len] = U
'\0';
1319bool CPyCppyy::NonConstCStringConverter::SetArg(
1323 if (this->CStringConverter::SetArg(pyobject, para, ctxt))
1328 return CArraySetArg(pyobject, para,
'c',
sizeof(
char));
1332PyObject* CPyCppyy::NonConstCStringConverter::FromMemory(
void* address)
1337 return this->CStringConverter::FromMemory(address);
1350 if (PyInt_CheckExact(pyobject) || PyLong_CheckExact(pyobject)) {
1351 intptr_t val = (intptr_t)PyLong_AsLongLong(pyobject);
1353 address = (
void*)val;
1387 if (GetAddressSpecialCase(pyobject, para.
fValue.
fVoidp)) {
1396 para.
fValue.
fVoidp = (
void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
1403 void** payload = (
void**)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;
1428 if (!address || *(ptrdiff_t*)address == 0) {
1451 void* ptr =
nullptr;
1452 if (GetAddressSpecialCase(value, ptr)) {
1453 *(
void**)address = ptr;
1458 void* buf =
nullptr;
1460 if (!buf || buflen == 0)
1463 *(
void**)address = buf;
1468#define CPPYY_IMPL_ARRAY_CONVERTER(name, ctype, type, code) \
1469CPyCppyy::name##ArrayConverter::name##ArrayConverter(dims_t dims) { \
1470 int nalloc = (dims && 0 < dims[0]) ? (int)dims[0]+1: 2; \
1471 fShape = new Py_ssize_t[nalloc]; \
1473 for (int i = 0; i < nalloc; ++i) fShape[i] = (Py_ssize_t)dims[i]; \
1475 fShape[0] = 1; fShape[1] = -1; \
1479bool CPyCppyy::name##ArrayConverter::SetArg( \
1480 PyObject* pyobject, Parameter& para, CallContext* ) \
1483 PyTypeObject* ctypes_type = GetCTypesType(ct_##ctype); \
1484 if (Py_TYPE(pyobject) == ctypes_type) { \
1485 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
1486 para.fTypeCode = 'p'; \
1488 } else if (Py_TYPE(pyobject) == GetCTypesPtrType(ct_##ctype)) { \
1489 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
1490 para.fTypeCode = 'V'; \
1492 } else if (IsPyCArgObject(pyobject)) { \
1493 CPyCppyy_tagPyCArgObject* carg = (CPyCppyy_tagPyCArgObject*)pyobject;\
1494 if (carg->obj && Py_TYPE(carg->obj) == ctypes_type) { \
1495 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)carg->obj)->b_ptr;\
1496 para.fTypeCode = 'p'; \
1500 return CArraySetArg(pyobject, para, code, sizeof(type)); \
1503PyObject* CPyCppyy::name##ArrayConverter::FromMemory(void* address) \
1505 if (fShape[1] == UNKNOWN_SIZE) \
1506 return CreateLowLevelView((type**)address, fShape); \
1507 return CreateLowLevelView(*(type**)address, fShape); \
1510bool CPyCppyy::name##ArrayConverter::ToMemory(PyObject* value, void* address)\
1512 if (fShape[0] != 1) { \
1513 PyErr_SetString(PyExc_ValueError, "only 1-dim arrays supported"); \
1516 void* buf = nullptr; \
1517 Py_ssize_t buflen = Utility::GetBuffer(value, code, sizeof(type), buf); \
1520 if (0 <= fShape[1]) { \
1521 if (fShape[1] < buflen) { \
1522 PyErr_SetString(PyExc_ValueError, "buffer too large for value"); \
1525 memcpy(*(type**)address, buf, (0 < buflen ? buflen : 1)*sizeof(type));\
1527 *(type**)address = (type*)buf; \
1531bool CPyCppyy::name##ArrayPtrConverter::SetArg( \
1532 PyObject* pyobject, Parameter& para, CallContext* ctxt ) \
1534 if (Py_TYPE(pyobject) == GetCTypesPtrType(ct_##ctype)) { \
1535 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
1536 para.fTypeCode = 'p'; \
1538 } else if (Py_TYPE(pyobject) == GetCTypesType(ct_c_void_p)) { \
1540 para.fValue.fVoidp = (void*)((CPyCppyy_tagCDataObject*)pyobject)->b_ptr;\
1541 para.fTypeCode = 'p'; \
1544 bool res = name##ArrayConverter::SetArg(pyobject, para, ctxt); \
1545 if (res && para.fTypeCode == 'p') { \
1546 para.fRef = para.fValue.fVoidp; \
1547 para.fValue.fVoidp = ¶.fRef; \
1558#if __cplusplus > 201402L
1598#define CPPYY_IMPL_STRING_AS_PRIMITIVE_CONVERTER(name, type, F1, F2) \
1599CPyCppyy::name##Converter::name##Converter(bool keepControl) : \
1600 InstanceConverter(Cppyy::GetScope(#type), keepControl) {} \
1602bool CPyCppyy::name##Converter::SetArg( \
1603 PyObject* pyobject, Parameter& para, CallContext* ctxt) \
1606 const char* cstr = CPyCppyy_PyText_AsStringAndSize(pyobject, &len); \
1608 fBuffer = type(cstr, len); \
1609 para.fValue.fVoidp = &fBuffer; \
1610 para.fTypeCode = 'V'; \
1615 if (!(PyInt_Check(pyobject) || PyLong_Check(pyobject))) { \
1616 bool result = InstanceConverter::SetArg(pyobject, para, ctxt); \
1617 para.fTypeCode = 'V'; \
1623PyObject* CPyCppyy::name##Converter::FromMemory(void* address) \
1626 return CPyCppyy_PyText_FromStringAndSize(((type*)address)->F1(), ((type*)address)->F2()); \
1627 Py_INCREF(PyStrings::gEmptyString); \
1628 return PyStrings::gEmptyString; \
1631bool CPyCppyy::name##Converter::ToMemory(PyObject* value, void* address) \
1633 if (CPyCppyy_PyText_Check(value)) { \
1634 *((type*)address) = CPyCppyy_PyText_AsString(value); \
1638 return InstanceConverter::ToMemory(value, address); \
1644bool CPyCppyy::STLStringViewConverter::SetArg(
1647 if (this->STLStringViewBaseConverter::SetArg(pyobject, para, ctxt))
1660 fBuffer = *((std::string*)ptr);
1669CPyCppyy::STLWStringConverter::STLWStringConverter(
bool keepControl) :
1670 InstanceConverter(
Cppyy::
GetScope(
"std::wstring"), keepControl) {}
1672bool CPyCppyy::STLWStringConverter::SetArg(
1675 if (PyUnicode_Check(pyobject)) {
1676 Py_ssize_t len = PyUnicode_GET_SIZE(pyobject);
1684 if (!(PyInt_Check(pyobject) || PyLong_Check(pyobject))) {
1685 bool result = InstancePtrConverter::SetArg(pyobject, para, ctxt);
1693PyObject* CPyCppyy::STLWStringConverter::FromMemory(
void* address)
1696 return PyUnicode_FromWideChar(((std::wstring*)address)->c_str(), ((std::wstring*)address)->size());
1698 return PyUnicode_FromWideChar(&w, 0);
1701bool CPyCppyy::STLWStringConverter::ToMemory(
PyObject* value,
void* address)
1703 if (PyUnicode_Check(value)) {
1705 wchar_t* buf =
new wchar_t[len+1];
1707 *((std::wstring*)address) = std::wstring(buf, len);
1711 return InstanceConverter::ToMemory(value, address);
1715bool CPyCppyy::STLStringMoveConverter::SetArg(
1719 int moveit_reason = 3;
1722 if (pyobj->
fFlags & CPPInstance::kIsRValue) {
1731 if (moveit_reason) {
1732 bool result = this->STLStringConverter::SetArg(pyobject, para, ctxt);
1733 if (!result && moveit_reason == 2)
1734 ((
CPPInstance*)pyobject)->fFlags |= CPPInstance::kIsRValue;
1738 PyErr_SetString(PyExc_ValueError,
"object is not an rvalue");
1792 void* ptr =
nullptr;
1793 if (GetAddressSpecialCase(value, ptr)) {
1794 *(
void**)address = ptr;
1817bool CPyCppyy::InstanceConverter::SetArg(
1843PyObject* CPyCppyy::InstanceConverter::FromMemory(
void* address)
1849bool CPyCppyy::InstanceConverter::ToMemory(
PyObject* value,
void* address)
1853 PyObject* result = PyObject_CallMethod(pyobj, (
char*)
"__assign__", (
char*)
"O", value);
1865bool CPyCppyy::InstanceRefConverter::SetArg(
1896PyObject* CPyCppyy::InstanceRefConverter::FromMemory(
void* address)
1902bool CPyCppyy::InstanceMoveConverter::SetArg(
1913 int moveit_reason = 0;
1921 if (moveit_reason) {
1922 bool result = this->InstanceRefConverter::SetArg(pyobject, para, ctxt);
1923 if (!result && moveit_reason == 2)
1928 PyErr_SetString(PyExc_ValueError,
"object is not an rvalue");
1933template <
bool ISREFERENCE>
1934bool CPyCppyy::InstancePtrPtrConverter<ISREFERENCE>::SetArg(
1952 para.
fTypeCode = ISREFERENCE ?
'V' :
'p';
1960template <
bool ISREFERENCE>
1961PyObject* CPyCppyy::InstancePtrPtrConverter<ISREFERENCE>::FromMemory(
void* address)
1968template <
bool ISREFERENCE>
1969bool CPyCppyy::InstancePtrPtrConverter<ISREFERENCE>::ToMemory(
PyObject* value,
void* address)
1995 template class CPyCppyy::InstancePtrPtrConverter<true>;
1996 template class CPyCppyy::InstancePtrPtrConverter<false>;
2000bool CPyCppyy::InstanceArrayConverter::SetArg(
2009 if (PyTuple_Size(pyobject) < 1)
2027PyObject* CPyCppyy::InstanceArrayConverter::FromMemory(
void* address)
2034bool CPyCppyy::InstanceArrayConverter::ToMemory(
PyObject* ,
void* )
2039 PyErr_SetString(PyExc_NotImplementedError,
2040 "access to C-arrays of objects not yet implemented!");
2047bool CPyCppyy::STLIteratorConverter::SetArg(
2062bool CPyCppyy::VoidPtrRefConverter::SetArg(
2077bool CPyCppyy::VoidPtrPtrConverter::SetArg(
2088 CPyCppyy_tagPyCArgObject* carg = (CPyCppyy_tagPyCArgObject*)pyobject;
2090 para.
fValue.
fVoidp = (
void*)((CPyCppyy_tagCDataObject*)carg->obj)->b_ptr;
2110PyObject* CPyCppyy::VoidPtrPtrConverter::FromMemory(
void* address)
2113 if (!address || *(ptrdiff_t*)address == 0) {
2121bool CPyCppyy::PyObjectConverter::SetArg(
2130PyObject* CPyCppyy::PyObjectConverter::FromMemory(
void* address)
2139 Py_INCREF(pyobject);
2143bool CPyCppyy::PyObjectConverter::ToMemory(
PyObject* value,
void* address)
2147 Py_XDECREF(*((
PyObject**)address));
2167 void* wpraddress = ipos->second.first;
2169 sWrapperFree[ipos->second.second].push_back(wpraddress);
2175 const_cast<char*
>(
"interal_WrapperCacheEraser"),
2181 const std::string& rettype,
const std::string& signature)
2200 void* fptr = (
void*)
m->GetFunctionAddress();
2201 if (fptr)
return fptr;
2217 if (fptr)
return fptr;
2222 if (PyCallable_Check(pyobject)) {
2224 void* wpraddress =
nullptr;
2227 auto key = std::make_pair(rettype, signature);
2230 const auto& existing = lookup->second.find(pyobject);
2231 if (existing != lookup->second.end() && *
sWrapperReference[existing->second] == pyobject)
2232 wpraddress = existing->second;
2238 if (freewrap !=
sWrapperFree.end() && !freewrap->second.empty()) {
2239 wpraddress = freewrap->second.back();
2240 freewrap->second.pop_back();
2242 PyObject* wref = PyWeakref_NewRef(pyobject, sWrapperCacheEraser);
2255 int nArgs = (
int)argtypes.size();
2258 std::ostringstream wname;
2262 std::ostringstream code;
2263 code <<
"namespace __cppyy_internal {\n "
2264 << rettype <<
" " << wname.str() <<
"(";
2265 for (
int i = 0; i < nArgs; ++i) {
2266 code << argtypes[i] <<
" arg" << i;
2267 if (i != nArgs-1) code <<
", ";
2278 code <<
" PyObject** ref = (PyObject**)" << (intptr_t)ref <<
";\n"
2279 " PyObject* pyresult = nullptr;\n"
2280 " if (*ref) pyresult = PyObject_CallFunctionObjArgs(*ref";
2281 for (
int i = 0; i < nArgs; ++i)
2282 code <<
", pyargs[" << i <<
"]";
2283 code <<
", NULL);\n"
2284 " else PyErr_SetString(PyExc_TypeError, \"callable was deleted\");\n";
2304 PyObject* wref = PyWeakref_NewRef(pyobject, sWrapperCacheEraser);
2316bool CPyCppyy::FunctionPointerConverter::SetArg(
2339PyObject* CPyCppyy::FunctionPointerConverter::FromMemory(
void* address)
2344 static int func_count = 0;
2346 if (!(address && *(
void**)address)) {
2351 void* faddr = *(
void**)address;
2354 std::ostringstream fname;
2355 fname <<
"ptr2func" << ++func_count;
2357 std::ostringstream code;
2358 code <<
"namespace __cppyy_internal {\n std::function<"
2376 PyObject* func = PyObject_GetAttrString(pyscope, cached->second.c_str());
2382bool CPyCppyy::FunctionPointerConverter::ToMemory(
PyObject* pyobject,
void* address)
2386 *((
void**)address) =
nullptr;
2393 *((
void**)address) = fptr;
2402bool CPyCppyy::StdFunctionConverter::SetArg(
2416 if (this->FunctionPointerConverter::SetArg(pyobject, para, ctxt)) {
2432PyObject* CPyCppyy::StdFunctionConverter::FromMemory(
void* address)
2437bool CPyCppyy::StdFunctionConverter::ToMemory(
PyObject* value,
void* address)
2444bool CPyCppyy::SmartPtrConverter::SetArg(
2447 char typeCode =
fIsRef ?
'p' :
'V';
2506PyObject* CPyCppyy::SmartPtrConverter::FromMemory(
void* address)
2519#if defined (_LIBCPP_INITIALIZER_LIST) || defined(__GNUC__)
2522 typedef size_t size_type;
2523 typedef void* iterator;
2527#elif defined (_MSC_VER)
2530 typedef char* iterator;
2535#define NO_KNOWN_INITIALIZER_LIST 1
2540CPyCppyy::InitializerListConverter::~InitializerListConverter()
2545bool CPyCppyy::InitializerListConverter::SetArg(
2548#ifdef NO_KNOWN_INITIALIZER_LIST
2555#
if PY_VERSION_HEX >= 0x03000000
2563 faux_initlist* fake =
nullptr;
2564 if (buf && buflen) {
2566 fake = (faux_initlist*)
malloc(
sizeof(faux_initlist));
2567 fake->_M_array = (faux_initlist::iterator)buf;
2568#if defined (_LIBCPP_INITIALIZER_LIST) || defined(__GNUC__)
2569 fake->_M_len = (faux_initlist::size_type)buflen;
2570#elif defined (_MSC_VER)
2571 fake->_Last = fake->_M_array+buflen*
fValueSize;
2575 size_t len = (size_t)PySequence_Size(pyobject);
2577 fake->_M_array = (faux_initlist::iterator)((
char*)fake+
sizeof(faux_initlist));
2578#if defined (_LIBCPP_INITIALIZER_LIST) || defined(__GNUC__)
2579 fake->_M_len = (faux_initlist::size_type)len;
2580 for (faux_initlist::size_type i = 0; i < fake->_M_len; ++i) {
2581#elif defined (_MSC_VER)
2583 for (
size_t i = 0; (fake->_M_array+i*
fValueSize) != fake->_Last; ++i) {
2585 PyObject* item = PySequence_GetItem(pyobject, i);
2586 bool convert_ok =
false;
2600 PyErr_Format(PyExc_TypeError,
"failed to get item %d from sequence", (
int)i);
2619 PyErr_SetString(PyExc_NotImplementedError,
"this method cannot (yet) be called");
2631 if (cpd ==
"**" || cpd ==
"*[]" || cpd ==
"&*")
2632 result =
new InstancePtrPtrConverter<false>(klass, control);
2633 else if (cpd ==
"*&")
2634 result =
new InstancePtrPtrConverter<true>(klass, control);
2635 else if (cpd ==
"*" && size <= 0)
2637 else if (cpd ==
"&")
2638 result =
new InstanceRefConverter(klass, isConst);
2639 else if (cpd ==
"&&")
2640 result =
new InstanceMoveConverter(klass);
2641 else if (cpd ==
"[]" || size > 0)
2642 result =
new InstanceArrayConverter(klass, dims,
false);
2644 result =
new InstanceConverter(klass,
true);
2662 dim_t size = (dims && dims[0] != -1) ? dims[1] : -1;
2667 return (
h->second)(dims);
2673 if (resolvedType != fullType) {
2676 return (
h->second)(dims);
2680 bool isConst = strncmp(resolvedType.c_str(),
"const", 5) == 0;
2687 return (
h->second)(dims);
2695 return (
h->second)(dims);
2704 return (
h->second)(dims);
2706 }
else if (cpd ==
"*[]") {
2712 dim_t newdim = (dims && 0 < dims[0]) ? dims[0]+1 : 2;
2714 newdims[0] = newdim;
2717 if (dims && 2 < newdim) {
2718 for (
int i = 2; i < (newdim-1); ++i)
2719 newdims[i+1] = dims[i];
2728 if (realType.compare(0, 16,
"initializer_list") == 0) {
2730 auto pos = realType.find(
'<');
2731 std::string value_type = realType.substr(pos+1, realType.size()-pos-2);
2732 Converter* cnv =
nullptr;
bool use_byte_cnv =
false;
2738 use_byte_cnv =
true;
2741 if (cnv || use_byte_cnv)
2742 return new InitializerListConverter(cnv,
Cppyy::SizeOf(value_type));
2746 bool control = cpd ==
"&" || isConst;
2749 auto pos = resolvedType.find(
"function<");
2750 if (pos == 0 || pos == 5 ||
2751 pos == 6 || pos == 11 ) {
2759 auto pos1 = resolvedType.find(
"(", pos+9);
2760 auto pos2 = resolvedType.rfind(
")");
2761 if (pos1 != std::string::npos && pos2 != std::string::npos) {
2762 auto sz1 = pos1-pos-9;
2763 if (resolvedType[pos+9+sz1-1] ==
' ') sz1 -= 1;
2765 return new StdFunctionConverter(cnv,
2766 resolvedType.substr(pos+9, sz1), resolvedType.substr(pos1, pos2-pos1+1));
2777 result =
new SmartPtrConverter(klass, raw, control);
2778 }
else if (cpd ==
"&") {
2779 result =
new SmartPtrConverter(klass, raw);
2780 }
else if (cpd ==
"*" && size <= 0) {
2781 result =
new SmartPtrConverter(klass, raw, control,
true);
2787 if (realType.rfind(
"__gnu_cxx::__normal_iterator", 0) == 0
2789 || realType.rfind(
"__wrap_iter", 0) == 0
2793 static STLIteratorConverter
c;
2799 }
else if (resolvedType.find(
"(*)") != std::string::npos ||
2800 (resolvedType.find(
"::*)") != std::string::npos)) {
2803 auto pos1 = resolvedType.find(
'(');
2804 auto pos2 = resolvedType.find(
"*)");
2805 auto pos3 = resolvedType.rfind(
')');
2806 result =
new FunctionPointerConverter(
2807 resolvedType.substr(0, pos1), resolvedType.substr(pos2+2, pos3-pos2-1));
2810 if (!result && cpd ==
"&&") {
2814 return (
h->second)(dims);
2816 result =
new NotImplementedConverter();
2821 result = (
h->second)(dims);
2824 if (cpd.size() == 2 && cpd !=
"&&")
2825 result =
new VoidPtrPtrConverter(size);
2826 else if (!cpd.empty())
2829 result =
new NotImplementedConverter();
2875#define STRINGVIEW "basic_string_view<char,char_traits<char> >"
2876#define WSTRING "basic_string<wchar_t,char_traits<wchar_t>,allocator<wchar_t> >"
2878static struct InitConvFactories_t {
2880 InitConvFactories_t() {
2885 gf[
"bool"] = (
cf_t)+[](
dims_t) {
static BoolConverter
c{};
return &
c; };
2886 gf[
"const bool&"] = (
cf_t)+[](
dims_t) {
static ConstBoolRefConverter
c{};
return &
c; };
2887 gf[
"bool&"] = (
cf_t)+[](
dims_t) {
static BoolRefConverter
c{};
return &
c; };
2888 gf[
"char"] = (
cf_t)+[](
dims_t) {
static CharConverter
c{};
return &
c; };
2889 gf[
"const char&"] = (
cf_t)+[](
dims_t) {
static ConstCharRefConverter
c{};
return &
c; };
2890 gf[
"char&"] = (
cf_t)+[](
dims_t) {
static CharRefConverter
c{};
return &
c; };
2891 gf[
"signed char&"] = (
cf_t)+[](
dims_t) {
static SCharRefConverter
c{};
return &
c; };
2892 gf[
"unsigned char"] = (
cf_t)+[](
dims_t) {
static UCharConverter
c{};
return &
c; };
2893 gf[
"const unsigned char&"] = (
cf_t)+[](
dims_t) {
static ConstUCharRefConverter
c{};
return &
c; };
2894 gf[
"unsigned char&"] = (
cf_t)+[](
dims_t) {
static UCharRefConverter
c{};
return &
c; };
2895 gf[
"UCharAsInt"] = (
cf_t)+[](
dims_t) {
static UCharAsIntConverter
c{};
return &
c; };
2896 gf[
"wchar_t"] = (
cf_t)+[](
dims_t) {
static WCharConverter
c{};
return &
c; };
2897 gf[
"char16_t"] = (
cf_t)+[](
dims_t) {
static Char16Converter
c{};
return &
c; };
2898 gf[
"char32_t"] = (
cf_t)+[](
dims_t) {
static Char32Converter
c{};
return &
c; };
2899 gf[
"wchar_t&"] = (
cf_t)+[](
dims_t) {
static WCharRefConverter
c{};
return &
c; };
2900 gf[
"char16_t&"] = (
cf_t)+[](
dims_t) {
static Char16RefConverter
c{};
return &
c; };
2901 gf[
"char32_t&"] = (
cf_t)+[](
dims_t) {
static Char32RefConverter
c{};
return &
c; };
2902 gf[
"int8_t"] = (
cf_t)+[](
dims_t) {
static Int8Converter
c{};
return &
c; };
2903 gf[
"int8_t&"] = (
cf_t)+[](
dims_t) {
static Int8RefConverter
c{};
return &
c; };
2904 gf[
"const int8_t&"] = (
cf_t)+[](
dims_t) {
static ConstInt8RefConverter
c{};
return &
c; };
2905 gf[
"uint8_t"] = (
cf_t)+[](
dims_t) {
static UInt8Converter
c{};
return &
c; };
2906 gf[
"const uint8_t&"] = (
cf_t)+[](
dims_t) {
static ConstUInt8RefConverter
c{};
return &
c; };
2907 gf[
"uint8_t&"] = (
cf_t)+[](
dims_t) {
static UInt8RefConverter
c{};
return &
c; };
2908 gf[
"short"] = (
cf_t)+[](
dims_t) {
static ShortConverter
c{};
return &
c; };
2909 gf[
"const short&"] = (
cf_t)+[](
dims_t) {
static ConstShortRefConverter
c{};
return &
c; };
2910 gf[
"short&"] = (
cf_t)+[](
dims_t) {
static ShortRefConverter
c{};
return &
c; };
2911 gf[
"unsigned short"] = (
cf_t)+[](
dims_t) {
static UShortConverter
c{};
return &
c; };
2912 gf[
"const unsigned short&"] = (
cf_t)+[](
dims_t) {
static ConstUShortRefConverter
c{};
return &
c; };
2913 gf[
"unsigned short&"] = (
cf_t)+[](
dims_t) {
static UShortRefConverter
c{};
return &
c; };
2914 gf[
"int"] = (
cf_t)+[](
dims_t) {
static IntConverter
c{};
return &
c; };
2915 gf[
"int&"] = (
cf_t)+[](
dims_t) {
static IntRefConverter
c{};
return &
c; };
2916 gf[
"const int&"] = (
cf_t)+[](
dims_t) {
static ConstIntRefConverter
c{};
return &
c; };
2917 gf[
"unsigned int"] = (
cf_t)+[](
dims_t) {
static UIntConverter
c{};
return &
c; };
2918 gf[
"const unsigned int&"] = (
cf_t)+[](
dims_t) {
static ConstUIntRefConverter
c{};
return &
c; };
2919 gf[
"unsigned int&"] = (
cf_t)+[](
dims_t) {
static UIntRefConverter
c{};
return &
c; };
2920 gf[
"long"] = (
cf_t)+[](
dims_t) {
static LongConverter
c{};
return &
c; };
2921 gf[
"long&"] = (
cf_t)+[](
dims_t) {
static LongRefConverter
c{};
return &
c; };
2922 gf[
"const long&"] = (
cf_t)+[](
dims_t) {
static ConstLongRefConverter
c{};
return &
c; };
2923 gf[
"unsigned long"] = (
cf_t)+[](
dims_t) {
static ULongConverter
c{};
return &
c; };
2924 gf[
"const unsigned long&"] = (
cf_t)+[](
dims_t) {
static ConstULongRefConverter
c{};
return &
c; };
2925 gf[
"unsigned long&"] = (
cf_t)+[](
dims_t) {
static ULongRefConverter
c{};
return &
c; };
2926 gf[
"long long"] = (
cf_t)+[](
dims_t) {
static LLongConverter
c{};
return &
c; };
2927 gf[
"const long long&"] = (
cf_t)+[](
dims_t) {
static ConstLLongRefConverter
c{};
return &
c; };
2928 gf[
"long long&"] = (
cf_t)+[](
dims_t) {
static LLongRefConverter
c{};
return &
c; };
2929 gf[
"unsigned long long"] = (
cf_t)+[](
dims_t) {
static ULLongConverter
c{};
return &
c; };
2930 gf[
"const unsigned long long&"] = (
cf_t)+[](
dims_t) {
static ConstULLongRefConverter
c{};
return &
c; };
2931 gf[
"unsigned long long&"] = (
cf_t)+[](
dims_t) {
static ULLongRefConverter
c{};
return &
c; };
2933 gf[
"float"] = (
cf_t)+[](
dims_t) {
static FloatConverter
c{};
return &
c; };
2934 gf[
"const float&"] = (
cf_t)+[](
dims_t) {
static ConstFloatRefConverter
c{};
return &
c; };
2935 gf[
"float&"] = (
cf_t)+[](
dims_t) {
static FloatRefConverter
c{};
return &
c; };
2936 gf[
"double"] = (
cf_t)+[](
dims_t) {
static DoubleConverter
c{};
return &
c; };
2937 gf[
"double&"] = (
cf_t)+[](
dims_t) {
static DoubleRefConverter
c{};
return &
c; };
2938 gf[
"const double&"] = (
cf_t)+[](
dims_t) {
static ConstDoubleRefConverter
c{};
return &
c; };
2939 gf[
"long double"] = (
cf_t)+[](
dims_t) {
static LDoubleConverter
c{};
return &
c; };
2940 gf[
"const long double&"] = (
cf_t)+[](
dims_t) {
static ConstLDoubleRefConverter
c{};
return &
c; };
2941 gf[
"long double&"] = (
cf_t)+[](
dims_t) {
static LDoubleRefConverter
c{};
return &
c; };
2942 gf[
"std::complex<double>"] = (
cf_t)+[](
dims_t) {
return new ComplexDConverter{}; };
2943 gf[
"complex<double>"] = (
cf_t)+[](
dims_t) {
return new ComplexDConverter{}; };
2944 gf[
"const std::complex<double>&"] = (
cf_t)+[](
dims_t) {
return new ComplexDConverter{}; };
2945 gf[
"const complex<double>&"] = (
cf_t)+[](
dims_t) {
return new ComplexDConverter{}; };
2946 gf[
"void"] = (
cf_t)+[](
dims_t) {
static VoidConverter
c{};
return &
c; };
2949 gf[
"bool*"] = (
cf_t)+[](
dims_t d) {
return new BoolArrayConverter{
d}; };
2950 gf[
"bool**"] = (
cf_t)+[](
dims_t d) {
return new BoolArrayPtrConverter{
d}; };
2951 gf[
"const signed char[]"] = (
cf_t)+[](
dims_t d) {
return new SCharArrayConverter{
d}; };
2952 gf[
"signed char[]"] = (
cf_t)+[](
dims_t d) {
return new SCharArrayConverter{
d}; };
2953 gf[
"signed char**"] = (
cf_t)+[](
dims_t d) {
return new SCharArrayPtrConverter{
d}; };
2954 gf[
"const unsigned char*"] = (
cf_t)+[](
dims_t d) {
return new UCharArrayConverter{
d}; };
2955 gf[
"unsigned char*"] = (
cf_t)+[](
dims_t d) {
return new UCharArrayConverter{
d}; };
2956 gf[
"UCharAsInt*"] = (
cf_t)+[](
dims_t d) {
return new UCharArrayConverter{
d}; };
2957 gf[
"unsigned char**"] = (
cf_t)+[](
dims_t d) {
return new UCharArrayPtrConverter{
d}; };
2958#if __cplusplus > 201402L
2959 gf[
"byte*"] = (
cf_t)+[](
dims_t d) {
return new ByteArrayConverter{
d}; };
2960 gf[
"byte**"] = (
cf_t)+[](
dims_t d) {
return new ByteArrayPtrConverter{
d}; };
2962 gf[
"short*"] = (
cf_t)+[](
dims_t d) {
return new ShortArrayConverter{
d}; };
2963 gf[
"short**"] = (
cf_t)+[](
dims_t d) {
return new ShortArrayPtrConverter{
d}; };
2964 gf[
"unsigned short*"] = (
cf_t)+[](
dims_t d) {
return new UShortArrayConverter{
d}; };
2965 gf[
"unsigned short**"] = (
cf_t)+[](
dims_t d) {
return new UShortArrayPtrConverter{
d}; };
2966 gf[
"int*"] = (
cf_t)+[](
dims_t d) {
return new IntArrayConverter{
d}; };
2967 gf[
"int**"] = (
cf_t)+[](
dims_t d) {
return new IntArrayPtrConverter{
d}; };
2968 gf[
"unsigned int*"] = (
cf_t)+[](
dims_t d) {
return new UIntArrayConverter{
d}; };
2969 gf[
"unsigned int**"] = (
cf_t)+[](
dims_t d) {
return new UIntArrayPtrConverter{
d}; };
2970 gf[
"long*"] = (
cf_t)+[](
dims_t d) {
return new LongArrayConverter{
d}; };
2971 gf[
"long**"] = (
cf_t)+[](
dims_t d) {
return new LongArrayPtrConverter{
d}; };
2972 gf[
"unsigned long*"] = (
cf_t)+[](
dims_t d) {
return new ULongArrayConverter{
d}; };
2973 gf[
"unsigned long**"] = (
cf_t)+[](
dims_t d) {
return new ULongArrayPtrConverter{
d}; };
2974 gf[
"long long*"] = (
cf_t)+[](
dims_t d) {
return new LLongArrayConverter{
d}; };
2975 gf[
"long long**"] = (
cf_t)+[](
dims_t d) {
return new LLongArrayPtrConverter{
d}; };
2976 gf[
"unsigned long long*"] = (
cf_t)+[](
dims_t d) {
return new ULLongArrayConverter{
d}; };
2977 gf[
"unsigned long long**"] = (
cf_t)+[](
dims_t d) {
return new ULLongArrayPtrConverter{
d}; };
2978 gf[
"float*"] = (
cf_t)+[](
dims_t d) {
return new FloatArrayConverter{
d}; };
2979 gf[
"float**"] = (
cf_t)+[](
dims_t d) {
return new FloatArrayPtrConverter{
d}; };
2980 gf[
"double*"] = (
cf_t)+[](
dims_t d) {
return new DoubleArrayConverter{
d}; };
2981 gf[
"double**"] = (
cf_t)+[](
dims_t d) {
return new DoubleArrayPtrConverter{
d}; };
2982 gf[
"long double*"] = (
cf_t)+[](
dims_t d) {
return new LDoubleArrayConverter{
d}; };
2983 gf[
"long double**"] = (
cf_t)+[](
dims_t d) {
return new LDoubleArrayPtrConverter{
d}; };
2984 gf[
"std::complex<double>*"] = (
cf_t)+[](
dims_t d) {
return new ComplexDArrayConverter{
d}; };
2985 gf[
"complex<double>*"] = (
cf_t)+[](
dims_t d) {
return new ComplexDArrayConverter{
d}; };
2986 gf[
"std::complex<double>**"] = (
cf_t)+[](
dims_t d) {
return new ComplexDArrayPtrConverter{
d}; };
2990 gf[
"signed char"] = gf[
"char"];
2991 gf[
"const signed char&"] = gf[
"const char&"];
2992#if __cplusplus > 201402L
2993 gf[
"byte"] = gf[
"uint8_t"];
2994 gf[
"const byte&"] = gf[
"const uint8_t&"];
2995 gf[
"byte&"] = gf[
"uint8&"];
2997 gf[
"internal_enum_type_t"] = gf[
"int"];
2998 gf[
"internal_enum_type_t&"] = gf[
"int&"];
2999 gf[
"const internal_enum_type_t&"] = gf[
"const int&"];
3000 gf[
"Long64_t"] = gf[
"long long"];
3001 gf[
"Long64_t*"] = gf[
"long long*"];
3002 gf[
"Long64_t&"] = gf[
"long long&"];
3003 gf[
"const Long64_t&"] = gf[
"const long long&"];
3004 gf[
"ULong64_t"] = gf[
"unsigned long long"];
3005 gf[
"ULong64_t*"] = gf[
"unsigned long long*"];
3006 gf[
"ULong64_t&"] = gf[
"unsigned long long&"];
3007 gf[
"const ULong64_t&"] = gf[
"const unsigned long long&"];
3008 gf[
"Float16_t"] = gf[
"float"];
3009 gf[
"const Float16_t&"] = gf[
"const float&"];
3010 gf[
"Double32_t"] = gf[
"double"];
3011 gf[
"Double32_t&"] = gf[
"double&"];
3012 gf[
"const Double32_t&"] = gf[
"const double&"];
3015 gf[
"TString"] = (
cf_t)+[](
dims_t) {
return new TStringConverter{}; };
3016 gf[
"TString&"] = gf[
"TString"];
3017 gf[
"const TString&"] = gf[
"TString"];
3018 gf[
"nullptr_t"] = (
cf_t)+[](
dims_t) {
static NullptrConverter
c{};
return &
c;};
3019 gf[
"const char*"] = (
cf_t)+[](
dims_t) {
return new CStringConverter{}; };
3020 gf[
"const signed char*"] = gf[
"const char*"];
3021 gf[
"const char[]"] = (
cf_t)+[](
dims_t) {
return new CStringConverter{}; };
3022 gf[
"char*"] = (
cf_t)+[](
dims_t) {
return new NonConstCStringConverter{}; };
3023 gf[
"signed char*"] = gf[
"char*"];
3024 gf[
"wchar_t*"] = (
cf_t)+[](
dims_t) {
return new WCStringConverter{}; };
3025 gf[
"char16_t*"] = (
cf_t)+[](
dims_t) {
return new CString16Converter{}; };
3026 gf[
"char32_t*"] = (
cf_t)+[](
dims_t) {
return new CString32Converter{}; };
3028 gf[
"char16_t**"] = gf[
"char16_t*"];
3029 gf[
"char32_t**"] = gf[
"char32_t*"];
3030 gf[
"const char**"] = (
cf_t)+[](
dims_t d) {
return new CStringArrayConverter{
d}; };
3031 gf[
"char**"] = gf[
"const char**"];
3032 gf[
"const char*[]"] = gf[
"const char**"];
3033 gf[
"char*[]"] = gf[
"const char*[]"];
3034 gf[
"std::string"] = (
cf_t)+[](
dims_t) {
return new STLStringConverter{}; };
3035 gf[
"string"] = gf[
"std::string"];
3036 gf[
"const std::string&"] = gf[
"std::string"];
3037 gf[
"const string&"] = gf[
"std::string"];
3038 gf[
"string&&"] = (
cf_t)+[](
dims_t) {
return new STLStringMoveConverter{}; };
3039 gf[
"std::string&&"] = gf[
"string&&"];
3040 gf[
"std::string_view"] = (
cf_t)+[](
dims_t) {
return new STLStringViewConverter{}; };
3041 gf[
"string_view"] = gf[
"std::string_view"];
3043 gf[
"experimental::" STRINGVIEW] = gf[
"std::string_view"];
3044 gf[
"std::string_view&"] = gf[
"std::string_view"];
3045 gf[
"const string_view&"] = gf[
"std::string_view"];
3046 gf[
"const " STRINGVIEW "&"] = gf[
"std::string_view"];
3047 gf[
"std::wstring"] = (
cf_t)+[](
dims_t) {
return new STLWStringConverter{}; };
3048 gf[
WSTRING] = gf[
"std::wstring"];
3049 gf[
"std::" WSTRING] = gf[
"std::wstring"];
3050 gf[
"const std::wstring&"] = gf[
"std::wstring"];
3051 gf[
"const std::" WSTRING "&"] = gf[
"std::wstring"];
3052 gf[
"const " WSTRING "&"] = gf[
"std::wstring"];
3053 gf[
"void*&"] = (
cf_t)+[](
dims_t) {
static VoidPtrRefConverter
c{};
return &
c; };
3054 gf[
"void**"] = (
cf_t)+[](
dims_t d) {
return new VoidPtrPtrConverter{size_t((
d &&
d[0] != -1) ?
d[1] : -1)}; };
3055 gf[
"void*[]"] = (
cf_t)+[](
dims_t d) {
return new VoidPtrPtrConverter{size_t((
d &&
d[0] != -1) ?
d[1] : -1)}; };
3056 gf[
"PyObject*"] = (
cf_t)+[](
dims_t) {
static PyObjectConverter
c{};
return &
c; };
3057 gf[
"_object*"] = gf[
"PyObject*"];
3060} initConvFactories_;
static Py_ssize_t CPyCppyy_PyUnicode_AsWideChar(PyObject *pyobj, wchar_t *w, Py_ssize_t size)
#define PyBytes_AS_STRING
#define CPyCppyy_PyText_FromStringAndSize
#define PY_SSIZE_T_FORMAT
static void * CPyCppyy_PyCapsule_GetPointer(PyObject *capsule, const char *)
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_GET_SIZE
#define CPyCppyy_PyCapsule_CheckExact
static const char * CPyCppyy_PyText_AsStringAndSize(PyObject *pystr, Py_ssize_t *size)
#define CPyCppyy_PyText_FromString
#define CPyCppyy_PyText_Check
static std::array< PyTypeObject *, NTYPES > gCTypesPtrTypes
static const char * FPCFM_ERRMSG
#define CPPYY_IMPL_BASIC_CONVERTER(name, type, stype, ctype, F1, F2, tc)
#define CPPYY_IMPL_ARRAY_CONVERTER(name, ctype, type, code)
static bool ConvertImplicit(Cppyy::TCppType_t klass, PyObject *pyobject, CPyCppyy::Parameter ¶, CPyCppyy::CallContext *ctxt)
static std::map< void *, PyObject ** > sWrapperReference
static bool CPyCppyy_PyLong_AsBool(PyObject *pyobject)
static bool IsPyCArgObject(PyObject *pyobject)
static PyObject * WrapperCacheEraser(PyObject *, PyObject *pyref)
#define CPPYY_IMPL_STRING_AS_PRIMITIVE_CONVERTER(name, type, F1, F2)
#define CPPYY_IMPL_BASIC_CHAR_CONVERTER(name, type, low, high)
const size_t MOVE_REFCOUNT_CUTOFF
static std::array< PyTypeObject *, NTYPES > gCTypesTypes
static char CPyCppyy_PyText_AsChar(PyObject *pyobject)
#define CPPYY_IMPL_BASIC_CONST_CHAR_REFCONVERTER(name, type, ctype, low, high)
static std::map< RetSigKey_t, std::map< PyObject *, void * > > sWrapperLookup
static int ExtractChar(PyObject *pyobject, const char *tname, int low, int high)
static PyTypeObject * GetCTypesPtrType(int nidx)
static std::map< PyObject *, std::pair< void *, RetSigKey_t > > sWrapperWeakRefs
static int8_t CPyCppyy_PyLong_AsInt8(PyObject *pyobject)
std::pair< std::string, std::string > RetSigKey_t
static PyMethodDef gWrapperCacheEraserMethodDef
#define CPPYY_IMPL_BASIC_CONST_REFCONVERTER(name, type, ctype, F1)
l unsigned CPyCppyy_PyLong_AsUShort
static CPyCppyy::Converter * selectInstanceCnv(Cppyy::TCppScope_t klass, const std::string &cpd, long size, dims_t dims, bool isConst, bool control)
static std::map< void *, std::string > sFuncWrapperLookup
static short CPyCppyy_PyLong_AsShort(PyObject *pyobject)
static long CPyCppyy_PyLong_AsStrictLong(PyObject *pyobject)
static CPyCppyy::CPPInstance * GetCppInstance(PyObject *pyobject)
#define UNKNOWN_ARRAY_SIZE
#define CPPYY_IMPL_REFCONVERTER(name, ctype, type, code)
static PyTypeObject * GetCTypesType(int nidx)
static std::array< const char *, NTYPES > gCTypesNames
static bool CArraySetArg(PyObject *pyobject, CPyCppyy::Parameter ¶, char tc, int size)
static int CPyCppyy_PyLong_AsStrictInt(PyObject *pyobject)
static std::map< RetSigKey_t, std::vector< void * > > sWrapperFree
static bool IsCTypesArrayOrPointer(PyObject *pyobject)
static unsigned int sWrapperCounter
static void * PyFunction_AsCPointer(PyObject *pyobject, const std::string &rettype, const std::string &signature)
#define CPPYY_IMPL_REFCONVERTER_FROM_MEMORY(name, ctype)
Cppyy::TCppType_t fSmartPtrType
Cppyy::TCppType_t fUnderlyingType
unsigned long long ULong64_t
Cppyy::TCppType_t GetSmartIsA() const
Cppyy::TCppType_t ObjectIsA(bool check_smart=true) const
MethodInfo_t * fMethodInfo
virtual bool SetArg(PyObject *, Parameter &, CallContext *=nullptr)=0
virtual PyObject * FromMemory(void *address)
virtual bool ToMemory(PyObject *value, void *address)
virtual bool SetArg(PyObject *, Parameter &, CallContext *=nullptr)
virtual PyObject * FromMemory(void *address)
virtual bool ToMemory(PyObject *value, void *address)
static bool RegisterPyObject(CPPInstance *pyobj, void *cppobj)
virtual bool ToMemory(PyObject *value, void *address)
virtual bool GetAddressSpecialCase(PyObject *pyobject, void *&address)
virtual PyObject * FromMemory(void *address)
virtual bool SetArg(PyObject *, Parameter &, CallContext *=nullptr)
basic_string_view< char > string_view
std::string remove_const(const std::string &cppname)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
std::vector< std::string > extract_arg_types(const std::string &sig)
void ConstructCallbackPreamble(const std::string &retType, const std::vector< std::string > &argtypes, std::ostringstream &code)
void ConstructCallbackReturn(const std::string &retType, int nArgs, std::ostringstream &code)
Py_ssize_t GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, bool check=true)
const std::string Compound(const std::string &name)
unsigned long PyLongOrInt_AsULong(PyObject *pyobject)
bool TupleOfInstances_CheckExact(T *object)
PyObject * CreatePointerView(void *ptr, size_t size=(size_t) -1)
bool RefFloat_CheckExact(T *object)
bool CPPExcInstance_Check(T *object)
bool NoImplicit(CallContext *ctxt)
PyObject * CreateLowLevelView(const char **, Py_ssize_t *shape=nullptr)
static ConvFactories_t gConvFactories
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
bool CPPOverload_Check(T *object)
bool RefInt_CheckExact(T *object)
bool CPPScope_Check(T *object)
CPYCPPYY_EXTERN bool RegisterConverter(const std::string &name, ConverterFactory_t)
bool AllowImplicit(CallContext *ctxt)
bool UseStrictOwnership(CallContext *ctxt)
bool CPPInstance_Check(T *object)
PyObject * CreateScopeProxy(Cppyy::TCppScope_t)
Converter *(* cf_t)(dims_t d)
PyObject * gNullPtrObject
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
CPYCPPYY_EXTERN void DestroyConverter(Converter *p)
bool TemplateProxy_Check(T *object)
std::map< std::string, cf_t > ConvFactories_t
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Py_ssize_t *dims)
CPYCPPYY_EXTERN bool UnregisterConverter(const std::string &name)
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 bool Compile(const std::string &code)
RPY_EXPORTED ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
RPY_EXPORTED bool GetSmartPtrInfo(const std::string &, TCppType_t *raw, TCppMethod_t *deref)
RPY_EXPORTED bool IsConstructor(TCppMethod_t method)
RPY_EXPORTED TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
RPY_EXPORTED TCppFuncAddr_t GetFunctionAddress(TCppMethod_t method, bool check_enabled=true)
RPY_EXPORTED size_t SizeOf(TCppType_t klass)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
static constexpr double pc
static constexpr double L
CPPOverload::Methods_t fMethods
static ECallFlags sMemoryPolicy
Cppyy::TCppScope_t fCurScope
void AddTemporary(PyObject *pyobj)
union CPyCppyy::Parameter::Value fValue
unsigned long long fULLong