Skip to content

Commit 6e38498

Browse files
committed
Sync Executor
1 parent 8034e74 commit 6e38498

File tree

2 files changed

+58
-25
lines changed

2 files changed

+58
-25
lines changed

src/Executors.cxx

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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) \
513513
PyObject* 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
//----------------------------------------------------------------------------
647662
PyObject* 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
//----------------------------------------------------------------------------
10161048
CPYCPPYY_EXPORT
10171049
bool 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*"];

src/Executors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ CPYCPPYY_EXPORT Executor* CreateExecutor(Cppyy::TCppType_t type, cdims_t = 0);
3737
CPYCPPYY_EXPORT void DestroyExecutor(Executor* p);
3838
typedef Executor* (*ef_t) (cdims_t);
3939
CPYCPPYY_EXPORT bool RegisterExecutor(const std::string& name, ef_t fac);
40+
CPYCPPYY_EXPORT bool RegisterExecutorAlias(const std::string& name, const std::string& target);
4041
CPYCPPYY_EXPORT bool UnregisterExecutor(const std::string& name);
4142

4243
// helper for the actual call

0 commit comments

Comments
 (0)