30 #define TParameter PyROOT::TParameter
37 typedef TConverter* (*ConverterFactory_t) ( Long_t size );
38 typedef std::map< std::string, ConverterFactory_t > ConvFactories_t;
39 ConvFactories_t gConvFactories;
40 R__EXTERN PyObject* gNullPtrObject;
45 #if PY_VERSION_HEX >= 0x02050000
47 struct PyROOT_tagCDataObject {
52 static inline PyTypeObject* GetCTypesType(
const char* name ) {
53 PyObject* ct = PyImport_ImportModule(
"ctypes" );
54 if ( ! ct )
return nullptr;
55 PyTypeObject* ct_t = (PyTypeObject*)PyObject_GetAttrString( ct, name );
66 static inline Bool_t PyROOT_PyLong_AsBool( PyObject* pyobject )
68 Long_t l = PyLong_AsLong( pyobject );
70 if ( ! ( l == 0 || l == 1 ) || PyFloat_Check( pyobject ) ) {
71 PyErr_SetString( PyExc_ValueError,
"boolean value should be bool, or integer 1 or 0" );
79 static inline Char_t PyROOT_PyUnicode_AsChar( PyObject* pyobject ) {
80 return (Char_t)PyROOT_PyUnicode_AsString( pyobject )[0];
85 static inline UShort_t PyROOT_PyLong_AsUShort( PyObject* pyobject )
88 if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
89 PyErr_SetString( PyExc_TypeError,
"unsigned short conversion expects an integer object" );
92 Long_t l = PyLong_AsLong( pyobject );
93 if ( l < 0 || USHRT_MAX < l ) {
94 PyErr_Format( PyExc_ValueError,
"integer %ld out of range for unsigned short", l );
103 static inline Short_t PyROOT_PyLong_AsShort( PyObject* pyobject )
106 if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
107 PyErr_SetString( PyExc_TypeError,
"short int conversion expects an integer object" );
110 Long_t l = PyLong_AsLong( pyobject );
111 if ( l < SHRT_MIN || SHRT_MAX < l ) {
112 PyErr_Format( PyExc_ValueError,
"integer %ld out of range for short int", l );
122 static inline Long_t PyROOT_PyLong_AsStrictLong( PyObject* pyobject )
127 if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
128 PyErr_SetString( PyExc_TypeError,
"int/long conversion expects an integer object" );
131 return (Long_t)PyLong_AsLong( pyobject );
136 PyObject* PyROOT::TConverter::FromMemory(
void* )
139 PyErr_SetString( PyExc_TypeError,
"C++ type can not be converted from memory" );
146 Bool_t PyROOT::TConverter::ToMemory( PyObject*,
void* )
148 PyErr_SetString( PyExc_TypeError,
"C++ type can not be converted to memory" );
154 #define PYROOT_IMPLEMENT_BASIC_CONVERTER( name, type, stype, F1, F2, tc ) \
155 Bool_t PyROOT::T##name##Converter::SetArg( \
156 PyObject* pyobject, TParameter& para, TCallContext* ) \
159 type val = (type)F2( pyobject ); \
160 if ( val == (type)-1 && PyErr_Occurred() ) \
162 para.fValue.f##name = val; \
163 para.fTypeCode = tc; \
167 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
169 return F1( (stype)*((type*)address) ); \
172 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
174 type s = (type)F2( value ); \
175 if ( s == (type)-1 && PyErr_Occurred() ) \
177 *((type*)address) = (type)s; \
182 static inline Int_t ExtractChar( PyObject* pyobject,
const char* tname, Int_t low, Int_t high )
185 if ( PyROOT_PyUnicode_Check( pyobject ) ) {
186 if ( PyROOT_PyUnicode_GET_SIZE( pyobject ) == 1 )
187 lchar = (Int_t)PyROOT_PyUnicode_AsChar( pyobject );
189 PyErr_Format( PyExc_TypeError,
"%s expected, got string of size " PY_SSIZE_T_FORMAT,
190 tname, PyROOT_PyUnicode_GET_SIZE( pyobject ) );
191 }
else if ( ! PyFloat_Check( pyobject ) ) {
192 lchar = PyLong_AsLong( pyobject );
193 if ( lchar == -1 && PyErr_Occurred() )
195 else if ( ! ( low <= lchar && lchar <= high ) ) {
196 PyErr_Format( PyExc_ValueError,
197 "integer to character: value %d not in range [%d,%d]", lchar, low, high );
201 PyErr_SetString( PyExc_TypeError,
"char or small int type expected" );
207 #define PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( name, type, F1 )\
208 Bool_t PyROOT::TConst##name##RefConverter::SetArg( \
209 PyObject* pyobject, TParameter& para, TCallContext* ) \
211 type val = (type)F1( pyobject ); \
212 if ( val == (type)-1 && PyErr_Occurred() ) \
214 para.fValue.f##name = val; \
215 para.fRef = ¶.fValue.f##name; \
216 para.fTypeCode = 'r'; \
220 #define PYROOT_IMPLEMENT_BASIC_CONST_CHAR_REF_CONVERTER( name, type, low, high )\
221 Bool_t PyROOT::TConst##name##RefConverter::SetArg( \
222 PyObject* pyobject, TParameter& para, TCallContext* ) \
225 type val = (type)ExtractChar( pyobject, #type, low, high ); \
226 if ( val == (type)-1 && PyErr_Occurred() ) \
228 para.fValue.fLong = val; \
229 para.fTypeCode = 'l'; \
236 #define PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( name, type, low, high ) \
237 Bool_t PyROOT::T##name##Converter::SetArg( \
238 PyObject* pyobject, TParameter& para, TCallContext* ) \
241 Long_t val = ExtractChar( pyobject, #type, low, high ); \
242 if ( val == -1 && PyErr_Occurred() ) \
244 para.fValue.fLong = val; \
245 para.fTypeCode = 'l'; \
249 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
251 return PyROOT_PyUnicode_FromFormat( "%c", *((type*)address) ); \
254 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
256 if ( PyROOT_PyUnicode_Check( value ) ) { \
257 const char* buf = PyROOT_PyUnicode_AsString( value ); \
258 if ( PyErr_Occurred() ) \
260 int len = PyROOT_PyUnicode_GET_SIZE( value ); \
262 PyErr_Format( PyExc_TypeError, #type" expected, got string of size %d", len );\
265 *((type*)address) = (type)buf[0]; \
267 Long_t l = PyLong_AsLong( value ); \
268 if ( l == -1 && PyErr_Occurred() ) \
270 if ( ! ( low <= l && l <= high ) ) { \
271 PyErr_Format( PyExc_ValueError, \
272 "integer to character: value %ld not in range [%d,%d]", l, low, high );\
275 *((type*)address) = (type)l; \
282 PYROOT_IMPLEMENT_BASIC_CONVERTER( Long, Long_t, Long_t, PyLong_FromLong, PyROOT_PyLong_AsStrictLong,
'l' )
287 Bool_t PyROOT::TLongRefConverter::SetArg(
288 PyObject* pyobject, TParameter& para, TCallContext* )
290 #if PY_VERSION_HEX < 0x03000000
291 if ( TCustomInt_CheckExact( pyobject ) ) {
292 para.fValue.fVoidp = (
void*)&((PyIntObject*)pyobject)->ob_ival;
293 para.fTypeCode =
'V';
294 if (PyErr_WarnEx(PyExc_FutureWarning,
295 "ROOT.Long is deprecated and will disappear in a future version of ROOT. "
296 "Instead, use ctypes.c_long for pass-by-ref of longs", 1) < 0) {
303 #if PY_VERSION_HEX < 0x02050000
304 PyErr_SetString( PyExc_TypeError,
"use ROOT.Long for pass-by-ref of longs" );
309 static PyTypeObject* c_long_type = GetCTypesType(
"c_long" );
310 if ( Py_TYPE( pyobject ) == c_long_type ) {
311 para.fValue.fVoidp = (
void*)((PyROOT_tagCDataObject*)pyobject)->b_ptr;
312 para.fTypeCode =
'V';
316 PyErr_SetString( PyExc_TypeError,
"use ctypes.c_long for pass-by-ref of longs" );
322 PYROOT_IMPLEMENT_BASIC_CONST_CHAR_REF_CONVERTER( Char, Char_t, CHAR_MIN, CHAR_MAX )
323 PYROOT_IMPLEMENT_BASIC_CONST_CHAR_REF_CONVERTER( UChar, UChar_t, 0, UCHAR_MAX )
325 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Bool, Bool_t, PyROOT_PyLong_AsBool )
326 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Short, Short_t, PyROOT_PyLong_AsShort )
327 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( UShort, UShort_t, PyROOT_PyLong_AsUShort )
328 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Int, Int_t, PyROOT_PyLong_AsStrictLong )
329 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( UInt, UInt_t, PyLongOrInt_AsULong )
330 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Long, Long_t, PyROOT_PyLong_AsStrictLong )
331 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( ULong, ULong_t, PyLongOrInt_AsULong )
332 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( LongLong, Long64_t, PyLong_AsLongLong )
333 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( ULongLong, ULong64_t, PyLongOrInt_AsULong64 )
338 Bool_t PyROOT::TIntRefConverter::SetArg(
339 PyObject* pyobject, TParameter& para, TCallContext* )
341 #if PY_VERSION_HEX < 0x03000000
342 if ( TCustomInt_CheckExact( pyobject ) ) {
343 para.fValue.fVoidp = (
void*)&((PyIntObject*)pyobject)->ob_ival;
344 para.fTypeCode =
'V';
345 if (PyErr_WarnEx(PyExc_FutureWarning,
346 "ROOT.Long is deprecated and will disappear in a future version of ROOT. "
347 "Instead, use ctypes.c_int for pass-by-ref of ints", 1) < 0) {
354 #if PY_VERSION_HEX >= 0x02050000
356 static PyTypeObject* c_int_type = GetCTypesType(
"c_int" );
357 if ( Py_TYPE( pyobject ) == c_int_type ) {
358 para.fValue.fVoidp = (
void*)((PyROOT_tagCDataObject*)pyobject)->b_ptr;
359 para.fTypeCode =
'V';
365 int buflen = Utility::GetBuffer( pyobject,
'i',
sizeof(
int), para.fValue.fVoidp );
366 if ( para.fValue.fVoidp && buflen ) {
367 para.fTypeCode =
'V';
371 #if PY_VERSION_HEX < 0x02050000
372 PyErr_SetString( PyExc_TypeError,
"use ROOT.Long for pass-by-ref of ints" );
374 PyErr_SetString( PyExc_TypeError,
"use ctypes.c_int for pass-by-ref of ints" );
382 PYROOT_IMPLEMENT_BASIC_CONVERTER( Bool, Bool_t, Long_t, PyInt_FromLong, PyROOT_PyLong_AsBool,
'l' )
386 PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( Char, Char_t, CHAR_MIN, CHAR_MAX )
387 PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( UChar, UChar_t, 0, UCHAR_MAX )
391 PYROOT_IMPLEMENT_BASIC_CONVERTER( Short, Short_t, Long_t, PyInt_FromLong, PyROOT_PyLong_AsShort, 'l' )
392 PYROOT_IMPLEMENT_BASIC_CONVERTER( UShort, UShort_t, Long_t, PyInt_FromLong, PyROOT_PyLong_AsUShort, 'l' )
393 PYROOT_IMPLEMENT_BASIC_CONVERTER( Int, Int_t, Long_t, PyInt_FromLong, PyROOT_PyLong_AsStrictLong, 'l' )
398 Bool_t PyROOT::TULongConverter::SetArg(
399 PyObject* pyobject, TParameter& para, TCallContext* )
401 para.fValue.fULong = PyLongOrInt_AsULong( pyobject );
402 if ( PyErr_Occurred() )
404 para.fTypeCode =
'U';
408 PyObject* PyROOT::TULongConverter::FromMemory(
void* address )
411 return PyLong_FromUnsignedLong( *((ULong_t*)address) );
414 Bool_t PyROOT::TULongConverter::ToMemory( PyObject* value,
void* address )
417 ULong_t u = PyLongOrInt_AsULong( value );
418 if ( PyErr_Occurred() )
420 *((ULong_t*)address) = u;
427 PyObject* PyROOT::TUIntConverter::FromMemory(
void* address )
429 return PyLong_FromUnsignedLong( *((UInt_t*)address) );
432 Bool_t PyROOT::TUIntConverter::ToMemory( PyObject* value,
void* address )
435 ULong_t u = PyLongOrInt_AsULong( value );
436 if ( PyErr_Occurred() )
439 if ( u > (ULong_t)UINT_MAX ) {
440 PyErr_SetString( PyExc_OverflowError,
"value too large for unsigned int" );
444 *((UInt_t*)address) = (UInt_t)u;
451 PYROOT_IMPLEMENT_BASIC_CONVERTER( Float, Float_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble,
'f' )
452 PYROOT_IMPLEMENT_BASIC_CONVERTER( Double, Double_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble, 'd' )
454 PYROOT_IMPLEMENT_BASIC_CONVERTER( LongDouble, LongDouble_t, LongDouble_t, PyFloat_FromDouble, PyFloat_AsDouble, 'D' )
459 Bool_t PyROOT::TDoubleRefConverter::SetArg(
460 PyObject* pyobject, TParameter& para, TCallContext* )
462 if ( TCustomFloat_CheckExact( pyobject ) ) {
463 para.fValue.fVoidp = (
void*)&((PyFloatObject*)pyobject)->ob_fval;
464 para.fTypeCode =
'V';
465 if (PyErr_WarnEx(PyExc_FutureWarning,
466 "ROOT.Double is deprecated and will disappear in a future version of ROOT. "
467 "Instead, use ctypes.c_double for pass-by-ref of doubles", 1) < 0) {
474 int buflen = Utility::GetBuffer( pyobject,
'd',
sizeof(
double), para.fValue.fVoidp );
475 if ( para.fValue.fVoidp && buflen ) {
476 para.fTypeCode =
'V';
480 PyErr_SetString( PyExc_TypeError,
"use ctypes.c_double for pass-by-ref of doubles" );
486 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Float, Float_t, PyFloat_AsDouble )
487 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( Double, Double_t, PyFloat_AsDouble )
488 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( LongDouble, LongDouble_t, PyFloat_AsDouble )
493 Bool_t PyROOT::TVoidConverter::SetArg( PyObject*, TParameter&, TCallContext* )
495 PyErr_SetString( PyExc_SystemError,
"void/unknown arguments can\'t be set" );
502 Bool_t PyROOT::TLongLongConverter::SetArg(
503 PyObject* pyobject, TParameter& para, TCallContext* )
505 if ( PyFloat_Check( pyobject ) ) {
508 PyErr_SetString( PyExc_ValueError,
"can not convert float to long long" );
512 para.fValue.fLongLong = PyLong_AsLongLong( pyobject );
513 if ( PyErr_Occurred() )
515 para.fTypeCode =
'k';
519 PyObject* PyROOT::TLongLongConverter::FromMemory(
void* address )
522 return PyLong_FromLongLong( *(Long64_t*)address );
525 Bool_t PyROOT::TLongLongConverter::ToMemory( PyObject* value,
void* address )
528 Long64_t ll = PyLong_AsLongLong( value );
529 if ( ll == -1 && PyErr_Occurred() )
531 *((Long64_t*)address) = ll;
538 Bool_t PyROOT::TULongLongConverter::SetArg(
539 PyObject* pyobject, TParameter& para, TCallContext* )
541 para.fValue.fULongLong = PyLongOrInt_AsULong64( pyobject );
542 if ( PyErr_Occurred() )
544 para.fTypeCode =
'K';
548 PyObject* PyROOT::TULongLongConverter::FromMemory(
void* address )
551 return PyLong_FromUnsignedLongLong( *(ULong64_t*)address );
554 Bool_t PyROOT::TULongLongConverter::ToMemory( PyObject* value,
void* address )
557 Long64_t ull = PyLongOrInt_AsULong64( value );
558 if ( PyErr_Occurred() )
560 *((ULong64_t*)address) = ull;
567 static std::tuple<const char*,Py_ssize_t> getStringAndSizeCString(PyObject* pyobject) {
568 #if PY_VERSION_HEX >= 0x03030000
571 auto charArr = PyROOT_PyUnicode_AsStringAndSize(pyobject, &size);
573 auto size = PyROOT_PyUnicode_GET_SIZE(pyobject);
574 auto charArr = PyROOT_PyUnicode_AsStringChecked(pyobject);
576 return std::tuple<const char*,Py_ssize_t>(charArr, size);
579 Bool_t PyROOT::TCStringConverter::SetArg(
580 PyObject* pyobject, TParameter& para, TCallContext* )
582 if (PyROOT_PyUnicode_Check(pyobject)
583 #
if PY_VERSION_HEX < 0x03000000
584 || PyUnicode_Check(pyobject)
587 auto strAndSize = getStringAndSizeCString(pyobject);
588 fBuffer = std::string(std::get<0>(strAndSize), std::get<1>(strAndSize));
589 }
else if (PyBytes_Check(pyobject)) {
590 auto s = PyBytes_AsString(pyobject); \
591 auto size = PyBytes_GET_SIZE(pyobject);
592 fBuffer = std::string(s, size);
598 if ( fMaxSize < (UInt_t)fBuffer.size() )
599 PyErr_Warn( PyExc_RuntimeWarning, (
char*)
"string too long for char array (truncated)" );
600 else if ( fMaxSize != UINT_MAX )
601 fBuffer.resize( fMaxSize,
'\0' );
604 para.fValue.fVoidp = (
void*)fBuffer.c_str();
605 para.fTypeCode =
'p';
609 PyObject* PyROOT::TCStringConverter::FromMemory(
void* address )
612 if ( address && *(
char**)address ) {
613 if ( fMaxSize != UINT_MAX ) {
614 std::string buf( *(
char**)address, fMaxSize );
615 return PyROOT_PyUnicode_FromString( buf.c_str() );
618 return PyROOT_PyUnicode_FromString( *(
char**)address );
622 Py_INCREF( PyStrings::gEmptyString );
623 return PyStrings::gEmptyString;
626 Bool_t PyROOT::TCStringConverter::ToMemory( PyObject* value,
void* address )
629 const char* s = PyROOT_PyUnicode_AsStringChecked( value );
630 if ( PyErr_Occurred() )
634 if ( fMaxSize < (UInt_t)PyROOT_PyUnicode_GET_SIZE( value ) )
635 PyErr_Warn( PyExc_RuntimeWarning, (
char*)
"string too long for char array (truncated)" );
637 if ( fMaxSize != UINT_MAX )
638 strncpy( *(
char**)address, s, fMaxSize );
641 strcpy( *(
char**)address, s );
650 using namespace PyROOT;
652 inline Bool_t CArraySetArg(
653 PyObject* pyobject, TParameter& para,
char tc,
int size )
656 if ( pyobject == gNullPtrObject ) {
657 para.fValue.fVoidp = NULL;
659 int buflen = Utility::GetBuffer( pyobject, tc, size, para.fValue.fVoidp );
660 if ( ! para.fValue.fVoidp || buflen == 0 )
663 para.fTypeCode =
'p';
673 Bool_t PyROOT::TNonConstCStringConverter::SetArg(
674 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
676 if ( this->TCStringConverter::SetArg( pyobject, para, ctxt ) )
681 return CArraySetArg( pyobject, para,
'c',
sizeof(
char) );
687 PyObject* PyROOT::TNonConstCStringConverter::FromMemory(
void* address )
689 if ( fMaxSize != UINT_MAX )
690 return PyROOT_PyUnicode_FromStringAndSize( *(
char**)address, fMaxSize );
691 return this->TCStringConverter::FromMemory( address );
697 Bool_t PyROOT::TNonConstUCStringConverter::SetArg(
698 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
700 if ( this->TCStringConverter::SetArg( pyobject, para, ctxt ) )
705 return CArraySetArg( pyobject, para,
'B',
sizeof(
unsigned char) );
711 Bool_t PyROOT::TVoidArrayConverter::GetAddressSpecialCase( PyObject* pyobject,
void*& address )
713 if ( pyobject == Py_None || pyobject == gNullPtrObject ) {
715 if (pyobject == Py_None) {
716 if (PyErr_WarnEx(PyExc_FutureWarning,
717 "The conversion from None to null pointer is deprecated "
718 "and will not be allowed anymore in a future version of ROOT. "
719 "Instead, use ROOT.nullptr or 0", 1) < 0) {
729 if ( PyInt_CheckExact( pyobject ) || PyLong_CheckExact( pyobject ) ) {
730 Long_t val = (Long_t)PyLong_AsLong( pyobject );
732 address = (
void*)val;
740 if ( PyROOT_PyCapsule_CheckExact( pyobject ) ) {
741 address = (
void*)PyROOT_PyCapsule_GetPointer( pyobject, NULL );
751 Bool_t PyROOT::TVoidArrayConverter::SetArg(
752 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
754 if ( ObjectProxy_Check( pyobject ) ) {
756 if ( ! fKeepControl && ! UseStrictOwnership( ctxt ) )
757 ((ObjectProxy*)pyobject)->Release();
760 para.fValue.fVoidp = ((ObjectProxy*)pyobject)->GetObject();
761 para.fTypeCode =
'p';
766 if ( GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
767 para.fTypeCode =
'p';
772 int buflen = Utility::GetBuffer( pyobject,
'*', 1, para.fValue.fVoidp, kFALSE );
775 if ( para.fValue.fVoidp && buflen != 0 ) {
776 para.fTypeCode =
'p';
787 PyObject* PyROOT::TVoidArrayConverter::FromMemory(
void* address )
789 if ( ! address || *(ptrdiff_t*)address == 0 ) {
790 Py_INCREF( gNullPtrObject );
791 return gNullPtrObject;
793 return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)*(ptrdiff_t**)address,
sizeof(
void*) );
799 Bool_t PyROOT::TVoidArrayConverter::ToMemory( PyObject* value,
void* address )
801 if ( ObjectProxy_Check( value ) ) {
803 if ( ! fKeepControl && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
804 ((ObjectProxy*)value)->Release();
807 *(
void**)address = ((ObjectProxy*)value)->GetObject();
813 if ( GetAddressSpecialCase( value, ptr ) ) {
814 *(
void**)address = ptr;
820 int buflen = Utility::GetBuffer( value,
'*', 1, buf, kFALSE );
821 if ( ! buf || buflen == 0 )
824 *(
void**)address = buf;
830 #define PYROOT_IMPLEMENT_ARRAY_CONVERTER( name, type, code ) \
831 Bool_t PyROOT::T##name##ArrayConverter::SetArg( \
832 PyObject* pyobject, TParameter& para, TCallContext* ) \
834 return CArraySetArg( pyobject, para, code, sizeof(type) ); \
837 Bool_t PyROOT::T##name##ArrayRefConverter::SetArg( \
838 PyObject* pyobject, TParameter& para, TCallContext* ctxt ) \
840 Bool_t result = T##name##ArrayConverter::SetArg( pyobject, para, ctxt ); \
841 para.fTypeCode = 'V'; \
845 PyObject* PyROOT::T##name##ArrayConverter::FromMemory( void* address ) \
847 return BufFac_t::Instance()->PyBuffer_FromMemory( *(type**)address, fSize * sizeof(type) );\
850 Bool_t PyROOT::T##name##ArrayConverter::ToMemory( PyObject* value, void* address )\
853 int buflen = Utility::GetBuffer( value, code, sizeof(type), buf ); \
854 if ( ! buf || buflen == 0 ) \
856 if ( 0 <= fSize ) { \
857 if ( fSize < buflen/(int)sizeof(type) ) { \
858 PyErr_SetString( PyExc_ValueError, "buffer too large for value" ); \
861 memcpy( *(type**)address, buf, 0 < buflen ? ((size_t) buflen) : sizeof(type) );\
863 *(type**)address = (type*)buf; \
869 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Bool, Bool_t,
'b' )
870 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Short, Short_t, 'h' )
871 PYROOT_IMPLEMENT_ARRAY_CONVERTER( UShort, UShort_t, 'H' )
872 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Int, Int_t, 'i' )
873 PYROOT_IMPLEMENT_ARRAY_CONVERTER( UInt, UInt_t, 'I' )
874 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Long, Long_t, 'l' )
875 PYROOT_IMPLEMENT_ARRAY_CONVERTER( ULong, ULong_t, 'L' )
876 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Float, Float_t, 'f' )
877 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Double, Double_t, 'd' )
882 Bool_t PyROOT::TLongLongArrayConverter::SetArg(
883 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
885 PyObject* pytc = PyObject_GetAttr( pyobject, PyStrings::gTypeCode );
891 return TVoidArrayConverter::SetArg( pyobject, para, ctxt );
897 static std::tuple<const char*,Py_ssize_t> getStringAndSizeSTLString(PyObject* pyobject) {
898 #if PY_VERSION_HEX >= 0x03030000
901 auto charArr = PyROOT_PyUnicode_AsStringAndSize(pyobject, &size);
903 auto size = PyROOT_PyUnicode_GET_SIZE(pyobject);
904 auto charArr = PyROOT_PyUnicode_AsString(pyobject);
906 return std::tuple<const char*,Py_ssize_t>(charArr, size);
909 #define PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( name, type, F1, F2 ) \
910 PyROOT::T##name##Converter::T##name##Converter( Bool_t keepControl ) : \
911 TCppObjectConverter( Cppyy::GetScope( #type ), keepControl ) {} \
913 Bool_t PyROOT::T##name##Converter::SetArg( \
914 PyObject* pyobject, TParameter& para, TCallContext* ctxt ) \
916 if ( PyROOT_PyUnicode_Check( pyobject ) ) { \
917 auto strAndSize = getStringAndSizeSTLString(pyobject); \
918 fBuffer = type(std::get<0>(strAndSize), std::get<1>(strAndSize)); \
919 para.fValue.fVoidp = &fBuffer; \
920 para.fTypeCode = 'V'; \
924 if (PyBytes_Check(pyobject)) { \
925 auto s = PyBytes_AsString(pyobject); \
926 auto size = PyBytes_GET_SIZE(pyobject); \
927 fBuffer = type(s, size); \
928 para.fValue.fVoidp = &fBuffer; \
929 para.fTypeCode = 'V'; \
933 if ( ! ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) ) { \
934 Bool_t result = TCppObjectConverter::SetArg( pyobject, para, ctxt ); \
935 para.fTypeCode = 'V'; \
941 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
944 return PyROOT_PyUnicode_FromStringAndSize( ((type*)address)->F1(), ((type*)address)->F2() );\
945 Py_INCREF( PyStrings::gEmptyString ); \
946 return PyStrings::gEmptyString; \
949 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
951 if ( PyROOT_PyUnicode_Check( value ) ) { \
952 *((type*)address) = PyROOT_PyUnicode_AsString( value ); \
956 return TCppObjectConverter::ToMemory( value, address ); \
959 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( TString, TString, Data, Length )
960 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLString, std::
string, c_str, size )
961 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLStringView, std::string_view, data, size )
966 Bool_t PyROOT::TCppObjectConverter::SetArg(
967 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
969 if ( ! ObjectProxy_Check( pyobject ) ) {
970 if ( GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
971 para.fTypeCode =
'p';
979 ObjectProxy* pyobj = (ObjectProxy*)pyobject;
980 if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
982 if ( ! KeepControl() && ! UseStrictOwnership( ctxt ) )
983 ((ObjectProxy*)pyobject)->Release();
986 para.fValue.fVoidp = pyobj->GetObject();
987 if ( pyobj->ObjectIsA() != fClass ) {
988 para.fValue.fLong += Cppyy::GetBaseOffset(
989 pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 );
993 para.fTypeCode =
'p';
996 }
else if ( ! TClass::GetClass( Cppyy::GetFinalName( fClass ).c_str() )->GetClassInfo() ) {
998 para.fValue.fVoidp = pyobj->GetObject();
999 para.fTypeCode =
'p';
1009 PyObject* PyROOT::TCppObjectConverter::FromMemory(
void* address )
1011 return BindCppObject( address, fClass, kFALSE );
1017 Bool_t PyROOT::TCppObjectConverter::ToMemory( PyObject* value,
void* address )
1019 if ( ! ObjectProxy_Check( value ) ) {
1021 if ( GetAddressSpecialCase( value, ptr ) ) {
1022 *(
void**)address = ptr;
1030 if ( Cppyy::IsSubtype( ((ObjectProxy*)value)->ObjectIsA(), fClass ) ) {
1032 if ( ! KeepControl() && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
1033 ((ObjectProxy*)value)->Release();
1036 PyObject* pyobj = BindCppObjectNoCast( address, fClass );
1037 ((ObjectProxy*)pyobj)->Release();
1038 PyObject* result = PyObject_CallMethod( pyobj, (
char*)
"__assign__", (
char*)
"O", value );
1041 Py_DECREF( result );
1054 Bool_t PyROOT::TValueCppObjectConverter::SetArg(
1055 PyObject* pyobject, TParameter& para, TCallContext* )
1057 if ( ObjectProxy_Check( pyobject ) ) {
1058 ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1059 if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
1061 para.fValue.fVoidp = pyobj->GetObject();
1062 if ( ! para.fValue.fVoidp )
1065 if ( pyobj->ObjectIsA() != fClass ) {
1066 para.fValue.fLong += Cppyy::GetBaseOffset(
1067 pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 );
1070 para.fTypeCode =
'V';
1074 else if ( PyTuple_Check( pyobject ) ){
1079 PyObject* pyclass = CreateScopeProxy( fClass );
1080 if ( ! pyclass )
return kFALSE;
1081 fObjProxy = (ObjectProxy*)((PyTypeObject*)pyclass)->tp_new( (PyTypeObject*)pyclass, NULL, NULL );
1082 Py_DECREF( pyclass );
1085 if( fObjProxy->GetObject() ) {
1087 Cppyy::CallDestructor( fObjProxy->ObjectIsA(), fObjProxy->GetObject() );
1088 Cppyy::Deallocate( fObjProxy->ObjectIsA(), fObjProxy->GetObject() );
1089 fObjProxy->Set(
nullptr);
1093 PyObject* constructor = PyObject_GetAttr( (PyObject*)fObjProxy, PyStrings::gInit );
1094 if( ! constructor )
return kFALSE;
1097 PyObject* obj = PyObject_CallObject( constructor, pyobject );
1098 Py_DECREF( constructor );
1099 if ( ! obj )
return kFALSE;
1102 para.fValue.fVoidp = fObjProxy->GetObject();
1103 para.fTypeCode =
'V';
1113 Bool_t PyROOT::TRefCppObjectConverter::SetArg(
1114 PyObject* pyobject, TParameter& para, TCallContext* )
1116 if ( ObjectProxy_Check( pyobject ) ) {
1117 ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1118 if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
1120 para.fValue.fVoidp = pyobj->GetObject();
1121 if ( pyobj->ObjectIsA() != fClass ) {
1122 para.fValue.fLong += Cppyy::GetBaseOffset(
1123 pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 );
1126 para.fTypeCode =
'V';
1128 }
else if ( ! TClass::GetClass( Cppyy::GetFinalName( fClass ).c_str() )->GetClassInfo() ) {
1130 para.fValue.fVoidp = pyobj->GetObject();
1131 para.fTypeCode =
'V';
1135 else if ( PyTuple_Check( pyobject ) ){
1140 PyObject* pyclass = CreateScopeProxy( fClass );
1141 if ( ! pyclass )
return kFALSE;
1142 fObjProxy = (ObjectProxy*)((PyTypeObject*)pyclass)->tp_new( (PyTypeObject*)pyclass, NULL, NULL );
1143 Py_DECREF( pyclass );
1146 if( fObjProxy->GetObject() ) {
1148 Cppyy::CallDestructor( fObjProxy->ObjectIsA(), fObjProxy->GetObject() );
1149 Cppyy::Deallocate( fObjProxy->ObjectIsA(), fObjProxy->GetObject() );
1150 fObjProxy->Set(
nullptr);
1154 PyObject* constructor = PyObject_GetAttr( (PyObject*)fObjProxy, PyStrings::gInit );
1155 if( ! constructor )
return kFALSE;
1158 PyObject* obj = PyObject_CallObject( constructor, pyobject );
1159 Py_DECREF( constructor );
1160 if ( ! obj )
return kFALSE;
1163 para.fValue.fVoidp = fObjProxy->GetObject();
1164 para.fTypeCode =
'V';
1174 template <
bool ISREFERENCE>
1175 Bool_t PyROOT::TCppObjectPtrConverter<ISREFERENCE>::SetArg(
1176 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
1178 if ( ! ObjectProxy_Check( pyobject ) )
1181 if ( Cppyy::IsSubtype( ((ObjectProxy*)pyobject)->ObjectIsA(), fClass ) ) {
1183 if ( ! KeepControl() && ! UseStrictOwnership( ctxt ) )
1184 ((ObjectProxy*)pyobject)->Release();
1187 if( ((ObjectProxy*)pyobject)->fFlags & ObjectProxy::kIsReference)
1189 para.fValue.fVoidp = ((ObjectProxy*)pyobject)->fObject;
1191 para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1192 para.fTypeCode = ISREFERENCE ?
'V' :
'p';
1202 template <
bool ISREFERENCE>
1203 PyObject* PyROOT::TCppObjectPtrConverter<ISREFERENCE>::FromMemory(
void* address )
1205 return BindCppObject( address, fClass, kTRUE );
1211 template <
bool ISREFERENCE>
1212 Bool_t PyROOT::TCppObjectPtrConverter<ISREFERENCE>::ToMemory( PyObject* value,
void* address )
1214 if ( ! ObjectProxy_Check( value ) )
1217 if ( Cppyy::IsSubtype( ((ObjectProxy*)value)->ObjectIsA(), fClass ) ) {
1219 if ( ! KeepControl() && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
1220 ((ObjectProxy*)value)->Release();
1223 *(
void**)address = ((ObjectProxy*)value)->GetObject();
1235 template class TCppObjectPtrConverter<true>;
1236 template class TCppObjectPtrConverter<false>;
1242 Bool_t PyROOT::TCppObjectArrayConverter::SetArg(
1243 PyObject* pyobject, TParameter& para, TCallContext* )
1245 if ( ! TTupleOfInstances_CheckExact( pyobject ) )
1250 if ( PyTuple_Size( pyobject ) < 1 )
1253 PyObject* first = PyTuple_GetItem( pyobject, 0 );
1254 if ( ! ObjectProxy_Check( first ) )
1257 if ( Cppyy::IsSubtype( ((ObjectProxy*)first)->ObjectIsA(), fClass ) ) {
1259 para.fValue.fVoidp = ((ObjectProxy*)first)->fObject;
1260 para.fTypeCode =
'p';
1270 PyObject* PyROOT::TCppObjectArrayConverter::FromMemory(
void* address )
1273 return BindCppObjectNoCast( address, fClass );
1275 return BindCppObjectArray( address, fClass, m_size );
1281 Bool_t PyROOT::TCppObjectArrayConverter::ToMemory( PyObject* ,
void* )
1284 PyErr_SetString( PyExc_NotImplementedError,
1285 "access to C-arrays of objects not yet implemented!" );
1292 Bool_t PyROOT::TSTLIteratorConverter::SetArg(
1293 PyObject* pyobject, TParameter& para, TCallContext* )
1295 if ( ! ObjectProxy_Check( pyobject ) )
1299 ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1300 para.fValue.fVoidp = pyobj->GetObject();
1301 para.fTypeCode =
'V';
1309 Bool_t PyROOT::TVoidPtrRefConverter::SetArg(
1310 PyObject* pyobject, TParameter& para, TCallContext* )
1312 if ( ObjectProxy_Check( pyobject ) ) {
1313 para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1314 para.fTypeCode =
'V';
1324 Bool_t PyROOT::TVoidPtrPtrConverter::SetArg(
1325 PyObject* pyobject, TParameter& para, TCallContext* )
1327 if ( ObjectProxy_Check( pyobject ) ) {
1329 para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1330 para.fTypeCode =
'p';
1335 int buflen = Utility::GetBuffer( pyobject,
'*', 1, para.fValue.fVoidp, kFALSE );
1338 if ( para.fValue.fVoidp && buflen != 0 ) {
1339 para.fTypeCode =
'p';
1349 PyObject* PyROOT::TVoidPtrPtrConverter::FromMemory(
void* address )
1351 if ( ! address || *(ptrdiff_t*)address == 0 ) {
1352 Py_INCREF( gNullPtrObject );
1353 return gNullPtrObject;
1355 return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)*(ptrdiff_t**)address,
sizeof(
void*) );
1361 Bool_t PyROOT::TPyObjectConverter::SetArg(
1362 PyObject* pyobject, TParameter& para, TCallContext* )
1364 para.fValue.fVoidp = pyobject;
1365 para.fTypeCode =
'p';
1369 PyObject* PyROOT::TPyObjectConverter::FromMemory(
void* address )
1372 PyObject* pyobject = *((PyObject**)address);
1375 Py_INCREF( Py_None );
1379 Py_INCREF( pyobject );
1383 Bool_t PyROOT::TPyObjectConverter::ToMemory( PyObject* value,
void* address )
1387 *((PyObject**)address) = value;
1395 Bool_t PyROOT::TSmartPtrCppObjectConverter::SetArg(
1396 PyObject* pyobject, TParameter& para, TCallContext* ctxt )
1398 char typeCode = fHandlePtr ?
'p' :
'V';
1400 if ( ! ObjectProxy_Check( pyobject ) ) {
1401 if ( fHandlePtr && GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
1402 para.fTypeCode = typeCode;
1409 ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1412 if ( pyobj->fFlags & ObjectProxy::kIsSmartPtr && Cppyy::IsSubtype( pyobj->fSmartPtrType, fClass ) ) {
1414 if ( fKeepControl && ! UseStrictOwnership( ctxt ) )
1415 ((ObjectProxy*)pyobject)->Release();
1418 para.fValue.fVoidp = pyobj->fSmartPtr;
1419 if ( pyobj->fSmartPtrType != fClass ) {
1420 para.fValue.fLong += Cppyy::GetBaseOffset(
1421 pyobj->fSmartPtrType, fClass, para.fValue.fVoidp, 1 );
1425 para.fTypeCode = typeCode;
1430 if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
1432 para.fValue.fVoidp = pyobj->GetObject();
1433 if ( pyobj->ObjectIsA() != fClass ) {
1434 para.fValue.fLong += Cppyy::GetBaseOffset(
1435 pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 );
1439 para.fTypeCode = typeCode;
1446 PyObject* PyROOT::TSmartPtrCppObjectConverter::FromMemory(
void* address )
1448 if ( !address || !fClass )
1452 std::vector<TParameter> args;
1453 ObjectProxy* pyobj = (ObjectProxy*) BindCppObject(
1454 Cppyy::CallR( (Cppyy::TCppMethod_t)fDereferencer, address, &args ), fRawPtrType );
1456 pyobj->SetSmartPtr( (
void*)address, fClass );
1458 return (PyObject*)pyobj;
1465 Bool_t PyROOT::TNotImplementedConverter::SetArg( PyObject*, TParameter&, TCallContext* )
1467 PyErr_SetString( PyExc_NotImplementedError,
"this method can not (yet) be called" );
1473 PyROOT::TConverter* PyROOT::CreateConverter(
const std::string& fullType, Long_t size )
1485 ConvFactories_t::iterator h = gConvFactories.find( fullType );
1486 if ( h != gConvFactories.end() )
1487 return (h->second)( size );
1490 std::string resolvedType = Cppyy::ResolveName( fullType );
1493 h = gConvFactories.find( resolvedType );
1494 if ( h != gConvFactories.end() )
1495 return (h->second)( size );
1498 const std::string& cpd = Utility::Compound( resolvedType );
1499 std::string realType = TClassEdit::ShortType( resolvedType.c_str(), 1 );
1502 h = gConvFactories.find( realType + cpd );
1503 if ( h != gConvFactories.end() )
1504 return (h->second)( size );
1510 realType = TClassEdit::CleanType( realType.substr( 0, realType.rfind(
"(") ).c_str(), 1 );
1514 if ( cpd ==
"[]" ) {
1515 h = gConvFactories.find( realType +
"*" );
1516 if ( h != gConvFactories.end() )
1517 return (h->second)( size );
1521 Bool_t isConst = resolvedType.substr(0, 5) ==
"const";
1522 Bool_t control = cpd ==
"&" || isConst;
1525 TConverter* result = 0;
1526 if ( Cppyy::TCppScope_t klass = Cppyy::GetScope( realType ) ) {
1527 if ( Cppyy::IsSmartPtr( realType ) ) {
1528 const std::vector< Cppyy::TCppMethod_t > methods = Cppyy::GetMethodsFromName( klass,
"operator->",
true );
1529 if ( ! methods.empty() ) {
1530 Cppyy::TCppType_t rawPtrType = Cppyy::GetScope(
1531 TClassEdit::ShortType( Cppyy::GetMethodResultType( methods[0] ).c_str(), 1 ) );
1534 result =
new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0], control );
1535 }
else if ( cpd ==
"&" ) {
1536 result =
new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0] );
1537 }
else if ( cpd ==
"*" && size <= 0 ) {
1538 result =
new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0], control, kTRUE );
1549 if ( realType.find(
"__gnu_cxx::__normal_iterator", 0 ) == 0 )
1550 result =
new TSTLIteratorConverter();
1553 if ( cpd ==
"**" || cpd ==
"&*" )
1554 result =
new TCppObjectPtrConverter<false>( klass, control);
1555 else if ( cpd ==
"*&" )
1556 result =
new TCppObjectPtrConverter<true>( klass, control);
1557 else if ( cpd ==
"*" && size <= 0 )
1558 result =
new TCppObjectConverter( klass, control );
1559 else if ( cpd ==
"&" )
1560 result =
new TRefCppObjectConverter( klass );
1561 else if ( cpd ==
"[]" || size > 0 )
1562 result =
new TCppObjectArrayConverter( klass, size, kFALSE );
1563 else if ( cpd ==
"" )
1564 result =
new TValueCppObjectConverter( klass, kTRUE );
1566 }
else if ( Cppyy::IsEnum( realType ) ) {
1568 std::string et(TClassEdit::ResolveTypedef(Cppyy::ResolveEnum(realType).c_str()));
1570 auto reft = et +
"&";
1571 h = isConst ? gConvFactories.find(
"const " + reft) : gConvFactories.find(reft);
1573 h = gConvFactories.find(et);
1574 }
else if ( realType.find(
"(*)" ) != std::string::npos ||
1575 ( realType.find(
"::*)" ) != std::string::npos ) ) {
1579 h = gConvFactories.find(
"void*" );
1582 if ( ! result && cpd ==
"&&" )
1583 result =
new TNotImplementedConverter();
1585 if ( ! result && h != gConvFactories.end() )
1587 result = (h->second)( size );
1588 else if ( ! result ) {
1590 std::stringstream s;
1591 s <<
"creating converter for unknown type \"" << fullType <<
"\"" << std::ends;
1592 PyErr_Warn( PyExc_RuntimeWarning, (
char*)s.str().c_str() );
1593 result =
new TVoidArrayConverter();
1595 result =
new TVoidConverter();
1603 #define PYROOT_BASIC_CONVERTER_FACTORY( name ) \
1604 TConverter* Create##name##Converter( Long_t ) \
1606 return new T##name##Converter(); \
1609 #define PYROOT_ARRAY_CONVERTER_FACTORY( name ) \
1610 TConverter* Create##name##Converter( Long_t size ) \
1612 return new T##name##Converter( size ); \
1618 using namespace PyROOT;
1621 PYROOT_BASIC_CONVERTER_FACTORY( Bool )
1622 PYROOT_BASIC_CONVERTER_FACTORY( ConstBoolRef )
1623 PYROOT_BASIC_CONVERTER_FACTORY( Char )
1624 PYROOT_BASIC_CONVERTER_FACTORY( ConstCharRef )
1625 PYROOT_BASIC_CONVERTER_FACTORY( UChar )
1626 PYROOT_BASIC_CONVERTER_FACTORY( ConstUCharRef )
1627 PYROOT_BASIC_CONVERTER_FACTORY( Short )
1628 PYROOT_BASIC_CONVERTER_FACTORY( ConstShortRef )
1629 PYROOT_BASIC_CONVERTER_FACTORY( UShort )
1630 PYROOT_BASIC_CONVERTER_FACTORY( ConstUShortRef )
1631 PYROOT_BASIC_CONVERTER_FACTORY( Int )
1632 PYROOT_BASIC_CONVERTER_FACTORY( IntRef )
1633 PYROOT_BASIC_CONVERTER_FACTORY( ConstIntRef )
1634 PYROOT_BASIC_CONVERTER_FACTORY( UInt )
1635 PYROOT_BASIC_CONVERTER_FACTORY( ConstUIntRef )
1636 PYROOT_BASIC_CONVERTER_FACTORY( Long )
1637 PYROOT_BASIC_CONVERTER_FACTORY( LongRef )
1638 PYROOT_BASIC_CONVERTER_FACTORY( ConstLongRef )
1639 PYROOT_BASIC_CONVERTER_FACTORY( ULong )
1640 PYROOT_BASIC_CONVERTER_FACTORY( ConstULongRef )
1641 PYROOT_BASIC_CONVERTER_FACTORY( Float )
1642 PYROOT_BASIC_CONVERTER_FACTORY( ConstFloatRef )
1643 PYROOT_BASIC_CONVERTER_FACTORY( Double )
1644 PYROOT_BASIC_CONVERTER_FACTORY( DoubleRef )
1645 PYROOT_BASIC_CONVERTER_FACTORY( ConstDoubleRef )
1646 PYROOT_BASIC_CONVERTER_FACTORY( LongDouble )
1647 PYROOT_BASIC_CONVERTER_FACTORY( ConstLongDoubleRef )
1648 PYROOT_BASIC_CONVERTER_FACTORY( Void )
1649 PYROOT_BASIC_CONVERTER_FACTORY( LongLong )
1650 PYROOT_BASIC_CONVERTER_FACTORY( ConstLongLongRef )
1651 PYROOT_BASIC_CONVERTER_FACTORY( ULongLong )
1652 PYROOT_BASIC_CONVERTER_FACTORY( ConstULongLongRef )
1653 PYROOT_ARRAY_CONVERTER_FACTORY( CString )
1654 PYROOT_ARRAY_CONVERTER_FACTORY( NonConstCString )
1655 PYROOT_ARRAY_CONVERTER_FACTORY( NonConstUCString )
1656 PYROOT_ARRAY_CONVERTER_FACTORY( BoolArray )
1657 PYROOT_BASIC_CONVERTER_FACTORY( BoolArrayRef )
1658 PYROOT_ARRAY_CONVERTER_FACTORY( ShortArray )
1659 PYROOT_ARRAY_CONVERTER_FACTORY( ShortArrayRef )
1660 PYROOT_ARRAY_CONVERTER_FACTORY( UShortArray )
1661 PYROOT_ARRAY_CONVERTER_FACTORY( UShortArrayRef )
1662 PYROOT_ARRAY_CONVERTER_FACTORY( IntArray )
1663 PYROOT_ARRAY_CONVERTER_FACTORY( UIntArray )
1664 PYROOT_ARRAY_CONVERTER_FACTORY( UIntArrayRef )
1665 PYROOT_ARRAY_CONVERTER_FACTORY( LongArray )
1666 PYROOT_ARRAY_CONVERTER_FACTORY( ULongArray )
1667 PYROOT_ARRAY_CONVERTER_FACTORY( ULongArrayRef )
1668 PYROOT_ARRAY_CONVERTER_FACTORY( FloatArray )
1669 PYROOT_ARRAY_CONVERTER_FACTORY( FloatArrayRef )
1670 PYROOT_ARRAY_CONVERTER_FACTORY( DoubleArray )
1671 PYROOT_BASIC_CONVERTER_FACTORY( VoidArray )
1672 PYROOT_BASIC_CONVERTER_FACTORY( LongLongArray )
1673 PYROOT_BASIC_CONVERTER_FACTORY( TString )
1674 PYROOT_BASIC_CONVERTER_FACTORY( STLString )
1675 PYROOT_BASIC_CONVERTER_FACTORY( STLStringView )
1676 PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrRef )
1677 PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrPtr )
1678 PYROOT_BASIC_CONVERTER_FACTORY( PyObject )
1681 typedef std::pair< const
char*, ConverterFactory_t > NFp_t;
1684 NFp_t factories_[] = {
1686 NFp_t(
"bool", &CreateBoolConverter ),
1687 NFp_t(
"const bool&", &CreateConstBoolRefConverter ),
1688 NFp_t(
"char", &CreateCharConverter ),
1689 NFp_t(
"const char&", &CreateConstCharRefConverter ),
1690 NFp_t(
"signed char", &CreateCharConverter ),
1691 NFp_t(
"const signed char&", &CreateConstCharRefConverter ),
1692 NFp_t(
"unsigned char", &CreateUCharConverter ),
1693 NFp_t(
"const unsigned char&", &CreateConstUCharRefConverter ),
1694 NFp_t(
"short", &CreateShortConverter ),
1695 NFp_t(
"const short&", &CreateConstShortRefConverter ),
1696 NFp_t(
"unsigned short", &CreateUShortConverter ),
1697 NFp_t(
"const unsigned short&", &CreateConstUShortRefConverter ),
1698 NFp_t(
"int", &CreateIntConverter ),
1699 NFp_t(
"int&", &CreateIntRefConverter ),
1700 NFp_t(
"const int&", &CreateConstIntRefConverter ),
1701 NFp_t(
"unsigned int", &CreateUIntConverter ),
1702 NFp_t(
"const unsigned int&", &CreateConstUIntRefConverter ),
1703 NFp_t(
"long", &CreateLongConverter ),
1704 NFp_t(
"long&", &CreateLongRefConverter ),
1705 NFp_t(
"const long&", &CreateConstLongRefConverter ),
1706 NFp_t(
"unsigned long", &CreateULongConverter ),
1707 NFp_t(
"const unsigned long&", &CreateConstULongRefConverter ),
1708 NFp_t(
"long long", &CreateLongLongConverter ),
1709 NFp_t(
"const long long&", &CreateConstLongLongRefConverter ),
1710 NFp_t(
"Long64_t", &CreateLongLongConverter ),
1711 NFp_t(
"const Long64_t&", &CreateConstLongLongRefConverter ),
1712 NFp_t(
"unsigned long long", &CreateULongLongConverter ),
1713 NFp_t(
"const unsigned long long&", &CreateConstULongLongRefConverter ),
1714 NFp_t(
"ULong64_t", &CreateULongLongConverter ),
1715 NFp_t(
"const ULong64_t&", &CreateConstULongLongRefConverter ),
1717 NFp_t(
"float", &CreateFloatConverter ),
1718 NFp_t(
"const float&", &CreateConstFloatRefConverter ),
1719 NFp_t(
"double", &CreateDoubleConverter ),
1720 NFp_t(
"double&", &CreateDoubleRefConverter ),
1721 NFp_t(
"const double&", &CreateConstDoubleRefConverter ),
1722 NFp_t(
"long double", &CreateLongDoubleConverter ),
1723 NFp_t(
"const long double&", &CreateConstLongDoubleRefConverter ),
1724 NFp_t(
"void", &CreateVoidConverter ),
1727 NFp_t(
"bool*", &CreateBoolArrayConverter ),
1728 NFp_t(
"bool&", &CreateBoolArrayRefConverter ),
1729 NFp_t(
"const unsigned char*", &CreateCStringConverter ),
1730 NFp_t(
"unsigned char*", &CreateNonConstUCStringConverter ),
1731 NFp_t(
"short*", &CreateShortArrayConverter ),
1732 NFp_t(
"short&", &CreateShortArrayRefConverter ),
1733 NFp_t(
"unsigned short*", &CreateUShortArrayConverter ),
1734 NFp_t(
"unsigned short&", &CreateUShortArrayRefConverter ),
1735 NFp_t(
"int*", &CreateIntArrayConverter ),
1736 NFp_t(
"unsigned int*", &CreateUIntArrayConverter ),
1737 NFp_t(
"unsigned int&", &CreateUIntArrayRefConverter ),
1738 NFp_t(
"long*", &CreateLongArrayConverter ),
1739 NFp_t(
"unsigned long*", &CreateULongArrayConverter ),
1740 NFp_t(
"unsigned long&", &CreateULongArrayRefConverter ),
1741 NFp_t(
"float*", &CreateFloatArrayConverter ),
1742 NFp_t(
"float&", &CreateFloatArrayRefConverter ),
1743 NFp_t(
"double*", &CreateDoubleArrayConverter ),
1744 NFp_t(
"long long*", &CreateLongLongArrayConverter ),
1745 NFp_t(
"Long64_t*", &CreateLongLongArrayConverter ),
1746 NFp_t(
"unsigned long long*", &CreateLongLongArrayConverter ),
1747 NFp_t(
"ULong64_t*", &CreateLongLongArrayConverter ),
1748 NFp_t(
"void*", &CreateVoidArrayConverter ),
1751 NFp_t(
"const char*", &CreateCStringConverter ),
1752 NFp_t(
"char*", &CreateNonConstCStringConverter ),
1753 NFp_t(
"TString", &CreateTStringConverter ),
1754 NFp_t(
"const TString&", &CreateTStringConverter ),
1755 NFp_t(
"std::string", &CreateSTLStringConverter ),
1756 NFp_t(
"string", &CreateSTLStringConverter ),
1757 NFp_t(
"const std::string&", &CreateSTLStringConverter ),
1758 NFp_t(
"const string&", &CreateSTLStringConverter ),
1759 NFp_t(
"std::string_view", &CreateSTLStringViewConverter ),
1760 NFp_t(
"string_view", &CreateSTLStringViewConverter ),
1761 NFp_t(
"experimental::basic_string_view<char,char_traits<char> >",&CreateSTLStringViewConverter),
1762 NFp_t(
"basic_string_view<char,char_traits<char> >",&CreateSTLStringViewConverter),
1763 NFp_t(
"void*&", &CreateVoidPtrRefConverter ),
1764 NFp_t(
"void**", &CreateVoidPtrPtrConverter ),
1765 NFp_t(
"PyObject*", &CreatePyObjectConverter ),
1766 NFp_t(
"_object*", &CreatePyObjectConverter ),
1767 NFp_t(
"FILE*", &CreateVoidArrayConverter ),
1768 NFp_t(
"Float16_t", &CreateFloatConverter ),
1769 NFp_t(
"const Float16_t&", &CreateConstFloatRefConverter ),
1770 NFp_t(
"Double32_t", &CreateDoubleConverter ),
1771 NFp_t(
"Double32_t&", &CreateDoubleRefConverter ),
1772 NFp_t(
"const Double32_t&", &CreateConstDoubleRefConverter )
1776 struct InitConvFactories_t {
1778 InitConvFactories_t()
1781 int nf =
sizeof( factories_ ) /
sizeof( factories_[ 0 ] );
1782 for (
int i = 0; i < nf; ++i ) {
1783 gConvFactories[ factories_[ i ].first ] = factories_[ i ].second;
1786 } initConvFactories_;