4#ifndef ROOTUTILS_CLINGCALLWRAPPER_H
5#define ROOTUTILS_CLINGCALLWRAPPER_H
18#include "TInterpreter.h"
19#include "TVirtualMutex.h"
20#include "TGenericClassInfo.h"
26constexpr auto getPtr(
typename std::remove_reference<T>::type& arg)
noexcept {
29 auto non_const_arg
ATLAS_THREAD_SAFE =
const_cast<std::remove_cvref<T>::type *
>( &arg);
33template <
typename ...T_MethodArgs>
34class ClingCallWrapperUncheckedReturnValue;
35template <
typename T_ReturnValue,
typename ...T_MethodArgs>
36class ClingCallWrapper;
38template <
typename ...T_MethodArgs>
39ClingCallWrapperUncheckedReturnValue<T_MethodArgs...>
getClingCallWrapper(TClass *the_class,
const std::string &method_name,
bool is_const);
41template <
typename T_ReturnValue,
typename ...T_MethodArgs>
42ClingCallWrapper<T_ReturnValue, T_MethodArgs...>
getClingCallWrapperChecked(ClingCallWrapperUncheckedReturnValue<T_MethodArgs...> &&call_wrapper);
49template <
typename ...T_MethodArgs>
51 template<
typename ...T_MethodArgsFunc>
54 template <
typename T_ReturnValue,
typename ...T_MethodArgsFunc>
69 template<
typename T_ReturnType>
70 T_ReturnType
call(
const void *
object, T_MethodArgs...args)
const {
71 T_ReturnType return_value;
78 m_methodWrapper(non_const_obj, arg_list.size(),arg_list.data(),&return_value);
84 template<
typename T_ReturnType>
86 return ROOT::Internal::GetDemangledTypeName(
typeid(T_ReturnType)) ==
m_method->GetReturnTypeNormalizedName();
91 return m_method->GetReturnTypeNormalizedName();
102template <
typename T_ReturnValue,
typename ...T_MethodArgs>
105template <
typename T_ReturnValueFunc,
typename ...T_MethodArgsFunc>
124 T_ReturnValue
operator()(
const void *
object, T_MethodArgs...args)
const {
133template <
typename ...T_MethodArgs>
142 return std::string();
147template <
typename T_First,
typename ...T_MethodArgs>
150 if (!arg_proto_type.empty()) {
154 constexpr unsigned int avTypeNameLength = 20;
155 arg_proto_type.reserve(
sizeof...(T_MethodArgs) * avTypeNameLength);
157 arg_proto_type += ROOT::Internal::GetDemangledTypeName(
typeid(T_First));
165template <
typename ...T_MethodArgs>
183template <
typename ...T_MethodArgs>
185 R__LOCKGUARD(gROOTMutex);
186 const TMethod *method = the_class->GetMethodWithPrototype(method_name.c_str(),
189 ROOT::kConversionMatch);
191 std::stringstream amsg; amsg <<
"Failed to get method " << method_name <<
"(" <<
makeArgumentPrototype<T_MethodArgs...>() <<
").";
192 throw std::runtime_error(amsg.str());
194 MethodInfo_t *method_info=gInterpreter->MethodInfo_Factory(method->GetDeclId());
195 static constexpr unsigned int flags = (kIsStatic|kIsPublic);
196 unsigned int method_properties = gInterpreter->MethodInfo_Property(method_info);
197 if ( (method_properties & flags) != kIsPublic ) {
198 std::runtime_error(
"Method is not public or is static.");
200 if (is_const && (method_properties & kIsConstant) != kIsConstant) {
201 std::runtime_error(
"Method is not constant.");
205 return TheClingCallWrapper_t(
reinterpret_cast<TheClingCallWrapper_t::TClingCallFuncWrapper_t
>(method->InterfaceMethod()),method);
213template <
typename T_ReturnValue,
typename ...T_MethodArgs>
215 if (!call_wrapper.template isReturnTypeMatching<T_ReturnValue>()) {
216 std::stringstream amsg;
217 amsg <<
"Return type mismatch. Desired "
219 <<
" != is " << call_wrapper.getReturnTypeNormalizedName();
220 throw std::runtime_error(amsg.str());
222 return ClingCallWrapper<T_ReturnValue, T_MethodArgs...>(std::forward<decltype(call_wrapper)>(call_wrapper));
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Intermediate helper class wrapping a cling method call with arbitrary return type.
T_ReturnType call(const void *object, T_MethodArgs...args) const
std::string getReturnTypeNormalizedName() const
the normalized name of the function return type.
TClingCallFuncWrapper_t m_methodWrapper
ClingCallWrapperUncheckedReturnValue(TClingCallFuncWrapper_t method_wrapper, const TMethod *method)
TMethodCall::EReturnType m_returnType
void(*)(void *, int, void **, void *) TClingCallFuncWrapper_t
bool isReturnTypeMatching() const
Test whether the function return type and the template parameter are the same.
friend ClingCallWrapper< T_ReturnValue, T_MethodArgsFunc... > getClingCallWrapperChecked(ClingCallWrapperUncheckedReturnValue< T_MethodArgsFunc... > &&call_wrapper)
friend ClingCallWrapperUncheckedReturnValue< T_MethodArgsFunc... > getClingCallWrapper(TClass *the_class, const std::string &method_name, bool is_const)
helper method to wrap a method of a certain name with defined arguments, but arbitrary return type im...
Helper class to wrap a cling method call of an object's method with defined return type and argument ...
friend ClingCallWrapper< T_ReturnValueFunc, T_MethodArgsFunc... > getClingCallWrapperChecked(ClingCallWrapperUncheckedReturnValue< T_MethodArgsFunc... > &&call_wrapper)
T_ReturnValue operator()(const void *object, T_MethodArgs...args) const
call the wrapped cling method.
ClingCallWrapper(const ClingCallWrapperUncheckedReturnValue< T_MethodArgs... > &call_wrapper)
create a cling method wrapper for a method with defined argument list and return type (copy).
ClingCallWrapper(ClingCallWrapperUncheckedReturnValue< T_MethodArgs... > &&call_wrapper)
create a cling method wrapper for a method with defined argument list and return type (move).
std::string makeArgumentPrototype()
template function to create a argument list prototype from a type list.
ClingCallWrapper< T_ReturnValue, T_MethodArgs... > getClingCallWrapperChecked(ClingCallWrapperUncheckedReturnValue< T_MethodArgs... > &&call_wrapper)
wrap a cling method call for a method with defined arguments and return types.
std::string getNormalizedTypeName()
constexpr auto getPtr(typename std::remove_reference< T >::type &arg) noexcept
ClingCallWrapperUncheckedReturnValue< T_MethodArgs... > getClingCallWrapper(TClass *the_class, const std::string &method_name, bool is_const)
helper method to wrap a method of a certain name with defined arguments, but arbitrary return type im...
static void addArgumentPrototype(std::string &arg_proto_type)
static std::string addArgumentPrototype(std::string &arg_proto_type)
helper template to turn an argument list into a prototype string.
static std::string addArgumentPrototype(std::string &arg_proto_type)