14#include "TInterpreter.h"
15#include "TVirtualMutex.h"
16#include "TGenericClassInfo.h"
22constexpr auto getPtr(
typename std::remove_reference<T>::type& arg)
noexcept {
25 auto non_const_arg
ATLAS_THREAD_SAFE =
const_cast<std::remove_cvref<T>::type *
>( &arg);
29template <
typename ...T_MethodArgs>
30class ClingCallWrapperUncheckedReturnValue;
31template <
typename T_ReturnValue,
typename ...T_MethodArgs>
32class ClingCallWrapper;
34template <
typename ...T_MethodArgs>
35ClingCallWrapperUncheckedReturnValue<T_MethodArgs...>
getClingCallWrapper(TClass *the_class,
const std::string &method_name,
bool is_const);
37template <
typename T_ReturnValue,
typename ...T_MethodArgs>
38ClingCallWrapper<T_ReturnValue, T_MethodArgs...>
getClingCallWrapperChecked(ClingCallWrapperUncheckedReturnValue<T_MethodArgs...> &&call_wrapper);
45template <
typename ...T_MethodArgs>
47 template<
typename ...T_MethodArgsFunc>
50 template <
typename T_ReturnValue,
typename ...T_MethodArgsFunc>
65 template<
typename T_ReturnType>
66 T_ReturnType
call(
const void *
object, T_MethodArgs...args)
const {
67 T_ReturnType return_value;
74 m_methodWrapper(non_const_obj, arg_list.size(),arg_list.data(),&return_value);
80 template<
typename T_ReturnType>
82 return ROOT::Internal::GetDemangledTypeName(
typeid(T_ReturnType)) ==
m_method->GetReturnTypeNormalizedName();
87 return m_method->GetReturnTypeNormalizedName();
98template <
typename T_ReturnValue,
typename ...T_MethodArgs>
101template <
typename T_ReturnValueFunc,
typename ...T_MethodArgsFunc>
120 T_ReturnValue
operator()(
const void *
object, T_MethodArgs...args)
const {
129template <
typename ...T_MethodArgs>
138 return std::string();
143template <
typename T_First,
typename ...T_MethodArgs>
146 if (!arg_proto_type.empty()) {
150 constexpr unsigned int avTypeNameLength = 20;
151 arg_proto_type.reserve(
sizeof...(T_MethodArgs) * avTypeNameLength);
153 arg_proto_type += ROOT::Internal::GetDemangledTypeName(
typeid(T_First));
161template <
typename ...T_MethodArgs>
179template <
typename ...T_MethodArgs>
181 R__LOCKGUARD(gROOTMutex);
182 const TMethod *method = the_class->GetMethodWithPrototype(method_name.c_str(),
185 ROOT::kConversionMatch);
187 std::stringstream amsg; amsg <<
"Failed to get method " << method_name <<
"(" <<
makeArgumentPrototype<T_MethodArgs...>() <<
").";
188 throw std::runtime_error(amsg.str());
190 MethodInfo_t *method_info=gInterpreter->MethodInfo_Factory(method->GetDeclId());
191 static constexpr unsigned int flags = (kIsStatic|kIsPublic);
192 unsigned int method_properties = gInterpreter->MethodInfo_Property(method_info);
193 if ( (method_properties & flags) != kIsPublic ) {
194 std::runtime_error(
"Method is not public or is static.");
196 if (is_const && (method_properties & kIsConstant) != kIsConstant) {
197 std::runtime_error(
"Method is not constant.");
201 return TheClingCallWrapper_t(
reinterpret_cast<TheClingCallWrapper_t::TClingCallFuncWrapper_t
>(method->InterfaceMethod()),method);
209template <
typename T_ReturnValue,
typename ...T_MethodArgs>
211 if (!call_wrapper.template isReturnTypeMatching<T_ReturnValue>()) {
212 std::stringstream amsg;
213 amsg <<
"Return type mismatch. Desired "
214 << ROOT::Internal::GetDemangledTypeName(
typeid(T_ReturnValue))
215 <<
" != is " << call_wrapper.getReturnTypeNormalizedName();
216 throw std::runtime_error(amsg.str());
218 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.
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)