Skip to content

Commit e63b71d

Browse files
add lambda related reflection/wrapper functions (#165)
`WrapLambdaFromVariable`: wraps a lambda variable to `std::function` This is required for codegen and execution, because lambda are types that cannot be expressed. Without this conversion from lambda to std::function we will not have sufficient type information to execute the lambda. Example of conversion: ```c++ // from auto f = [](){ return 1; } // to namespace __cppyy_internal_wrap_g { std::function f = ::f; } ``` `AdaptFunctionForLambdaReturn`: This wraps a function that returns a lambda to return `std::function` Example: ```c++ // from auto f() { return [](){ return 1; } // to namespace __cppyy_internal_wrap_g { auto wrapper_fn(...args) { return std::function(f(args...)); } } ```
1 parent ce32d49 commit e63b71d

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

clingwrapper/src/clingwrapper.cxx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,50 @@ bool Cppyy::CheckDatamember(TCppScope_t scope, const std::string& name) {
18351835
return (bool) Cpp::LookupDatamember(name, scope);
18361836
}
18371837

1838+
bool Cppyy::IsLambdaClass(TCppType_t type) {
1839+
return Cpp::IsLambdaClass(type);
1840+
}
1841+
1842+
Cppyy::TCppScope_t Cppyy::WrapLambdaFromVariable(TCppScope_t var) {
1843+
std::ostringstream code;
1844+
std::string name = Cppyy::GetFinalName(var);
1845+
code << "namespace __cppyy_internal_wrap_g {\n"
1846+
<< " " << "std::function " << name << " = ::" << Cpp::GetQualifiedName(var) << ";\n"
1847+
<< "}\n";
1848+
1849+
if (Cppyy::Compile(code.str().c_str())) {
1850+
TCppScope_t res = Cpp::GetNamed(name, Cpp::GetScope("__cppyy_internal_wrap_g"));
1851+
if (res) return res;
1852+
}
1853+
return var;
1854+
}
1855+
1856+
Cppyy::TCppScope_t Cppyy::AdaptFunctionForLambdaReturn(TCppScope_t fn) {
1857+
std::string fn_name = Cpp::GetQualifiedCompleteName(fn);
1858+
std::string signature = Cppyy::GetMethodSignature(fn, true);
1859+
1860+
std::ostringstream call;
1861+
call << "(";
1862+
for (size_t i = 0, n = Cppyy::GetMethodNumArgs(fn); i < n; i++) {
1863+
call << Cppyy::GetMethodArgName(fn, i);
1864+
if (i != n - 1)
1865+
call << ", ";
1866+
}
1867+
call << ")";
1868+
1869+
std::ostringstream code;
1870+
static int i = 0;
1871+
std::string name = "lambda_return_convert_" + std::to_string(++i);
1872+
code << "namespace __cppyy_internal_wrap_g {\n"
1873+
<< "auto " << name << signature << "{" << "return std::function(" << fn_name << call.str() << "); }\n"
1874+
<< "}\n";
1875+
if (Cppyy::Compile(code.str().c_str())) {
1876+
TCppScope_t res = Cpp::GetNamed(name, Cpp::GetScope("__cppyy_internal_wrap_g"));
1877+
if (res) return res;
1878+
}
1879+
return fn;
1880+
}
1881+
18381882
// std::string Cppyy::GetDatamemberName(TCppScope_t scope, TCppIndex_t idata)
18391883
// {
18401884
// TClassRef& cr = type_from_handle(scope);

clingwrapper/src/cpp_cppyy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ namespace Cppyy {
359359
// RPY_EXPORTED
360360
// std::string GetDatamemberName(TCppScope_t scope, TCppIndex_t idata) { return ""; }
361361
RPY_EXPORTED
362+
bool IsLambdaClass(TCppType_t type);
363+
RPY_EXPORTED
364+
TCppScope_t WrapLambdaFromVariable(TCppScope_t var);
365+
RPY_EXPORTED
366+
TCppScope_t AdaptFunctionForLambdaReturn(TCppScope_t fn);
367+
RPY_EXPORTED
362368
TCppType_t GetDatamemberType(TCppScope_t data);
363369
RPY_EXPORTED
364370
std::string GetDatamemberTypeAsString(TCppScope_t var);

0 commit comments

Comments
 (0)