ATLAS Offline Software
Loading...
Searching...
No Matches
MethodAccessor.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4#ifndef _ExpressionEvaluation_MethodAccessor_h_
5#define _ExpressionEvaluation_MethodAccessor_h_
6
11
12#include "TClass.h"
15#include "TMethodCall.h"
16#include "TVirtualCollectionProxy.h"
17#include "TFunction.h"
18
19#include <memory>
20#include <map>
21#include <stdexcept>
22#include <sstream>
23#include <cassert>
24
25namespace ExpressionParsing {
26
29 template <class T_Cont,typename T_src>
31 public:
32 CollectionMethodHelper(const RootUtils::TSMethodCall& method_call, const TVirtualCollectionProxy &collection_proxy, const void *data, [[maybe_unused]] unsigned int n_elements)
33 : m_methodCall( method_call),
34 m_collectionProxy( collection_proxy.Generate())
35 {
36 // cppcheck-suppress assertWithSideEffect
37 assert( m_methodCall.call() != nullptr );
38 void* data_nc ATLAS_THREAD_SAFE = const_cast<void *>(data); // required by TVirtualCollectionProxy
39 m_collectionProxy->PushProxy(data_nc);
40 assert( m_collectionProxy->Size() == n_elements);
41 }
42
43 std::size_t size(const T_Cont &/*cont*/) const {
44 return m_collectionProxy->Size();
45 }
46
48 T_src get(const T_Cont &/*cont*/) const {
49 T_src ret;
50 assert( m_collectionProxy->Size() == 1);
51 m_methodCall.call()->Execute((*m_collectionProxy)[0], ret);
52 return ret;
53 }
54
56 T_src get(const T_Cont &/*cont*/, std::size_t idx) const {
57 T_src ret;
58 void *element_data=(*m_collectionProxy)[idx];
59 m_methodCall.call()->Execute(element_data, ret);
60 return ret;
61 }
62
65 class Kit {
66 public:
67 Kit(Kit &&) = default;
68 Kit(RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy &collection_proxy)
69 : m_methodCall(std::move(method_call)),
70 m_collectionProxy(&collection_proxy)
71 {}
72
73 CollectionMethodHelper<T_Cont,T_src> create(const EventContext& /*ctx*/,
74 SG::ReadHandle<T_Cont> &handle) const
75 {
77 }
78 private:
80 const TVirtualCollectionProxy *m_collectionProxy;
81 };
82
83 private:
85 std::unique_ptr<TVirtualCollectionProxy> m_collectionProxy;
86 };
87
90 template <class T_Cont,typename T_src>
92 public:
93 MethodHelper(const RootUtils::TSMethodCall& method_call, const void *data)
94 : m_methodCall( method_call),
96 {
97 // cppcheck-suppress assertWithSideEffect
98 assert( m_methodCall.call() != nullptr );
99 }
100
101 std::size_t size(const T_Cont &cont) const {
102 return getContainerSize(cont); //@TODO correct ? or 1 ?
103 }
104
106 T_src get(const T_Cont &/*cont*/) const {
107 T_src ret;
108 void* data_nc ATLAS_THREAD_SAFE = const_cast<void *>(m_data); // required by TMethodCall
109 m_methodCall.call()->Execute(data_nc, ret);
110 return ret;
111 }
112
114 T_src get(const T_Cont &/*cont*/, [[maybe_unused]] std::size_t idx) const {
115 T_src ret;
116 assert( idx==0);
117 void* data_nc ATLAS_THREAD_SAFE = const_cast<void *>(m_data); // required by TMethodCall
118 m_methodCall.call()->Execute(data_nc, ret);
119 return ret;
120 }
121
124 class Kit {
125 public:
126 Kit(Kit &&) = default;
127 Kit(RootUtils::TSMethodCall &&method_call) : m_methodCall(std::move(method_call)) {}
128
129 MethodHelper<T_Cont,T_src> create(const EventContext& /*ctx*/, SG::ReadHandle<T_Cont> &handle) const {
130 return MethodHelper<T_Cont,T_src>(m_methodCall,handle.cptr());
131 }
132 private:
134 };
135 private:
137 const void *m_data;
138 };
139
142 class MethodAccessorFactory : public Singleton<MethodAccessorFactory> {
143 private:
146 public:
148 virtual std::unique_ptr<IAccessor> create( const SG::ReadHandleKey<SG::AuxVectorBase> &key,
149 RootUtils::TSMethodCall &&method_call,
150 TVirtualCollectionProxy *proxy=nullptr) const = 0;
151 virtual std::unique_ptr<IAccessor> create( const SG::ReadHandleKey<SG::AuxElement> &key,
152 RootUtils::TSMethodCall &&method_call,
153 TVirtualCollectionProxy *proxy=nullptr) const = 0;
154 };
155
158 template <class T_src>
160 public:
166
168 virtual std::unique_ptr<IAccessor> create( const SG::ReadHandleKey<SG::AuxVectorBase> &key,
169 RootUtils::TSMethodCall &&method_call,
170 TVirtualCollectionProxy *proxy) const override {
171 if (!proxy) {
172 std::stringstream msg;
173 msg << "Cannot use method access of types SG::AuxVectorBase without a collection proxy.";
174 throw std::logic_error(msg.str());
175 }
176 return createAccessor<SG::AuxVectorBase, VectorHelper>(key,std::move(method_call),proxy,m_vectorType);
177 }
178
180 virtual std::unique_ptr<IAccessor> create( const SG::ReadHandleKey<SG::AuxElement> &key,
181 RootUtils::TSMethodCall &&method_call,
182 TVirtualCollectionProxy *proxy=nullptr) const override {
183 if (proxy) {
184 return createAccessor<SG::AuxElement,VectorHelper>(key,std::move(method_call),proxy, (!proxy ? m_scalarType : m_vectorType));
185 }
186 else {
187 return createAccessor<SG::AuxElement,ScalarHelper>(key,std::move(method_call),proxy, (!proxy ? m_scalarType : m_vectorType));
188 }
189 // @TODO really vectorType and GenScalarAccessor if collection proxy is given ?
190 }
191 private:
192 template <class T_Aux, class T_ScalarVectorHelper>
193 std::unique_ptr<IAccessor> createAccessor( const SG::ReadHandleKey<T_Aux> &key,
194 RootUtils::TSMethodCall &&method_call,
195 TVirtualCollectionProxy *proxy,
197 if (proxy) {
198 return std::make_unique<GenAccessor<T_Aux,
200 T_ScalarVectorHelper> >(key,
201 typename CollectionMethodHelper<T_Aux,T_src>::Kit(std::move(method_call), *proxy),
202 variable_type);
203 }
204 else {
205 return std::make_unique<GenAccessor<T_Aux,
207 T_ScalarVectorHelper> >(key,
208 typename MethodHelper<T_Aux,T_src>::Kit(std::move(method_call)),
209 variable_type);
210 }
211 }
214 };
215
216 public:
218 m_kits.insert( std::make_pair(TInterpreter::EReturnType::kLong,std::make_unique<MethodAccessorKit<long> >(IProxyLoader::VT_INT,IProxyLoader::VT_VECINT)));
219 m_kits.insert( std::make_pair(TInterpreter::EReturnType::kDouble,std::make_unique<MethodAccessorKit<double> >(IProxyLoader::VT_DOUBLE, IProxyLoader::VT_VECDOUBLE)));
220 }
221
224 std::unique_ptr<IAccessor> create(const SG::ReadHandleKey<SG::AuxElement> &key,
225 RootUtils::TSMethodCall &&method_call,
226 TVirtualCollectionProxy *proxy=nullptr) const {
227 return getKit(method_call).create(key,std::move(method_call), proxy);
228 }
229
232 std::unique_ptr<IAccessor> create(const SG::ReadHandleKey<SG::AuxVectorBase> &key,
233 RootUtils::TSMethodCall &&method_call,
234 TVirtualCollectionProxy *proxy=nullptr) const {
235 return getKit(method_call).create(key,std::move(method_call), proxy);
236 }
237
238 private:
239
243 std::map<TMethodCall::EReturnType, std::unique_ptr<IMethodAccessorKit> >::const_iterator
244 iter = m_kits.find(method_call.call()->ReturnType());
245 if (iter == m_kits.end()) {
246 std::stringstream msg;
247 msg << "ExpressionParsing::MethodAccessorFactory: no kit for return type " << method_call.call()->GetMethod()->GetReturnTypeNormalizedName ();
248 throw std::runtime_error(msg.str());
249 }
250 return *(iter->second);
251 }
252 std::map<TMethodCall::EReturnType, std::unique_ptr<IMethodAccessorKit> > m_kits;
253 };
254
255}
256#endif
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Property holding a SG store/key/clid from which a ReadHandle is made.
Handle class for reading from StoreGate.
Define macros for attributes used to control the static checker.
Auxiliary class to create the corresponding auxiliary helper object.
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
CollectionMethodHelper< T_Cont, T_src > create(const EventContext &, SG::ReadHandle< T_Cont > &handle) const
Kit(RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy &collection_proxy)
const TVirtualCollectionProxy * m_collectionProxy
std::unique_ptr< TVirtualCollectionProxy > m_collectionProxy
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
T_src get(const T_Cont &) const
Get the scalar provided by the container.
std::size_t size(const T_Cont &) const
CollectionMethodHelper(const RootUtils::TSMethodCall &method_call, const TVirtualCollectionProxy &collection_proxy, const void *data, unsigned int n_elements)
T_src get(const T_Cont &, std::size_t idx) const
Get the specified element of the vector provided by the container.
Generic accessor to access xAOD object content.
Definition GenAccessor.h:63
virtual std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxElement > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy=nullptr) const =0
virtual std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxVectorBase > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy=nullptr) const =0
Auxiliary class to create a specific accessor which calls a method of an AuxElement or AuxVectorBase.
std::unique_ptr< IAccessor > createAccessor(const SG::ReadHandleKey< T_Aux > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy, ExpressionParsing::IProxyLoader::VariableType variable_type) const
virtual std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxVectorBase > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy) const override
create an accessor which called the specified method of an AuxVectorBase.
virtual std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxElement > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy=nullptr) const override
create an accessor which called the specified method of an AuxElement.
ExpressionParsing::IProxyLoader::VariableType m_scalarType
ExpressionParsing::IProxyLoader::VariableType m_vectorType
MethodAccessorKit(ExpressionParsing::IProxyLoader::VariableType scalar_type, ExpressionParsing::IProxyLoader::VariableType vector_type)
const IMethodAccessorKit & getKit(RootUtils::TSMethodCall &method_call) const
Get an specific class which creates the accessor for the given method.
std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxVectorBase > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy=nullptr) const
Create an accessor which calls the specified method of an AuxVectorBase.
std::map< TMethodCall::EReturnType, std::unique_ptr< IMethodAccessorKit > > m_kits
std::unique_ptr< IAccessor > create(const SG::ReadHandleKey< SG::AuxElement > &key, RootUtils::TSMethodCall &&method_call, TVirtualCollectionProxy *proxy=nullptr) const
Create an accessor which calls the specified method of an AuxElement.
Auxiliary class to create the corresponding auxiliary helper object.
Kit(RootUtils::TSMethodCall &&method_call)
MethodHelper< T_Cont, T_src > create(const EventContext &, SG::ReadHandle< T_Cont > &handle) const
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
T_src get(const T_Cont &) const
Get the scalar provided by the container.
MethodHelper(const RootUtils::TSMethodCall &method_call, const void *data)
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
std::size_t size(const T_Cont &cont) const
T_src get(const T_Cont &, std::size_t idx) const
Get the specified element of the vector provided by the container.
Helper for making a thread-safe function call.
TMethodCall * call()
Return a pointer to the thread-specific TMethodCall.
Property holding a SG store/key/clid from which a ReadHandle is made.
const_pointer_type cptr()
Dereference the pointer.
Namespace holding all the expression evaluation code.
const SG::AuxVectorData * getVectorData(const T &cont)
STL namespace.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
MsgStream & msg
Definition testRead.cxx:32