Logo ROOT   6.08/07
Reference Guide
Converters.cxx
Go to the documentation of this file.
1 // @(#)root/pyroot:$Id$
2 // Author: Wim Lavrijsen, Jan 2005
3 
4 // Bindings
5 #include "PyROOT.h"
6 #include "PyStrings.h"
7 #include "Converters.h"
8 #include "TCallContext.h"
9 #include "ObjectProxy.h"
10 #include "TPyBufferFactory.h"
11 #include "TCustomPyTypes.h"
12 #include "TTupleOfInstances.h"
13 #include "Utility.h"
14 #include "RootWrapper.h"
15 
16 // ROOT
17 #include "TClass.h" // for checking class info existence
18 #include "TClassEdit.h" // for CleanType and ShortType
19 
20 // Standard
21 #include <limits.h>
22 #include <stddef.h> // for ptrdiff_t
23 #include <string.h>
24 #include <utility>
25 #include <sstream>
26 
27 
28 //- data ______________________________________________________________________
29 namespace PyROOT {
30 
31 // factories
32  typedef TConverter* (*ConverterFactory_t) ( Long_t size );
33  typedef std::map< std::string, ConverterFactory_t > ConvFactories_t;
34  ConvFactories_t gConvFactories;
36 
37 }
38 
39 //- pretend-ctypes helpers ----------------------------------------------------
40 #if PY_VERSION_HEX >= 0x02050000
41 
42 struct PyROOT_tagCDataObject { // non-public (but so far very stable)
43  PyObject_HEAD
44  char* b_ptr;
45 };
46 
47 static inline PyTypeObject* GetCTypesType( const char* name ) {
48  PyObject* ct = PyImport_ImportModule( "ctypes" );
49  if ( ! ct ) return nullptr;
50  PyTypeObject* ct_t = (PyTypeObject*)PyObject_GetAttrString( ct, name );
51  Py_DECREF( ct );
52  return ct_t;
53 }
54 
55 #endif
56 
57 //- custom helpers to check ranges --------------------------------------------
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// range-checking python integer to C++ bool conversion
61 static inline Bool_t PyROOT_PyLong_AsBool( PyObject* pyobject )
62 {
63  Long_t l = PyLong_AsLong( pyobject );
64 // fail to pass float -> bool; the problem is rounding (0.1 -> 0 -> False)
65  if ( ! ( l == 0 || l == 1 ) || PyFloat_Check( pyobject ) ) {
66  PyErr_SetString( PyExc_ValueError, "boolean value should be bool, or integer 1 or 0" );
67  return (Bool_t)-1;
68  }
69  return (Bool_t)l;
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// python string to C++ char conversion
74 static inline Char_t PyROOT_PyUnicode_AsChar( PyObject* pyobject ) {
75  return (Char_t)PyROOT_PyUnicode_AsString( pyobject )[0];
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// range-checking python integer to C++ unsigend short int conversion
80 static inline UShort_t PyROOT_PyLong_AsUShort( PyObject* pyobject )
81 {
82 // prevent p2.7 silent conversions and do a range check
83  if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
84  PyErr_SetString( PyExc_TypeError, "unsigned short converion expects an integer object" );
85  return (UShort_t)-1;
86  }
87  Long_t l = PyLong_AsLong( pyobject );
88  if ( l < 0 || USHRT_MAX < l ) {
89  PyErr_Format( PyExc_ValueError, "integer %ld out of range for unsigned short", l );
90  return (UShort_t)-1;
91 
92  }
93  return (UShort_t)l;
94 }
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 /// range-checking python integer to C++ short int conversion
98 static inline Short_t PyROOT_PyLong_AsShort( PyObject* pyobject )
99 {
100 // prevent p2.7 silent conversions and do a range check
101  if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
102  PyErr_SetString( PyExc_TypeError, "short int converion expects an integer object" );
103  return (Short_t)-1;
104  }
105  Long_t l = PyLong_AsLong( pyobject );
106  if ( l < SHRT_MIN || SHRT_MAX < l ) {
107  PyErr_Format( PyExc_ValueError, "integer %ld out of range for short int", l );
108  return (Short_t)-1;
109 
110  }
111  return (Short_t)l;
112 }
113 
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// strict python integer to C++ integer conversion
117 static inline Long_t PyROOT_PyLong_AsStrictLong( PyObject* pyobject )
118 {
119 // p2.7 and later silently converts floats to long, therefore require this
120 // check; earlier pythons may raise a SystemError which should be avoided as
121 // it is confusing
122  if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) ) {
123  PyErr_SetString( PyExc_TypeError, "int/long converion expects an integer object" );
124  return (Long_t)-1;
125  }
126  return (Long_t)PyLong_AsLong( pyobject );
127 }
128 
129 
130 //- base converter implementation ---------------------------------------------
132 {
133 // could happen if no derived class override
134  PyErr_SetString( PyExc_TypeError, "C++ type can not be converted from memory" );
135  return 0;
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// could happen if no derived class override
140 
142 {
143  PyErr_SetString( PyExc_TypeError, "C++ type can not be converted to memory" );
144  return kFALSE;
145 }
146 
147 
148 //- helper macro's ------------------------------------------------------------
149 #define PYROOT_IMPLEMENT_BASIC_CONVERTER( name, type, stype, F1, F2, tc ) \
150 Bool_t PyROOT::T##name##Converter::SetArg( \
151  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ ) \
152 { \
153 /* convert <pyobject> to C++ 'type', set arg for call */ \
154  type val = (type)F2( pyobject ); \
155  if ( val == (type)-1 && PyErr_Occurred() ) \
156  return kFALSE; \
157  para.fValue.f##name = val; \
158  para.fTypeCode = tc; \
159  return kTRUE; \
160 } \
161  \
162 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
163 { \
164  return F1( (stype)*((type*)address) ); \
165 } \
166  \
167 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
168 { \
169  type s = (type)F2( value ); \
170  if ( s == (type)-1 && PyErr_Occurred() ) \
171  return kFALSE; \
172  *((type*)address) = (type)s; \
173  return kTRUE; \
174 }
175 
176 
177 static inline Int_t ExtractChar( PyObject* pyobject, const char* tname, Int_t low, Int_t high )
178 {
179  Int_t lchar = -1;
180  if ( PyROOT_PyUnicode_Check( pyobject ) ) {
181  if ( PyROOT_PyUnicode_GET_SIZE( pyobject ) == 1 )
182  lchar = (Int_t)PyROOT_PyUnicode_AsChar( pyobject );
183  else
184  PyErr_Format( PyExc_TypeError, "%s expected, got string of size " PY_SSIZE_T_FORMAT,
185  tname, PyROOT_PyUnicode_GET_SIZE( pyobject ) );
186  } else if ( ! PyFloat_Check( pyobject ) ) { // don't allow truncating conversion
187  lchar = PyLong_AsLong( pyobject );
188  if ( lchar == -1 && PyErr_Occurred() )
189  ; // empty, as error already set
190  else if ( ! ( low <= lchar && lchar <= high ) ) {
191  PyErr_Format( PyExc_ValueError,
192  "integer to character: value %d not in range [%d,%d]", lchar, low, high );
193  lchar = -1;
194  }
195  } else
196  PyErr_SetString( PyExc_TypeError, "char or small int type expected" );
197 
198  return lchar;
199 }
200 
201 
202 #define PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( name, type, F1 )\
203 Bool_t PyROOT::TConst##name##RefConverter::SetArg( \
204  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ ) \
205 { \
206  type val = (type)F1( pyobject ); \
207  if ( val == (type)-1 && PyErr_Occurred() ) \
208  return kFALSE; \
209  para.fValue.f##name = val; \
210  para.fRef = &para.fValue.f##name; \
211  para.fTypeCode = 'r'; \
212  return kTRUE; \
213 }
214 
215 #define PYROOT_IMPLEMENT_BASIC_CONST_CHAR_REF_CONVERTER( name, type, low, high )\
216 Bool_t PyROOT::TConst##name##RefConverter::SetArg( \
217  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ ) \
218 { \
219 /* convert <pyobject> to C++ <<type>>, set arg for call, allow int -> char */ \
220  type val = (type)ExtractChar( pyobject, #type, low, high ); \
221  if ( val == (type)-1 && PyErr_Occurred() ) \
222  return kFALSE; \
223  para.fValue.fLong = val; \
224  para.fTypeCode = 'l'; \
225  return kTRUE; \
226 }
227 
228 
229 ////////////////////////////////////////////////////////////////////////////////
230 
231 #define PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( name, type, low, high ) \
232 Bool_t PyROOT::T##name##Converter::SetArg( \
233  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ ) \
234 { \
235 /* convert <pyobject> to C++ <<type>>, set arg for call, allow int -> char */ \
236  Long_t val = ExtractChar( pyobject, #type, low, high ); \
237  if ( val == -1 && PyErr_Occurred() ) \
238  return kFALSE; \
239  para.fValue.fLong = val; \
240  para.fTypeCode = 'l'; \
241  return kTRUE; \
242 } \
243  \
244 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
245 { \
246  return PyROOT_PyUnicode_FromFormat( "%c", *((type*)address) ); \
247 } \
248  \
249 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
250 { \
251  if ( PyROOT_PyUnicode_Check( value ) ) { \
252  const char* buf = PyROOT_PyUnicode_AsString( value ); \
253  if ( PyErr_Occurred() ) \
254  return kFALSE; \
255  int len = PyROOT_PyUnicode_GET_SIZE( value ); \
256  if ( len != 1 ) { \
257  PyErr_Format( PyExc_TypeError, #type" expected, got string of size %d", len );\
258  return kFALSE; \
259  } \
260  *((type*)address) = (type)buf[0]; \
261  } else { \
262  Long_t l = PyLong_AsLong( value ); \
263  if ( l == -1 && PyErr_Occurred() ) \
264  return kFALSE; \
265  if ( ! ( low <= l && l <= high ) ) { \
266  PyErr_Format( PyExc_ValueError, \
267  "integer to character: value %ld not in range [%d,%d]", l, low, high );\
268  return kFALSE; \
269  } \
270  *((type*)address) = (type)l; \
271  } \
272  return kTRUE; \
273 }
274 
275 
276 //- converters for built-ins --------------------------------------------------
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// convert <pyobject> to C++ long&, set arg for call
281 
282 Bool_t PyROOT::TLongRefConverter::SetArg(
283  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
284 {
285 #if PY_VERSION_HEX < 0x03000000
286  if ( TCustomInt_CheckExact( pyobject ) ) {
287  para.fValue.fVoidp = (void*)&((PyIntObject*)pyobject)->ob_ival;
288  para.fTypeCode = 'V';
289  return kTRUE;
290  }
291 #endif
292 
293 #if PY_VERSION_HEX < 0x02050000
294  PyErr_SetString( PyExc_TypeError, "use ROOT.Long for pass-by-ref of longs" );
295  return kFALSE;
296 #endif
297 
298 // TODO: this keeps a refcount to the type .. it should be okay to drop that
299  static PyTypeObject* c_long_type = GetCTypesType( "c_long" );
300  if ( Py_TYPE( pyobject ) == c_long_type ) {
301  para.fValue.fVoidp = (void*)((PyROOT_tagCDataObject*)pyobject)->b_ptr;
302  para.fTypeCode = 'V';
303  return kTRUE;
304  }
305 
306  PyErr_SetString( PyExc_TypeError, "use ctypes.c_long for pass-by-ref of longs" );
307  return kFALSE;
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 
314 
322 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( LongLong, Long64_t, PyLong_AsLongLong )
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 /// convert <pyobject> to C++ (pseudo)int&, set arg for call
327 
328 Bool_t PyROOT::TIntRefConverter::SetArg(
329  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
330 {
331 #if PY_VERSION_HEX < 0x03000000
332  if ( TCustomInt_CheckExact( pyobject ) ) {
333  para.fValue.fVoidp = (void*)&((PyIntObject*)pyobject)->ob_ival;
334  para.fTypeCode = 'V';
335  return kTRUE;
336  }
337 #endif
338 
339 #if PY_VERSION_HEX >= 0x02050000
340 // TODO: this keeps a refcount to the type .. it should be okay to drop that
341  static PyTypeObject* c_int_type = GetCTypesType( "c_int" );
342  if ( Py_TYPE( pyobject ) == c_int_type ) {
343  para.fValue.fVoidp = (void*)((PyROOT_tagCDataObject*)pyobject)->b_ptr;
344  para.fTypeCode = 'V';
345  return kTRUE;
346  }
347 #endif
348 
349 // alternate, pass pointer from buffer
350  int buflen = Utility::GetBuffer( pyobject, 'i', sizeof(int), para.fValue.fVoidp );
351  if ( para.fValue.fVoidp && buflen ) {
352  para.fTypeCode = 'V';
353  return kTRUE;
354  };
355 
356 #if PY_VERSION_HEX < 0x02050000
357  PyErr_SetString( PyExc_TypeError, "use ROOT.Long for pass-by-ref of ints" );
358 #else
359  PyErr_SetString( PyExc_TypeError, "use ctypes.c_int for pass-by-ref of ints" );
360 #endif
361  return kFALSE;
362 }
363 
364 ////////////////////////////////////////////////////////////////////////////////
365 /// convert <pyobject> to C++ bool, allow int/long -> bool, set arg for call
366 
368 
369 ////////////////////////////////////////////////////////////////////////////////
370 
371 PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( Char, Char_t, CHAR_MIN, CHAR_MAX )
373 
374 ////////////////////////////////////////////////////////////////////////////////
375 
379 
380 ////////////////////////////////////////////////////////////////////////////////
381 /// convert <pyobject> to C++ unsigned long, set arg for call
382 
383 Bool_t PyROOT::TULongConverter::SetArg(
384  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
385 {
386  para.fValue.fULong = PyLongOrInt_AsULong( pyobject );
387  if ( PyErr_Occurred() )
388  return kFALSE;
389  para.fTypeCode = 'U';
390  return kTRUE;
391 }
392 
393 PyObject* PyROOT::TULongConverter::FromMemory( void* address )
394 {
395 // construct python object from C++ unsigned long read at <address>
396  return PyLong_FromUnsignedLong( *((ULong_t*)address) );
397 }
398 
399 Bool_t PyROOT::TULongConverter::ToMemory( PyObject* value, void* address )
400 {
401 // convert <value> to C++ unsigned long, write it at <address>
402  ULong_t u = PyLongOrInt_AsULong( value );
403  if ( PyErr_Occurred() )
404  return kFALSE;
405  *((ULong_t*)address) = u;
406  return kTRUE;
407 }
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// construct python object from C++ unsigned int read at <address>
411 
412 PyObject* PyROOT::TUIntConverter::FromMemory( void* address )
413 {
414  return PyLong_FromUnsignedLong( *((UInt_t*)address) );
415 }
416 
417 Bool_t PyROOT::TUIntConverter::ToMemory( PyObject* value, void* address )
418 {
419 // convert <value> to C++ unsigned int, write it at <address>
420  ULong_t u = PyLongOrInt_AsULong( value );
421  if ( PyErr_Occurred() )
422  return kFALSE;
423 
424  if ( u > (ULong_t)UINT_MAX ) {
425  PyErr_SetString( PyExc_OverflowError, "value too large for unsigned int" );
426  return kFALSE;
427  }
428 
429  *((UInt_t*)address) = (UInt_t)u;
430  return kTRUE;
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// floating point converters
435 
436 PYROOT_IMPLEMENT_BASIC_CONVERTER( Float, Float_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble, 'f' )
437 PYROOT_IMPLEMENT_BASIC_CONVERTER( Double, Double_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble, 'd' )
438 
439 PYROOT_IMPLEMENT_BASIC_CONVERTER( LongDouble, LongDouble_t, LongDouble_t, PyFloat_FromDouble, PyFloat_AsDouble, 'D' )
440 
441 ////////////////////////////////////////////////////////////////////////////////
442 /// convert <pyobject> to C++ double&, set arg for call
443 
444 Bool_t PyROOT::TDoubleRefConverter::SetArg(
445  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
446 {
447  if ( TCustomFloat_CheckExact( pyobject ) ) {
448  para.fValue.fVoidp = (void*)&((PyFloatObject*)pyobject)->ob_fval;
449  para.fTypeCode = 'V';
450  return kTRUE;
451  }
452 
453 // alternate, pass pointer from buffer
454  int buflen = Utility::GetBuffer( pyobject, 'd', sizeof(double), para.fValue.fVoidp );
455  if ( para.fValue.fVoidp && buflen ) {
456  para.fTypeCode = 'V';
457  return kTRUE;
458  }
459 
460  PyErr_SetString( PyExc_TypeError, "use ROOT.Double for pass-by-ref of doubles" );
461  return kFALSE;
462 }
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 
468 PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER( LongDouble, LongDouble_t, PyFloat_AsDouble )
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// can't happen (unless a type is mapped wrongly), but implemented for completeness
472 
474 {
475  PyErr_SetString( PyExc_SystemError, "void/unknown arguments can\'t be set" );
476  return kFALSE;
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// convert <pyobject> to C++ long long, set arg for call
481 
482 Bool_t PyROOT::TLongLongConverter::SetArg(
483  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
484 {
485  if ( PyFloat_Check( pyobject ) ) {
486  // special case: float implements nb_int, but allowing rounding conversions
487  // interferes with overloading
488  PyErr_SetString( PyExc_ValueError, "can not convert float to long long" );
489  return kFALSE;
490  }
491 
492  para.fValue.fLongLong = PyLong_AsLongLong( pyobject );
493  if ( PyErr_Occurred() )
494  return kFALSE;
495  para.fTypeCode = 'k';
496  return kTRUE;
497 }
498 
499 PyObject* PyROOT::TLongLongConverter::FromMemory( void* address )
500 {
501 // construct python object from C++ long long read at <address>
502  return PyLong_FromLongLong( *(Long64_t*)address );
503 }
504 
505 Bool_t PyROOT::TLongLongConverter::ToMemory( PyObject* value, void* address )
506 {
507 // convert <value> to C++ long long, write it at <address>
508  Long64_t ll = PyLong_AsLongLong( value );
509  if ( ll == -1 && PyErr_Occurred() )
510  return kFALSE;
511  *((Long64_t*)address) = ll;
512  return kTRUE;
513 }
514 
515 ////////////////////////////////////////////////////////////////////////////////
516 /// convert <pyobject> to C++ unsigned long long, set arg for call
517 
518 Bool_t PyROOT::TULongLongConverter::SetArg(
519  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
520 {
521  para.fValue.fULongLong = PyLongOrInt_AsULong64( pyobject );
522  if ( PyErr_Occurred() )
523  return kFALSE;
524  para.fTypeCode = 'K';
525  return kTRUE;
526 }
527 
528 PyObject* PyROOT::TULongLongConverter::FromMemory( void* address )
529 {
530 // construct python object from C++ unsigned long long read at <address>
531  return PyLong_FromUnsignedLongLong( *(ULong64_t*)address );
532 }
533 
534 Bool_t PyROOT::TULongLongConverter::ToMemory( PyObject* value, void* address )
535 {
536 // convert <value> to C++ unsigned long long, write it at <address>
537  Long64_t ull = PyLongOrInt_AsULong64( value );
538  if ( PyErr_Occurred() )
539  return kFALSE;
540  *((ULong64_t*)address) = ull;
541  return kTRUE;
542 }
543 
544 ////////////////////////////////////////////////////////////////////////////////
545 /// construct a new string and copy it in new memory
546 
548  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
549 {
550  const char* s = PyROOT_PyUnicode_AsStringChecked( pyobject );
551  if ( PyErr_Occurred() )
552  return kFALSE;
553 
554  fBuffer = std::string( s, PyROOT_PyUnicode_GET_SIZE( pyobject ) );
555 
556 // verify (too long string will cause truncation, no crash)
557  if ( fMaxSize < (UInt_t)fBuffer.size() )
558  PyErr_Warn( PyExc_RuntimeWarning, (char*)"string too long for char array (truncated)" );
559  else if ( fMaxSize != UINT_MAX )
560  fBuffer.resize( fMaxSize, '\0' ); // padd remainder of buffer as needed
561 
562 // set the value and declare success
563  para.fValue.fVoidp = (void*)fBuffer.c_str();
564  para.fTypeCode = 'p';
565  return kTRUE;
566 }
567 
569 {
570 // construct python object from C++ const char* read at <address>
571  if ( address && *(char**)address ) {
572  if ( fMaxSize != UINT_MAX ) { // need to prevent reading beyond boundary
573  std::string buf( *(char**)address, fMaxSize ); // cut on fMaxSize
574  return PyROOT_PyUnicode_FromString( buf.c_str() ); // cut on \0
575  }
576 
577  return PyROOT_PyUnicode_FromString( *(char**)address );
578  }
579 
580 // empty string in case there's no address
581  Py_INCREF( PyStrings::gEmptyString );
583 }
584 
586 {
587 // convert <value> to C++ const char*, write it at <address>
588  const char* s = PyROOT_PyUnicode_AsStringChecked( value );
589  if ( PyErr_Occurred() )
590  return kFALSE;
591 
592 // verify (too long string will cause truncation, no crash)
593  if ( fMaxSize < (UInt_t)PyROOT_PyUnicode_GET_SIZE( value ) )
594  PyErr_Warn( PyExc_RuntimeWarning, (char*)"string too long for char array (truncated)" );
595 
596  if ( fMaxSize != UINT_MAX )
597  strncpy( *(char**)address, s, fMaxSize ); // padds remainder
598  else
599  // coverity[secure_coding] - can't help it, it's intentional.
600  strcpy( *(char**)address, s );
601 
602  return kTRUE;
603 }
604 
605 
606 //- pointer/array conversions -------------------------------------------------
607 namespace {
608 
609  using namespace PyROOT;
610 
611  inline Bool_t CArraySetArg(
612  PyObject* pyobject, TParameter& para, char tc, int size )
613  {
614  // general case of loading a C array pointer (void* + type code) as function argument
615  if ( pyobject == gNullPtrObject ) {
616  para.fValue.fVoidp = NULL;
617  } else {
618  int buflen = Utility::GetBuffer( pyobject, tc, size, para.fValue.fVoidp );
619  if ( ! para.fValue.fVoidp || buflen == 0 )
620  return kFALSE;
621  }
622  para.fTypeCode = 'p';
623  return kTRUE;
624  }
625 
626 } // unnamed namespace
627 
628 
629 ////////////////////////////////////////////////////////////////////////////////
630 /// attempt base class first (i.e. passing a string), but if that fails, try a buffer
631 
633  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
634 {
635  if ( this->TCStringConverter::SetArg( pyobject, para, ctxt ) )
636  return kTRUE;
637 
638 // apparently failed, try char buffer
639  PyErr_Clear();
640  return CArraySetArg( pyobject, para, 'c', sizeof(char) );
641 }
642 
643 ////////////////////////////////////////////////////////////////////////////////
644 /// assume this is a buffer access if the size is known; otherwise assume string
645 
647 {
648  if ( fMaxSize != UINT_MAX )
649  return PyROOT_PyUnicode_FromStringAndSize( *(char**)address, fMaxSize );
650  return this->TCStringConverter::FromMemory( address );
651 }
652 
653 ////////////////////////////////////////////////////////////////////////////////
654 /// attempt base class first (i.e. passing a string), but if that fails, try a buffer
655 
657  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
658 {
659  if ( this->TCStringConverter::SetArg( pyobject, para, ctxt ) )
660  return kTRUE;
661 
662 // apparently failed, try char buffer
663  PyErr_Clear();
664  return CArraySetArg( pyobject, para, 'B', sizeof(unsigned char) );
665 }
666 
667 ////////////////////////////////////////////////////////////////////////////////
668 /// (1): "null pointer" or C++11 style nullptr
669 
671 {
672  if ( pyobject == Py_None || pyobject == gNullPtrObject ) {
673  address = (void*)0;
674  return kTRUE;
675  }
676 
677 // (2): allow integer zero to act as a null pointer, no deriveds
678  if ( PyInt_CheckExact( pyobject ) || PyLong_CheckExact( pyobject ) ) {
679  Long_t val = (Long_t)PyLong_AsLong( pyobject );
680  if ( val == 0l ) {
681  address = (void*)val;
682  return kTRUE;
683  }
684 
685  return kFALSE;
686  }
687 
688 // (3): opaque PyCapsule (CObject in older pythons) from somewhere
689  if ( PyROOT_PyCapsule_CheckExact( pyobject ) ) {
690  address = (void*)PyROOT_PyCapsule_GetPointer( pyobject, NULL );
691  return kTRUE;
692  }
693 
694  return kFALSE;
695 }
696 
697 ////////////////////////////////////////////////////////////////////////////////
698 /// just convert pointer if it is a ROOT object
699 
701  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
702 {
703  if ( ObjectProxy_Check( pyobject ) ) {
704  // depending on memory policy, some objects are no longer owned when passed to C++
705  if ( ! fKeepControl && ! UseStrictOwnership( ctxt ) )
706  ((ObjectProxy*)pyobject)->Release();
707 
708  // set pointer (may be null) and declare success
709  para.fValue.fVoidp = ((ObjectProxy*)pyobject)->GetObject();
710  para.fTypeCode = 'p';
711  return kTRUE;
712  }
713 
714 // handle special cases
715  if ( GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
716  para.fTypeCode = 'p';
717  return kTRUE;
718  }
719 
720 // final try: attempt to get buffer
721  int buflen = Utility::GetBuffer( pyobject, '*', 1, para.fValue.fVoidp, kFALSE );
722 
723 // ok if buffer exists (can't perform any useful size checks)
724  if ( para.fValue.fVoidp && buflen != 0 ) {
725  para.fTypeCode = 'p';
726  return kTRUE;
727  }
728 
729 // give up
730  return kFALSE;
731 }
732 
733 ////////////////////////////////////////////////////////////////////////////////
734 /// nothing sensible can be done, just return <address> as pylong
735 
737 {
738  if ( ! address || *(ptrdiff_t*)address == 0 ) {
739  Py_INCREF( gNullPtrObject );
740  return gNullPtrObject;
741  }
742  return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)*(ptrdiff_t**)address, sizeof(void*) );
743 }
744 
745 ////////////////////////////////////////////////////////////////////////////////
746 /// just convert pointer if it is a ROOT object
747 
749 {
750  if ( ObjectProxy_Check( value ) ) {
751  // depending on memory policy, some objects are no longer owned when passed to C++
752  if ( ! fKeepControl && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
753  ((ObjectProxy*)value)->Release();
754 
755  // set pointer (may be null) and declare success
756  *(void**)address = ((ObjectProxy*)value)->GetObject();
757  return kTRUE;
758  }
759 
760 // handle special cases
761  void* ptr = 0;
762  if ( GetAddressSpecialCase( value, ptr ) ) {
763  *(void**)address = ptr;
764  return kTRUE;
765  }
766 
767 // final try: attempt to get buffer
768  void* buf = 0;
769  int buflen = Utility::GetBuffer( value, '*', 1, buf, kFALSE );
770  if ( ! buf || buflen == 0 )
771  return kFALSE;
772 
773  *(void**)address = buf;
774  return kTRUE;
775 }
776 
777 ////////////////////////////////////////////////////////////////////////////////
778 
779 #define PYROOT_IMPLEMENT_ARRAY_CONVERTER( name, type, code ) \
780 Bool_t PyROOT::T##name##ArrayConverter::SetArg( \
781  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ ) \
782 { \
783  return CArraySetArg( pyobject, para, code, sizeof(type) ); \
784 } \
785  \
786 Bool_t PyROOT::T##name##ArrayRefConverter::SetArg( \
787  PyObject* pyobject, TParameter& para, TCallContext* ctxt ) \
788 { \
789  Bool_t result = T##name##ArrayConverter::SetArg( pyobject, para, ctxt ); \
790  para.fTypeCode = 'V'; \
791  return result; \
792 } \
793  \
794 PyObject* PyROOT::T##name##ArrayConverter::FromMemory( void* address ) \
795 { \
796  return BufFac_t::Instance()->PyBuffer_FromMemory( *(type**)address, fSize * sizeof(type) );\
797 } \
798  \
799 Bool_t PyROOT::T##name##ArrayConverter::ToMemory( PyObject* value, void* address )\
800 { \
801  void* buf = 0; \
802  int buflen = Utility::GetBuffer( value, code, sizeof(type), buf ); \
803  if ( ! buf || buflen == 0 ) \
804  return kFALSE; \
805  if ( 0 <= fSize ) { \
806  if ( fSize < buflen/(int)sizeof(type) ) { \
807  PyErr_SetString( PyExc_ValueError, "buffer too large for value" ); \
808  return kFALSE; \
809  } \
810  memcpy( *(type**)address, buf, 0 < buflen ? ((size_t) buflen) : sizeof(type) );\
811  } else \
812  *(type**)address = (type*)buf; \
813  return kTRUE; \
814 }
815 
816 ////////////////////////////////////////////////////////////////////////////////
817 
827 
828 ////////////////////////////////////////////////////////////////////////////////
829 /// convert <pyobject> to C++ long long*, set arg for call
830 
832  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
833 {
834  PyObject* pytc = PyObject_GetAttr( pyobject, PyStrings::gTypeCode );
835  if ( pytc != 0 ) { // iow, this array has a known type, but there's no
836  Py_DECREF( pytc ); // such thing for long long in module array
837  return kFALSE;
838  }
839 
840  return TVoidArrayConverter::SetArg( pyobject, para, ctxt );
841 }
842 
843 
844 //- converters for special cases ----------------------------------------------
845 #define PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( name, type, F1, F2 ) \
846 PyROOT::T##name##Converter::T##name##Converter( Bool_t keepControl ) : \
847  TCppObjectConverter( Cppyy::GetScope( #type ), keepControl ) {} \
848  \
849 Bool_t PyROOT::T##name##Converter::SetArg( \
850  PyObject* pyobject, TParameter& para, TCallContext* ctxt ) \
851 { \
852  if ( PyROOT_PyUnicode_Check( pyobject ) ) { \
853  fBuffer = type( PyROOT_PyUnicode_AsString( pyobject ), \
854  PyROOT_PyUnicode_GET_SIZE( pyobject ) ); \
855  para.fValue.fVoidp = &fBuffer; \
856  para.fTypeCode = 'V'; \
857  return kTRUE; \
858  } \
859  \
860  if ( ! ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) ) { \
861  Bool_t result = TCppObjectConverter::SetArg( pyobject, para, ctxt ); \
862  para.fTypeCode = 'V'; \
863  return result; \
864  } \
865  return kFALSE; \
866 } \
867  \
868 PyObject* PyROOT::T##name##Converter::FromMemory( void* address ) \
869 { \
870  if ( address ) \
871  return PyROOT_PyUnicode_FromStringAndSize( ((type*)address)->F1(), ((type*)address)->F2() );\
872  Py_INCREF( PyStrings::gEmptyString ); \
873  return PyStrings::gEmptyString; \
874 } \
875  \
876 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
877 { \
878  if ( PyROOT_PyUnicode_Check( value ) ) { \
879  *((type*)address) = PyROOT_PyUnicode_AsString( value ); \
880  return kTRUE; \
881  } \
882  \
883  return TCppObjectConverter::ToMemory( value, address ); \
884 }
885 
886 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( TString, TString, Data, Length )
887 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLString, std::string, c_str, size )
888 
889 ////////////////////////////////////////////////////////////////////////////////
890 /// convert <pyobject> to C++ instance*, set arg for call
891 
893  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
894 {
895  if ( ! ObjectProxy_Check( pyobject ) ) {
896  if ( GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
897  para.fTypeCode = 'p'; // allow special cases such as NULL
898  return kTRUE;
899  }
900 
901  // not a PyROOT object (TODO: handle SWIG etc.)
902  return kFALSE;
903  }
904 
905  ObjectProxy* pyobj = (ObjectProxy*)pyobject;
906  if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
907  // depending on memory policy, some objects need releasing when passed into functions
908  if ( ! KeepControl() && ! UseStrictOwnership( ctxt ) )
909  ((ObjectProxy*)pyobject)->Release();
910 
911  // calculate offset between formal and actual arguments
912  para.fValue.fVoidp = pyobj->GetObject();
913  if ( pyobj->ObjectIsA() != fClass ) {
914  para.fValue.fLong += Cppyy::GetBaseOffset(
915  pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 /* up-cast */ );
916  }
917 
918  // set pointer (may be null) and declare success
919  para.fTypeCode = 'p';
920  return kTRUE;
921 
922  } else if ( ! TClass::GetClass( Cppyy::GetFinalName( fClass ).c_str() )->GetClassInfo() ) {
923  // assume "user knows best" to allow anonymous pointer passing
924  para.fValue.fVoidp = pyobj->GetObject();
925  para.fTypeCode = 'p';
926  return kTRUE;
927  }
928 
929  return kFALSE;
930 }
931 
932 ////////////////////////////////////////////////////////////////////////////////
933 /// construct python object from C++ instance read at <address>
934 
936 {
937  return BindCppObject( address, fClass, kFALSE );
938 }
939 
940 ////////////////////////////////////////////////////////////////////////////////
941 /// convert <value> to C++ instance, write it at <address>
942 
944 {
945  if ( ! ObjectProxy_Check( value ) ) {
946  void* ptr = 0;
947  if ( GetAddressSpecialCase( value, ptr ) ) {
948  *(void**)address = ptr; // allow special cases such as NULL
949  return kTRUE;
950  }
951 
952  // not a PyROOT object (TODO: handle SWIG etc.)
953  return kFALSE;
954  }
955 
956  if ( Cppyy::IsSubtype( ((ObjectProxy*)value)->ObjectIsA(), fClass ) ) {
957  // depending on memory policy, some objects need releasing when passed into functions
958  if ( ! KeepControl() && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
959  ((ObjectProxy*)value)->Release();
960 
961  // call assignment operator through a temporarily wrapped object proxy
962  PyObject* pyobj = BindCppObjectNoCast( address, fClass );
963  ((ObjectProxy*)pyobj)->Release(); // TODO: might be recycled (?)
964  PyObject* result = PyObject_CallMethod( pyobj, (char*)"__assign__", (char*)"O", value );
965  Py_DECREF( pyobj );
966  if ( result ) {
967  Py_DECREF( result );
968  return kTRUE;
969  }
970  }
971 
972  return kFALSE;
973 }
974 
975 // TODO: CONSOLIDATE ValueCpp, RefCpp, and CppObject ...
976 
977 ////////////////////////////////////////////////////////////////////////////////
978 /// convert <pyobject> to C++ instance, set arg for call
979 
981  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
982 {
983  if ( ! ObjectProxy_Check( pyobject ) )
984  return kFALSE;
985 
986  ObjectProxy* pyobj = (ObjectProxy*)pyobject;
987  if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
988  // calculate offset between formal and actual arguments
989  para.fValue.fVoidp = pyobj->GetObject();
990  if ( ! para.fValue.fVoidp )
991  return kFALSE;
992 
993  if ( pyobj->ObjectIsA() != fClass ) {
995  pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 /* up-cast */ );
996  }
997 
998  para.fTypeCode = 'V';
999  return kTRUE;
1000  }
1001 
1002  return kFALSE;
1003 }
1004 
1005 ////////////////////////////////////////////////////////////////////////////////
1006 /// convert <pyobject> to C++ instance&, set arg for call
1007 
1009  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
1010 {
1011  if ( ! ObjectProxy_Check( pyobject ) )
1012  return kFALSE;
1013 
1014  ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1015  if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
1016  // calculate offset between formal and actual arguments
1017  para.fValue.fVoidp = pyobj->GetObject();
1018  if ( pyobj->ObjectIsA() != fClass ) {
1020  pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 /* up-cast */ );
1021  }
1022 
1023  para.fTypeCode = 'V';
1024  return kTRUE;
1025  } else if ( ! TClass::GetClass( Cppyy::GetFinalName( fClass ).c_str() )->GetClassInfo() ) {
1026  // assume "user knows best" to allow anonymous reference passing
1027  para.fValue.fVoidp = pyobj->GetObject();
1028  para.fTypeCode = 'V';
1029  return kTRUE;
1030  }
1031 
1032  return kFALSE;
1033 }
1034 
1035 ////////////////////////////////////////////////////////////////////////////////
1036 /// convert <pyobject> to C++ instance**, set arg for call
1037 
1038 template <bool ISREFERENCE>
1040  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
1041 {
1042  if ( ! ObjectProxy_Check( pyobject ) )
1043  return kFALSE; // not a PyROOT object (TODO: handle SWIG etc.)
1044 
1045  if ( Cppyy::IsSubtype( ((ObjectProxy*)pyobject)->ObjectIsA(), fClass ) ) {
1046  // depending on memory policy, some objects need releasing when passed into functions
1047  if ( ! KeepControl() && ! UseStrictOwnership( ctxt ) )
1048  ((ObjectProxy*)pyobject)->Release();
1049 
1050  // set pointer (may be null) and declare success
1051  if( ((ObjectProxy*)pyobject)->fFlags & ObjectProxy::kIsReference)
1052  // If given object is already a reference (aka pointer) then we should not take the address of it
1053  para.fValue.fVoidp = ((ObjectProxy*)pyobject)->fObject;
1054  else
1055  para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1056  para.fTypeCode = ISREFERENCE ? 'V' : 'p';
1057  return kTRUE;
1058  }
1059 
1060  return kFALSE;
1061 }
1062 
1063 ////////////////////////////////////////////////////////////////////////////////
1064 /// construct python object from C++ instance* read at <address>
1065 
1066 template <bool ISREFERENCE>
1068 {
1069  return BindCppObject( address, fClass, kTRUE );
1070 }
1071 
1072 ////////////////////////////////////////////////////////////////////////////////
1073 /// convert <value> to C++ instance*, write it at <address>
1074 
1075 template <bool ISREFERENCE>
1077 {
1078  if ( ! ObjectProxy_Check( value ) )
1079  return kFALSE; // not a PyROOT object (TODO: handle SWIG etc.)
1080 
1081  if ( Cppyy::IsSubtype( ((ObjectProxy*)value)->ObjectIsA(), fClass ) ) {
1082  // depending on memory policy, some objects need releasing when passed into functions
1083  if ( ! KeepControl() && TCallContext::sMemoryPolicy != TCallContext::kUseStrict )
1084  ((ObjectProxy*)value)->Release();
1085 
1086  // set pointer (may be null) and declare success
1087  *(void**)address = ((ObjectProxy*)value)->GetObject();
1088  return kTRUE;
1089  }
1090 
1091  return kFALSE;
1092 }
1093 
1094 
1095 namespace PyROOT {
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// Instantiate the templates
1098 
1099 template class TCppObjectPtrConverter<true>;
1100 template class TCppObjectPtrConverter<false>;
1101 }
1102 
1103 ////////////////////////////////////////////////////////////////////////////////
1104 /// convert <pyobject> to C++ instance**, set arg for call
1105 
1107  PyObject* pyobject, TParameter& para, TCallContext* /* txt */ )
1108 {
1109  if ( ! TTupleOfInstances_CheckExact( pyobject ) )
1110  return kFALSE; // no guarantee that the tuple is okay
1111 
1112 // treat the first instance of the tuple as the start of the array, and pass it
1113 // by pointer (TODO: store and check sizes)
1114  if ( PyTuple_Size( pyobject ) < 1 )
1115  return kFALSE;
1116 
1117  PyObject* first = PyTuple_GetItem( pyobject, 0 );
1118  if ( ! ObjectProxy_Check( first ) )
1119  return kFALSE; // should not happen
1120 
1121  if ( Cppyy::IsSubtype( ((ObjectProxy*)first)->ObjectIsA(), fClass ) ) {
1122  // no memory policies supported; set pointer (may be null) and declare success
1123  para.fValue.fVoidp = ((ObjectProxy*)first)->fObject;
1124  para.fTypeCode = 'p';
1125  return kTRUE;
1126  }
1127 
1128  return kFALSE;
1129 }
1130 
1131 ////////////////////////////////////////////////////////////////////////////////
1132 /// construct python tuple of instances from C++ array read at <address>
1133 
1135 {
1136  if ( m_size <= 0 ) // if size unknown, just hand out the first object
1137  return BindCppObjectNoCast( address, fClass );
1138 
1139  return BindCppObjectArray( address, fClass, m_size );
1140 }
1141 
1142 ////////////////////////////////////////////////////////////////////////////////
1143 /// convert <value> to C++ array of instances, write it at <address>
1144 
1145 Bool_t PyROOT::TCppObjectArrayConverter::ToMemory( PyObject* /* value */, void* /* address */ )
1146 {
1147 // TODO: need to have size both for the array and from the input
1148  PyErr_SetString( PyExc_NotImplementedError,
1149  "access to C-arrays of objects not yet implemented!" );
1150  return kFALSE;
1151 }
1152 
1153 //____________________________________________________________________________
1154 // CLING WORKAROUND -- classes for STL iterators are completely undefined in that
1155 // they come in a bazillion different guises, so just do whatever
1157  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
1158 {
1159  if ( ! ObjectProxy_Check( pyobject ) )
1160  return kFALSE;
1161 
1162 // just set the pointer value, no check
1163  ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1164  para.fValue.fVoidp = pyobj->GetObject();
1165  para.fTypeCode = 'V';
1166  return kTRUE;
1167 }
1168 // -- END CLING WORKAROUND
1169 
1170 ////////////////////////////////////////////////////////////////////////////////
1171 /// convert <pyobject> to C++ void*&, set arg for call
1172 
1174  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
1175 {
1176  if ( ObjectProxy_Check( pyobject ) ) {
1177  para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1178  para.fTypeCode = 'V';
1179  return kTRUE;
1180  }
1181 
1182  return kFALSE;
1183 }
1184 
1185 ////////////////////////////////////////////////////////////////////////////////
1186 /// convert <pyobject> to C++ void**, set arg for call
1187 
1189  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
1190 {
1191  if ( ObjectProxy_Check( pyobject ) ) {
1192  // this is a ROOT object, take and set its address
1193  para.fValue.fVoidp = &((ObjectProxy*)pyobject)->fObject;
1194  para.fTypeCode = 'p';
1195  return kTRUE;
1196  }
1197 
1198 // buffer objects are allowed under "user knows best"
1199  int buflen = Utility::GetBuffer( pyobject, '*', 1, para.fValue.fVoidp, kFALSE );
1200 
1201 // ok if buffer exists (can't perform any useful size checks)
1202  if ( para.fValue.fVoidp && buflen != 0 ) {
1203  para.fTypeCode = 'p';
1204  return kTRUE;
1205  }
1206 
1207  return kFALSE;
1208 }
1209 
1210 ////////////////////////////////////////////////////////////////////////////////
1211 /// read a void** from address; since this is unknown, long is used (user can cast)
1212 
1214 {
1215  if ( ! address || *(ptrdiff_t*)address == 0 ) {
1216  Py_INCREF( gNullPtrObject );
1217  return gNullPtrObject;
1218  }
1219  return BufFac_t::Instance()->PyBuffer_FromMemory( (Long_t*)*(ptrdiff_t**)address, sizeof(void*) );
1220 }
1221 
1222 ////////////////////////////////////////////////////////////////////////////////
1223 /// by definition: set and declare success
1224 
1225 Bool_t PyROOT::TPyObjectConverter::SetArg(
1226  PyObject* pyobject, TParameter& para, TCallContext* /* ctxt */ )
1227 {
1228  para.fValue.fVoidp = pyobject;
1229  para.fTypeCode = 'p';
1230  return kTRUE;
1231 }
1232 
1233 PyObject* PyROOT::TPyObjectConverter::FromMemory( void* address )
1234 {
1235 // construct python object from C++ PyObject* read at <address>
1236  PyObject* pyobject = *((PyObject**)address);
1237 
1238  if ( ! pyobject ) {
1239  Py_INCREF( Py_None );
1240  return Py_None;
1241  }
1242 
1243  Py_INCREF( pyobject );
1244  return pyobject;
1245 }
1246 
1247 Bool_t PyROOT::TPyObjectConverter::ToMemory( PyObject* value, void* address )
1248 {
1249 // no conversion needed, write <value> at <address>
1250  Py_INCREF( value );
1251  *((PyObject**)address) = value;
1252  return kTRUE;
1253 }
1254 
1255 
1256 ////////////////////////////////////////////////////////////////////////////////
1257 /// smart pointer converter
1258 
1260  PyObject* pyobject, TParameter& para, TCallContext* ctxt )
1261 {
1262  char typeCode = fHandlePtr ? 'p' : 'V';
1263 
1264  if ( ! ObjectProxy_Check( pyobject ) ) {
1265  if ( fHandlePtr && GetAddressSpecialCase( pyobject, para.fValue.fVoidp ) ) {
1266  para.fTypeCode = typeCode; // allow special cases such as NULL
1267  return kTRUE;
1268  }
1269 
1270  return kFALSE;
1271  }
1272 
1273  ObjectProxy* pyobj = (ObjectProxy*)pyobject;
1274 
1275 // for the case where we have a 'hidden' smart pointer:
1276  if ( pyobj->fFlags & ObjectProxy::kIsSmartPtr && Cppyy::IsSubtype( pyobj->fSmartPtrType, fClass ) ) {
1277  // depending on memory policy, some objects need releasing when passed into functions
1278  if ( fKeepControl && ! UseStrictOwnership( ctxt ) )
1279  ((ObjectProxy*)pyobject)->Release();
1280 
1281  // calculate offset between formal and actual arguments
1282  para.fValue.fVoidp = pyobj->fSmartPtr;
1283  if ( pyobj->fSmartPtrType != fClass ) {
1285  pyobj->fSmartPtrType, fClass, para.fValue.fVoidp, 1 /* up-cast */ );
1286  }
1287 
1288  // set pointer (may be null) and declare success
1289  para.fTypeCode = typeCode;
1290  return kTRUE;
1291  }
1292 
1293 // for the case where we have an 'exposed' smart pointer:
1294  if ( pyobj->ObjectIsA() && Cppyy::IsSubtype( pyobj->ObjectIsA(), fClass ) ) {
1295  // calculate offset between formal and actual arguments
1296  para.fValue.fVoidp = pyobj->GetObject();
1297  if ( pyobj->ObjectIsA() != fClass ) {
1299  pyobj->ObjectIsA(), fClass, para.fValue.fVoidp, 1 /* up-cast */ );
1300  }
1301 
1302  // set pointer (may be null) and declare success
1303  para.fTypeCode = typeCode;
1304  return kTRUE;
1305  }
1306 
1307  return kFALSE;
1308 }
1309 
1311 {
1312  if ( !address || !fClass )
1313  return nullptr;
1314 
1315 // obtain raw pointer
1316  std::vector<TParameter> args;
1318  Cppyy::CallR( (Cppyy::TCppMethod_t)fDereferencer, address, &args ), fRawPtrType );
1319  if ( pyobj )
1320  pyobj->SetSmartPtr( (void*)address, fClass );
1321 
1322  return (PyObject*)pyobj;
1323 }
1324 
1325 
1326 ////////////////////////////////////////////////////////////////////////////////
1327 /// raise a NotImplemented exception to take a method out of overload resolution
1328 
1330 {
1331  PyErr_SetString( PyExc_NotImplementedError, "this method can not (yet) be called" );
1332  return kFALSE;
1333 }
1334 
1335 
1336 //- factories -----------------------------------------------------------------
1337 PyROOT::TConverter* PyROOT::CreateConverter( const std::string& fullType, Long_t size )
1338 {
1339 // The matching of the fulltype to a converter factory goes through up to five levels:
1340 // 1) full, exact match
1341 // 2) match of decorated, unqualified type
1342 // 3) accept const ref as by value
1343 // 4) accept ref as pointer
1344 // 5) generalized cases (covers basically all ROOT classes)
1345 //
1346 // If all fails, void is used, which will generate a run-time warning when used.
1347 
1348 // an exactly matching converter is best
1349  ConvFactories_t::iterator h = gConvFactories.find( fullType );
1350  if ( h != gConvFactories.end() )
1351  return (h->second)( size );
1352 
1353 // resolve typedefs etc.
1354  std::string resolvedType = Cppyy::ResolveName( fullType );
1355 
1356 // a full, qualified matching converter is preferred
1357  h = gConvFactories.find( resolvedType );
1358  if ( h != gConvFactories.end() )
1359  return (h->second)( size );
1360 
1361 //-- nothing? ok, collect information about the type and possible qualifiers/decorators
1362  const std::string& cpd = Utility::Compound( resolvedType );
1363  std::string realType = TClassEdit::ShortType( resolvedType.c_str(), 1 );
1364 
1365 // accept unqualified type (as python does not know about qualifiers)
1366  h = gConvFactories.find( realType + cpd );
1367  if ( h != gConvFactories.end() )
1368  return (h->second)( size );
1369 
1370 // CLING WORKAROUND -- if the type is a fixed-size array, it will have a funky
1371 // resolved type like MyClass(&)[N], which TClass::GetClass() fails on. So, strip
1372 // it down:
1373  if ( cpd == "[]" )
1374  realType = TClassEdit::CleanType( realType.substr( 0, realType.rfind("(") ).c_str(), 1 );
1375 // -- CLING WORKAROUND
1376 
1377 //-- still nothing? try pointer instead of array (for builtins)
1378  if ( cpd == "[]" ) {
1379  h = gConvFactories.find( realType + "*" );
1380  if ( h != gConvFactories.end() )
1381  return (h->second)( size );
1382  }
1383 
1384 //-- still nothing? use a generalized converter
1385  Bool_t isConst = resolvedType.substr(0, 5) == "const";
1386  Bool_t control = cpd == "&" || isConst;
1387 
1388 // converters for known/ROOT classes and default (void*)
1389  TConverter* result = 0;
1390  if ( Cppyy::TCppScope_t klass = Cppyy::GetScope( realType ) ) {
1391  if ( Cppyy::IsSmartPtr( realType ) ) {
1392  const std::vector< Cppyy::TCppMethod_t > methods = Cppyy::GetMethodsFromName( klass, "operator->" );
1393  if ( ! methods.empty() ) {
1394  Cppyy::TCppType_t rawPtrType = Cppyy::GetScope(
1395  TClassEdit::ShortType( Cppyy::GetMethodResultType( methods[0] ).c_str(), 1 ) );
1396  if ( rawPtrType ) {
1397  if ( cpd == "" ) {
1398  result = new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0], control );
1399  } else if ( cpd == "&" ) {
1400  result = new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0] );
1401  } else if ( cpd == "*" && size <= 0 ) {
1402  result = new TSmartPtrCppObjectConverter( klass, rawPtrType, methods[0], control, kTRUE );
1403  } /* else if ( cpd == "**" || cpd == "*&" || cpd == "&*" ) {
1404  } else if ( cpd == "[]" || size > 0 ) {
1405  } else {
1406  } */
1407  }
1408  }
1409  }
1410 
1411  if ( ! result ) {
1412  // CLING WORKAROUND -- special case for STL iterators
1413  if ( realType.find( "__gnu_cxx::__normal_iterator", 0 ) /* vector */ == 0 )
1414  result = new TSTLIteratorConverter();
1415  else
1416  // -- CLING WORKAROUND
1417  if ( cpd == "**" || cpd == "&*" )
1418  result = new TCppObjectPtrConverter<false>( klass, control);
1419  else if ( cpd == "*&" )
1420  result = new TCppObjectPtrConverter<true>( klass, control);
1421  else if ( cpd == "*" && size <= 0 )
1422  result = new TCppObjectConverter( klass, control );
1423  else if ( cpd == "&" )
1424  result = new TRefCppObjectConverter( klass );
1425  else if ( cpd == "[]" || size > 0 )
1426  result = new TCppObjectArrayConverter( klass, size, kFALSE );
1427  else if ( cpd == "" ) // by value
1428  result = new TValueCppObjectConverter( klass, kTRUE );
1429  }
1430  } else if ( Cppyy::IsEnum( realType ) ) {
1431  // special case (Cling): represent enums as unsigned integers
1432  if ( cpd == "&" )
1433  h = isConst ? gConvFactories.find( "const long&" ) : gConvFactories.find( "long&" );
1434  else
1435  h = gConvFactories.find( "UInt_t" );
1436  } else if ( realType.find( "(*)" ) != std::string::npos ||
1437  ( realType.find( "::*)" ) != std::string::npos ) ) {
1438  // this is a function function pointer
1439  // TODO: find better way of finding the type
1440  // TODO: a converter that generates wrappers as appropriate
1441  h = gConvFactories.find( "void*" );
1442  }
1443 
1444  if ( ! result && cpd == "&&" ) // moves
1445  result = new TNotImplementedConverter();
1446 
1447  if ( ! result && h != gConvFactories.end() )
1448  // converter factory available, use it to create converter
1449  result = (h->second)( size );
1450  else if ( ! result ) {
1451  if ( cpd != "" ) {
1452  std::stringstream s;
1453  s << "creating converter for unknown type \"" << fullType << "\"" << std::ends;
1454  PyErr_Warn( PyExc_RuntimeWarning, (char*)s.str().c_str() );
1455  result = new TVoidArrayConverter(); // "user knows best"
1456  } else
1457  result = new TVoidConverter(); // fails on use
1458  }
1459 
1460  return result;
1461 }
1462 
1463 ////////////////////////////////////////////////////////////////////////////////
1464 
1465 #define PYROOT_BASIC_CONVERTER_FACTORY( name ) \
1466 TConverter* Create##name##Converter( Long_t ) \
1467 { \
1468  return new T##name##Converter(); \
1469 }
1470 
1471 #define PYROOT_ARRAY_CONVERTER_FACTORY( name ) \
1472 TConverter* Create##name##Converter( Long_t size ) \
1473 { \
1474  return new T##name##Converter( size ); \
1475 }
1476 
1477 ////////////////////////////////////////////////////////////////////////////////
1478 
1479 namespace {
1480  using namespace PyROOT;
1481 
1482 // use macro rather than template for portability ...
1484  PYROOT_BASIC_CONVERTER_FACTORY( ConstBoolRef )
1486  PYROOT_BASIC_CONVERTER_FACTORY( ConstCharRef )
1488  PYROOT_BASIC_CONVERTER_FACTORY( ConstUCharRef )
1490  PYROOT_BASIC_CONVERTER_FACTORY( ConstShortRef )
1492  PYROOT_BASIC_CONVERTER_FACTORY( ConstUShortRef )
1495  PYROOT_BASIC_CONVERTER_FACTORY( ConstIntRef )
1497  PYROOT_BASIC_CONVERTER_FACTORY( ConstUIntRef )
1500  PYROOT_BASIC_CONVERTER_FACTORY( ConstLongRef )
1502  PYROOT_BASIC_CONVERTER_FACTORY( ConstULongRef )
1504  PYROOT_BASIC_CONVERTER_FACTORY( ConstFloatRef )
1506  PYROOT_BASIC_CONVERTER_FACTORY( DoubleRef )
1507  PYROOT_BASIC_CONVERTER_FACTORY( ConstDoubleRef )
1508  PYROOT_BASIC_CONVERTER_FACTORY( LongDouble )
1509  PYROOT_BASIC_CONVERTER_FACTORY( ConstLongDoubleRef )
1511  PYROOT_BASIC_CONVERTER_FACTORY( LongLong )
1512  PYROOT_BASIC_CONVERTER_FACTORY( ConstLongLongRef )
1513  PYROOT_BASIC_CONVERTER_FACTORY( ULongLong )
1514  PYROOT_BASIC_CONVERTER_FACTORY( ConstULongLongRef )
1516  PYROOT_ARRAY_CONVERTER_FACTORY( NonConstCString )
1517  PYROOT_ARRAY_CONVERTER_FACTORY( NonConstUCString )
1518  PYROOT_ARRAY_CONVERTER_FACTORY( BoolArray )
1519  PYROOT_BASIC_CONVERTER_FACTORY( BoolArrayRef )
1520  PYROOT_ARRAY_CONVERTER_FACTORY( ShortArray )
1521  PYROOT_ARRAY_CONVERTER_FACTORY( ShortArrayRef )
1522  PYROOT_ARRAY_CONVERTER_FACTORY( UShortArray )
1523  PYROOT_ARRAY_CONVERTER_FACTORY( UShortArrayRef )
1524  PYROOT_ARRAY_CONVERTER_FACTORY( IntArray )
1525  PYROOT_ARRAY_CONVERTER_FACTORY( UIntArray )
1526  PYROOT_ARRAY_CONVERTER_FACTORY( UIntArrayRef )
1527  PYROOT_ARRAY_CONVERTER_FACTORY( LongArray )
1528  PYROOT_ARRAY_CONVERTER_FACTORY( ULongArray )
1529  PYROOT_ARRAY_CONVERTER_FACTORY( ULongArrayRef )
1530  PYROOT_ARRAY_CONVERTER_FACTORY( FloatArray )
1531  PYROOT_ARRAY_CONVERTER_FACTORY( FloatArrayRef )
1532  PYROOT_ARRAY_CONVERTER_FACTORY( DoubleArray )
1533  PYROOT_BASIC_CONVERTER_FACTORY( VoidArray )
1534  PYROOT_BASIC_CONVERTER_FACTORY( LongLongArray )
1536  PYROOT_BASIC_CONVERTER_FACTORY( STLString )
1537  PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrRef )
1538  PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrPtr )
1540 
1541 // converter factories for ROOT types
1542  typedef std::pair< const char*, ConverterFactory_t > NFp_t;
1543 
1544  // clang-format off
1545  NFp_t factories_[] = {
1546  // factories for built-ins
1547  NFp_t( "bool", &CreateBoolConverter ),
1548  NFp_t( "const bool&", &CreateConstBoolRefConverter ),
1549  NFp_t( "char", &CreateCharConverter ),
1550  NFp_t( "const char&", &CreateConstCharRefConverter ),
1551  NFp_t( "signed char", &CreateCharConverter ),
1552  NFp_t( "const signed char&", &CreateConstCharRefConverter ),
1553  NFp_t( "unsigned char", &CreateUCharConverter ),
1554  NFp_t( "const unsigned char&", &CreateConstUCharRefConverter ),
1555  NFp_t( "short", &CreateShortConverter ),
1556  NFp_t( "const short&", &CreateConstShortRefConverter ),
1557  NFp_t( "unsigned short", &CreateUShortConverter ),
1558  NFp_t( "const unsigned short&", &CreateConstUShortRefConverter ),
1559  NFp_t( "int", &CreateIntConverter ),
1560  NFp_t( "int&", &CreateIntRefConverter ),
1561  NFp_t( "const int&", &CreateConstIntRefConverter ),
1562  NFp_t( "unsigned int", &CreateUIntConverter ),
1563  NFp_t( "const unsigned int&", &CreateConstUIntRefConverter ),
1564  NFp_t( "UInt_t", /* enum */ &CreateIntConverter /* yes: Int */ ),
1565  NFp_t( "long", &CreateLongConverter ),
1566  NFp_t( "long&", &CreateLongRefConverter ),
1567  NFp_t( "const long&", &CreateConstLongRefConverter ),
1568  NFp_t( "unsigned long", &CreateULongConverter ),
1569  NFp_t( "const unsigned long&", &CreateConstULongRefConverter ),
1570  NFp_t( "long long", &CreateLongLongConverter ),
1571  NFp_t( "const long long&", &CreateConstLongLongRefConverter ),
1572  NFp_t( "Long64_t", &CreateLongLongConverter ),
1573  NFp_t( "const Long64_t&", &CreateConstLongLongRefConverter ),
1574  NFp_t( "unsigned long long", &CreateULongLongConverter ),
1575  NFp_t( "const unsigned long long&", &CreateConstULongLongRefConverter ),
1576  NFp_t( "ULong64_t", &CreateULongLongConverter ),
1577  NFp_t( "const ULong64_t&", &CreateConstULongLongRefConverter ),
1578 
1579  NFp_t( "float", &CreateFloatConverter ),
1580  NFp_t( "const float&", &CreateConstFloatRefConverter ),
1581  NFp_t( "double", &CreateDoubleConverter ),
1582  NFp_t( "double&", &CreateDoubleRefConverter ),
1583  NFp_t( "const double&", &CreateConstDoubleRefConverter ),
1584  NFp_t( "long double", &CreateLongDoubleConverter ),
1585  NFp_t( "const long double&", &CreateConstLongDoubleRefConverter ),
1586  NFp_t( "void", &CreateVoidConverter ),
1587 
1588  // pointer/array factories
1589  NFp_t( "bool*", &CreateBoolArrayConverter ),
1590  NFp_t( "bool&", &CreateBoolArrayRefConverter ),
1591  NFp_t( "const unsigned char*", &CreateCStringConverter ),
1592  NFp_t( "unsigned char*", &CreateNonConstUCStringConverter ),
1593  NFp_t( "short*", &CreateShortArrayConverter ),
1594  NFp_t( "short&", &CreateShortArrayRefConverter ),
1595  NFp_t( "unsigned short*", &CreateUShortArrayConverter ),
1596  NFp_t( "unsigned short&", &CreateUShortArrayRefConverter ),
1597  NFp_t( "int*", &CreateIntArrayConverter ),
1598  NFp_t( "unsigned int*", &CreateUIntArrayConverter ),
1599  NFp_t( "unsigned int&", &CreateUIntArrayRefConverter ),
1600  NFp_t( "long*", &CreateLongArrayConverter ),
1601  NFp_t( "unsigned long*", &CreateULongArrayConverter ),
1602  NFp_t( "unsigned long&", &CreateULongArrayRefConverter ),
1603  NFp_t( "float*", &CreateFloatArrayConverter ),
1604  NFp_t( "float&", &CreateFloatArrayRefConverter ),
1605  NFp_t( "double*", &CreateDoubleArrayConverter ),
1606  NFp_t( "long long*", &CreateLongLongArrayConverter ),
1607  NFp_t( "Long64_t*", &CreateLongLongArrayConverter ),
1608  NFp_t( "unsigned long long*", &CreateLongLongArrayConverter ), // TODO: ULongLong
1609  NFp_t( "ULong64_t*", &CreateLongLongArrayConverter ), // TODO: ULongLong
1610  NFp_t( "void*", &CreateVoidArrayConverter ),
1611 
1612  // factories for special cases
1613  NFp_t( "const char*", &CreateCStringConverter ),
1614  NFp_t( "char*", &CreateNonConstCStringConverter ),
1615  NFp_t( "TString", &CreateTStringConverter ),
1616  NFp_t( "const TString&", &CreateTStringConverter ),
1617  NFp_t( "std::string", &CreateSTLStringConverter ),
1618  NFp_t( "string", &CreateSTLStringConverter ),
1619  NFp_t( "const std::string&", &CreateSTLStringConverter ),
1620  NFp_t( "const string&", &CreateSTLStringConverter ),
1621  NFp_t( "void*&", &CreateVoidPtrRefConverter ),
1622  NFp_t( "void**", &CreateVoidPtrPtrConverter ),
1623  NFp_t( "PyObject*", &CreatePyObjectConverter ),
1624  NFp_t( "_object*", &CreatePyObjectConverter ),
1625  NFp_t( "FILE*", &CreateVoidArrayConverter ),
1626  NFp_t( "Float16_t", &CreateFloatConverter ),
1627  NFp_t( "const Float16_t&", &CreateConstFloatRefConverter ),
1628  NFp_t( "Double32_t", &CreateDoubleConverter ),
1629  NFp_t( "Double32_t&", &CreateDoubleRefConverter ),
1630  NFp_t( "const Double32_t&", &CreateConstDoubleRefConverter )
1631  };
1632  // clang-format on
1633 
1634  struct InitConvFactories_t {
1635  public:
1636  InitConvFactories_t()
1637  {
1638  // load all converter factories in the global map 'gConvFactories'
1639  int nf = sizeof( factories_ ) / sizeof( factories_[ 0 ] );
1640  for ( int i = 0; i < nf; ++i ) {
1641  gConvFactories[ factories_[ i ].first ] = factories_[ i ].second;
1642  }
1643  }
1644  } initConvFactories_;
1645 
1646 } // unnamed namespace
TCppScope_t TCppType_t
Definition: Cppyy.h:13
virtual Bool_t ToMemory(PyObject *value, void *address)
could happen if no derived class override
Definition: Converters.cxx:141
#define PyROOT_PyUnicode_FromString
Definition: PyROOT.h:71
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
construct a new string and copy it in new memory
Definition: Converters.cxx:547
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
long long Long64_t
Definition: RtypesCore.h:69
#define PyROOT_PyUnicode_GET_SIZE
Definition: PyROOT.h:68
Cppyy::TCppType_t fSmartPtrType
Definition: ObjectProxy.h:80
float Float_t
Definition: RtypesCore.h:53
const char * Int
RooArgList L(const RooAbsArg &v1)
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ instance**, set arg for call
virtual Bool_t ToMemory(PyObject *value, void *address)
just convert pointer if it is a ROOT object
Definition: Converters.cxx:748
virtual PyObject * FromMemory(void *address)
nothing sensible can be done, just return <address> as pylong
Definition: Converters.cxx:736
unsigned short UShort_t
Definition: RtypesCore.h:36
ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
Definition: Cppyy.cxx:615
static Long_t PyROOT_PyLong_AsStrictLong(PyObject *pyobject)
strict python integer to C++ integer conversion
Definition: Converters.cxx:117
TH1 * h
Definition: legend2.C:5
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
Definition: Cppyy.cxx:685
#define PyROOT_PyCapsule_CheckExact
Definition: PyROOT.h:83
#define H(x, y, z)
std::string GetFinalName(TCppType_t type)
Definition: Cppyy.cxx:556
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=0)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
const char * Long
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
const char * Char
#define PYROOT_BASIC_CONVERTER_FACTORY(name)
const char * UShort
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Int_t size)
TODO: this function exists for symmetry; need to figure out if it&#39;s useful.
const char * UInt
virtual Bool_t ToMemory(PyObject *value, void *address)
could happen if no derived class override
Definition: Converters.cxx:585
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
smart pointer converter
Bool_t UseStrictOwnership(TCallContext *ctxt)
Definition: TCallContext.h:85
#define PY_SSIZE_T_FORMAT
Definition: PyROOT.h:159
virtual PyObject * FromMemory(void *address)
Definition: Converters.cxx:568
#define PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER(name, type, low, high)
Definition: Converters.cxx:231
#define PYROOT_IMPLEMENT_BASIC_CONST_CHAR_REF_CONVERTER(name, type, low, high)
Definition: Converters.cxx:215
std::string ResolveName(const std::string &cppitem_name)
Definition: Cppyy.cxx:161
PyLong_FromUnsignedLongLong
Definition: Executors.cxx:289
union PyROOT::TParameter::Value fValue
static UShort_t PyROOT_PyLong_AsUShort(PyObject *pyobject)
range-checking python integer to C++ unsigend short int conversion
Definition: Converters.cxx:80
virtual PyObject * FromMemory(void *address)
Definition: Converters.cxx:131
std::vector< std::vector< double > > Data
void SetSmartPtr(void *address, Cppyy::TCppType_t ptrType)
Definition: ObjectProxy.h:40
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:391
#define PyROOT_PyUnicode_AsStringChecked
Definition: PyROOT.h:67
virtual Bool_t ToMemory(PyObject *value, void *address)
convert to C++ array of instances, write it at <address>
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:66
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *=0)
raise a NotImplemented exception to take a method out of overload resolution
const char * UChar
const char * Float
virtual PyObject * FromMemory(void *address)
R__EXTERN PyObject * gNullPtrObject
Definition: Converters.cxx:35
ULong_t PyLongOrInt_AsULong(PyObject *pyobject)
Definition: Utility.cxx:145
#define PYROOT_ARRAY_CONVERTER_FACTORY(name)
TConverter * CreateConverter(const std::string &fullType, Long_t size=-1)
virtual Bool_t ToMemory(PyObject *value, void *address)
convert to C++ instance*, write it at <address>
ptrdiff_t TCppMethod_t
Definition: Cppyy.h:15
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ instance**, set arg for call
Bool_t ObjectProxy_Check(T *object)
Definition: ObjectProxy.h:91
virtual Bool_t GetAddressSpecialCase(PyObject *pyobject, void *&address)
(1): "null pointer" or C++11 style nullptr
Definition: Converters.cxx:670
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
attempt base class first (i.e. passing a string), but if that fails, try a buffer ...
Definition: Converters.cxx:656
virtual Bool_t ToMemory(PyObject *value, void *address)
convert to C++ instance, write it at <address>
Definition: Converters.cxx:943
Bool_t TTupleOfInstances_CheckExact(T *object)
#define PyROOT_PyUnicode_FromStringAndSize
Definition: PyROOT.h:75
virtual PyObject * FromMemory(void *address)
assume this is a buffer access if the size is known; otherwise assume string
Definition: Converters.cxx:646
#define PYROOT_IMPLEMENT_ARRAY_CONVERTER(name, type, code)
Definition: Converters.cxx:779
unsigned int UInt_t
Definition: RtypesCore.h:42
const char * ULong
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
Convert <pyobject> to C++ unsigned long long, with bounds checking.
Definition: Utility.cxx:166
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE, Bool_t isValue=kFALSE)
only known or knowable objects will be bound (null object is ok)
short Short_t
Definition: RtypesCore.h:35
TLine * l
Definition: textangle.C:4
const char * Double
long double LongDouble_t
Definition: RtypesCore.h:57
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ void*&, set arg for call
virtual PyObject * FromMemory(void *address)
construct python object from C++ instance* read at <address>
PyObject * PyBuffer_FromMemory(Bool_t *buf, Py_ssize_t size=-1)
virtual PyObject * FromMemory(void *address)
construct python tuple of instances from C++ array read at <address>
Bool_t TCustomFloat_CheckExact(T *object)
void * CallR(TCppMethod_t method, TCppObject_t self, void *args)
Definition: Cppyy.cxx:463
long Long_t
Definition: RtypesCore.h:50
Bool_t IsSubtype(TCppType_t derived, TCppType_t base)
Definition: Cppyy.cxx:593
static Bool_t PyROOT_PyLong_AsBool(PyObject *pyobject)
range-checking python integer to C++ bool conversion
Definition: Converters.cxx:61
double f(double x)
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:171
double Double_t
Definition: RtypesCore.h:55
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
attempt base class first (i.e. passing a string), but if that fails, try a buffer ...
Definition: Converters.cxx:632
std::string GetMethodResultType(TCppMethod_t)
Definition: Cppyy.cxx:739
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
just convert pointer if it is a ROOT object
Definition: Converters.cxx:700
virtual PyObject * FromMemory(void *address)
construct python object from C++ instance read at <address>
Definition: Converters.cxx:935
R__EXTERN PyObject * gTypeCode
Definition: PyStrings.h:36
unsigned long long ULong64_t
Definition: RtypesCore.h:70
unsigned long ULong_t
Definition: RtypesCore.h:51
#define PYROOT_IMPLEMENT_BASIC_CONST_REF_CONVERTER(name, type, F1)
Definition: Converters.cxx:202
#define PyROOT_PyUnicode_Check
Definition: PyROOT.h:64
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2893
virtual PyObject * FromMemory(void *address)
read a void** from address; since this is unknown, long is used (user can cast)
static Int_t ExtractChar(PyObject *pyobject, const char *tname, Int_t low, Int_t high)
Definition: Converters.cxx:177
static void * PyROOT_PyCapsule_GetPointer(PyObject *capsule, const char *)
Definition: PyROOT.h:84
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ instance, set arg for call
Definition: Converters.cxx:980
static Short_t PyROOT_PyLong_AsShort(PyObject *pyobject)
range-checking python integer to C++ short int conversion
Definition: Converters.cxx:98
Bool_t IsSmartPtr(const std::string &)
Definition: Cppyy.cxx:606
const char * Bool
#define R__EXTERN
Definition: DllImport.h:27
char Char_t
Definition: RtypesCore.h:29
#define Py_TYPE(ob)
Definition: PyROOT.h:151
void * GetObject() const
Definition: ObjectProxy.h:47
static TPyBufferFactory * Instance()
static Char_t PyROOT_PyUnicode_AsChar(PyObject *pyobject)
python string to C++ char conversion
Definition: Converters.cxx:74
int GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, Bool_t check=kTRUE)
Retrieve a linear buffer pointer from the given pyobject.
Definition: Utility.cxx:539
std::map< std::string, ConverterFactory_t > ConvFactories_t
Definition: Converters.cxx:33
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
#define NULL
Definition: Rtypes.h:82
double result[121]
unsigned char UChar_t
Definition: RtypesCore.h:34
Definition: first.py:1
#define I(x, y, z)
const Bool_t kTRUE
Definition: Rtypes.h:91
ptrdiff_t TCppScope_t
Definition: Cppyy.h:12
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE)
if the object is a null pointer, return a typed one (as needed for overloading)
Bool_t IsEnum(const std::string &type_name)
Definition: Cppyy.cxx:550
Bool_t TCustomInt_CheckExact(T *object)
static ECallFlags sMemoryPolicy
Definition: TCallContext.h:49
char name[80]
Definition: TGX11.cxx:109
ConvFactories_t gConvFactories
Definition: Converters.cxx:34
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ void**, set arg for call
#define PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER(name, type, F1, F2)
Definition: Converters.cxx:845
_object PyObject
Definition: TPyArg.h:22
virtual Bool_t SetArg(PyObject *, TParameter &, TCallContext *ctxt=0)
convert <pyobject> to C++ instance&, set arg for call
R__EXTERN PyObject * gEmptyString
Definition: PyStrings.h:23
Cppyy::TCppType_t ObjectIsA() const
Definition: ObjectProxy.h:66
#define PYROOT_IMPLEMENT_BASIC_CONVERTER(name, type, stype, F1, F2, tc)
Definition: Converters.cxx:149
const std::string Compound(const std::string &name)
Break down the compound of a fully qualified type name.
Definition: Utility.cxx:658
const char * Short