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