@@ -509,34 +509,34 @@ PyObject* CPyCppyy::VoidArrayExecutor::Execute(
509509}
510510
511511// ----------------------------------------------------------------------------
512- #define CPPYY_IMPL_ARRAY_EXEC (name, type ) \
512+ #define CPPYY_IMPL_ARRAY_EXEC (name, type, suffix ) \
513513PyObject* CPyCppyy::name##ArrayExecutor::Execute( \
514514 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
515515{ \
516- return CreateLowLevelView ((type*)GILCallR (method, self, ctxt), fShape ); \
516+ return CreateLowLevelView## suffix ((type*)GILCallR (method, self, ctxt), fShape ); \
517517}
518518
519- CPPYY_IMPL_ARRAY_EXEC (Bool, bool )
520- CPPYY_IMPL_ARRAY_EXEC(UChar, unsigned char )
519+ CPPYY_IMPL_ARRAY_EXEC (Bool, bool , )
520+ CPPYY_IMPL_ARRAY_EXEC(UChar, unsigned char , )
521521#if __cplusplus > 201402L
522- CPPYY_IMPL_ARRAY_EXEC (Byte, std::byte)
522+ CPPYY_IMPL_ARRAY_EXEC (Byte, std::byte, )
523523#endif
524- CPPYY_IMPL_ARRAY_EXEC (Int8, int8_t )
525- CPPYY_IMPL_ARRAY_EXEC(UInt8, uint8_t )
526- CPPYY_IMPL_ARRAY_EXEC(Short, short )
527- CPPYY_IMPL_ARRAY_EXEC(UShort, unsigned short )
528- CPPYY_IMPL_ARRAY_EXEC(Int, int )
529- CPPYY_IMPL_ARRAY_EXEC(UInt, unsigned int )
530- CPPYY_IMPL_ARRAY_EXEC(Long, long )
531- CPPYY_IMPL_ARRAY_EXEC(ULong, unsigned long )
532- CPPYY_IMPL_ARRAY_EXEC(LLong, long long )
533- CPPYY_IMPL_ARRAY_EXEC(ULLong, unsigned long long )
534- CPPYY_IMPL_ARRAY_EXEC(Float, float )
535- CPPYY_IMPL_ARRAY_EXEC(Double, double )
536- CPPYY_IMPL_ARRAY_EXEC(ComplexF, std::complex <float >)
537- CPPYY_IMPL_ARRAY_EXEC(ComplexD, std::complex <double >)
538- CPPYY_IMPL_ARRAY_EXEC(ComplexI, std::complex <int >)
539- CPPYY_IMPL_ARRAY_EXEC(ComplexL, std::complex <long >)
524+ CPPYY_IMPL_ARRAY_EXEC (Int8, int8_t , _i8 )
525+ CPPYY_IMPL_ARRAY_EXEC(UInt8, uint8_t , _i8 )
526+ CPPYY_IMPL_ARRAY_EXEC(Short, short , )
527+ CPPYY_IMPL_ARRAY_EXEC(UShort, unsigned short , )
528+ CPPYY_IMPL_ARRAY_EXEC(Int, int , )
529+ CPPYY_IMPL_ARRAY_EXEC(UInt, unsigned int , )
530+ CPPYY_IMPL_ARRAY_EXEC(Long, long , )
531+ CPPYY_IMPL_ARRAY_EXEC(ULong, unsigned long , )
532+ CPPYY_IMPL_ARRAY_EXEC(LLong, long long , )
533+ CPPYY_IMPL_ARRAY_EXEC(ULLong, unsigned long long , )
534+ CPPYY_IMPL_ARRAY_EXEC(Float, float , )
535+ CPPYY_IMPL_ARRAY_EXEC(Double, double , )
536+ CPPYY_IMPL_ARRAY_EXEC(ComplexF, std::complex <float >, )
537+ CPPYY_IMPL_ARRAY_EXEC(ComplexD, std::complex <double >, )
538+ CPPYY_IMPL_ARRAY_EXEC(ComplexI, std::complex <int >, )
539+ CPPYY_IMPL_ARRAY_EXEC(ComplexL, std::complex <long >, )
540540
541541
542542// - special cases ------------------------------------------------------------
@@ -591,7 +591,7 @@ PyObject* CPyCppyy::STLWStringExecutor::Execute(
591591 }
592592
593593 PyObject* pyresult = PyUnicode_FromWideChar (result->c_str (), result->size ());
594- :: operator delete ( result) ; // calls Cppyy::CallO which calls ::operator new
594+ delete result; // Cppyy::CallO allocates and constructs a string, so it must be properly destroyed
595595
596596 return pyresult;
597597}
@@ -642,6 +642,21 @@ CPyCppyy::IteratorExecutor::IteratorExecutor(Cppyy::TCppScope_t klass) :
642642 fFlags |= CPPInstance::kNoWrapConv ; // adds to flags from base class
643643}
644644
645+ // ----------------------------------------------------------------------------
646+ PyObject* CPyCppyy::IteratorExecutor::Execute (
647+ Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt)
648+ {
649+ PyObject* iter = this ->InstanceExecutor ::Execute (method, self, ctxt);
650+ if (iter && ctxt->fPyContext ) {
651+ // set life line to tie iterator life time to the container (which may
652+ // be a temporary)
653+ std::ostringstream attr_name;
654+ attr_name << " __" << (intptr_t )iter;
655+ if (PyObject_SetAttrString (ctxt->fPyContext , (char *)attr_name.str ().c_str (), iter))
656+ PyErr_Clear ();
657+ }
658+ return iter;
659+ }
645660
646661// ----------------------------------------------------------------------------
647662PyObject* CPyCppyy::InstanceRefExecutor::Execute (
@@ -850,7 +865,7 @@ CPyCppyy::Executor* CPyCppyy::CreateExecutor(const std::string& fullType, cdims_
850865// C++ classes and special cases
851866 Executor* result = 0 ;
852867 if (Cppyy::TCppType_t klass = Cppyy::GetFullScope (realType)) {
853- if (resolvedType. find ( " iterator " ) != std::string::npos || gIteratorTypes .find (fullType) != gIteratorTypes .end ()) {
868+ if (Utility::IsSTLIterator (realType) || gIteratorTypes .find (fullType) != gIteratorTypes .end ()) {
854869 if (cpd == " " )
855870 return new IteratorExecutor (klass);
856871 }
@@ -1012,6 +1027,23 @@ bool CPyCppyy::RegisterExecutor(const std::string& name, ef_t fac)
10121027 return true ;
10131028}
10141029
1030+ // ----------------------------------------------------------------------------
1031+ CPYCPPYY_EXPORT
1032+ bool CPyCppyy::RegisterExecutorAlias (const std::string& name, const std::string& target)
1033+ {
1034+ // register a custom executor that is a reference to an existing converter
1035+ auto f = gExecFactories .find (name);
1036+ if (f != gExecFactories .end ())
1037+ return false ;
1038+
1039+ auto t = gExecFactories .find (target);
1040+ if (t == gExecFactories .end ())
1041+ return false ;
1042+
1043+ gExecFactories [name] = t->second ;
1044+ return true ;
1045+ }
1046+
10151047// ----------------------------------------------------------------------------
10161048CPYCPPYY_EXPORT
10171049bool CPyCppyy::UnregisterExecutor (const std::string& name)
@@ -1164,9 +1196,9 @@ struct InitExecFactories_t {
11641196 gf[CCOMPLEX_D " ptr" ] = gf[" std::complex<double> ptr" ];
11651197
11661198 // factories for special cases
1167- gf[" const char*" ] = (ef_t )+[]() { static CStringExecutor e{}; return &e; };
1199+ gf[" const char*" ] = (ef_t )+[](cdims_t ) { static CStringExecutor e{}; return &e; };
11681200 gf[" char*" ] = gf[" const char*" ];
1169- gf[" const char*&" ] = (ef_t )+[]() { static CStringRefExecutor e{}; return &e; };
1201+ gf[" const char*&" ] = (ef_t )+[](cdims_t ) { static CStringRefExecutor e{}; return &e; };
11701202 gf[" char*&" ] = gf[" const char*&" ];
11711203 gf[" const signed char*" ] = gf[" const char*" ];
11721204 gf[" signed char*" ] = gf[" char*" ];
0 commit comments