File indexing completed on 2024-04-06 12:01:17
0001 #ifndef CommonTools_Utils_MethodInvoker_h
0002 #define CommonTools_Utils_MethodInvoker_h
0003
0004 #include "CommonTools/Utils/interface/parser/AnyMethodArgument.h"
0005 #include "CommonTools/Utils/interface/TypeCode.h"
0006 #include "FWCore/Reflection/interface/FunctionWithDict.h"
0007 #include "FWCore/Reflection/interface/MemberWithDict.h"
0008 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0009 #include "FWCore/Utilities/interface/TypeID.h"
0010
0011 #include <map>
0012 #include <vector>
0013
0014 #include "oneapi/tbb/concurrent_unordered_map.h"
0015 #include "oneapi/tbb/concurrent_queue.h"
0016
0017 namespace edm {
0018 struct TypeIDHasher {
0019 size_t operator()(TypeID const& tid) const { return std::hash<std::string>{}(std::string(tid.name())); }
0020 };
0021 }
0022
0023 namespace reco {
0024 namespace parser {
0025
0026 class MethodInvoker {
0027 private:
0028 edm::FunctionWithDict method_;
0029 edm::MemberWithDict member_;
0030 std::vector<AnyMethodArgument> ints_;
0031 std::vector<void*> args_;
0032
0033 bool isFunction_;
0034 edm::TypeWithDict retTypeFinal_;
0035
0036 private:
0037 void setArgs();
0038
0039 public:
0040 explicit MethodInvoker(const edm::FunctionWithDict& method,
0041 const std::vector<AnyMethodArgument>& ints = std::vector<AnyMethodArgument>());
0042 explicit MethodInvoker(const edm::MemberWithDict&);
0043 MethodInvoker(const MethodInvoker&);
0044 MethodInvoker& operator=(const MethodInvoker&);
0045
0046 edm::FunctionWithDict const method() const { return method_; }
0047 edm::MemberWithDict const member() const { return member_; }
0048 bool isFunction() const { return isFunction_; }
0049 std::string methodName() const;
0050 std::string returnTypeName() const;
0051
0052
0053
0054
0055
0056
0057 edm::ObjectWithDict invoke(const edm::ObjectWithDict& obj, edm::ObjectWithDict& retstore) const;
0058 };
0059
0060 struct SingleInvoker;
0061
0062
0063 struct StorageManager {
0064 private:
0065 edm::ObjectWithDict object_;
0066 SingleInvoker const* invoker_;
0067 bool needsDestructor_;
0068
0069 public:
0070 StorageManager(edm::ObjectWithDict const& iObj, SingleInvoker const* iInvoker, bool iNeedsDestructor_)
0071 : object_(iObj), invoker_(iInvoker), needsDestructor_(iNeedsDestructor_) {}
0072
0073 StorageManager(const StorageManager&) = delete;
0074 StorageManager(StorageManager&& iOther)
0075 : object_(iOther.object_), invoker_(iOther.invoker_), needsDestructor_(iOther.needsDestructor_) {
0076 iOther.needsDestructor_ = false;
0077 iOther.invoker_ = nullptr;
0078 }
0079 StorageManager& operator=(const StorageManager&) = delete;
0080 StorageManager& operator=(StorageManager&&) = delete;
0081
0082 ~StorageManager();
0083 };
0084
0085
0086
0087
0088 struct SingleInvoker {
0089 private:
0090 method::TypeCode retType_;
0091 std::vector<MethodInvoker> invokers_;
0092 mutable oneapi::tbb::concurrent_queue<edm::ObjectWithDict> storage_;
0093 bool storageNeedsDestructor_;
0094
0095 bool isRefGet_;
0096
0097 edm::ObjectWithDict borrowStorage() const;
0098
0099 edm::ObjectWithDict createStorage(bool& needsDestructor) const;
0100
0101 public:
0102 SingleInvoker(const SingleInvoker&) = delete;
0103 SingleInvoker& operator=(const SingleInvoker&) = delete;
0104
0105 SingleInvoker(const edm::TypeWithDict&, const std::string& name, const std::vector<AnyMethodArgument>& args);
0106 ~SingleInvoker();
0107
0108
0109
0110
0111
0112
0113
0114
0115 std::pair<edm::ObjectWithDict, bool> invoke(const edm::ObjectWithDict& o, std::vector<StorageManager>& v) const;
0116
0117
0118 double retToDouble(const edm::ObjectWithDict&) const;
0119
0120 void throwFailedConversion(const edm::ObjectWithDict&) const;
0121
0122 void returnStorage(edm::ObjectWithDict&&) const;
0123 };
0124
0125
0126 struct LazyInvoker {
0127 typedef std::shared_ptr<SingleInvoker> SingleInvokerPtr;
0128 typedef tbb::concurrent_unordered_map<edm::TypeID, SingleInvokerPtr, edm::TypeIDHasher> InvokerMap;
0129
0130 private:
0131 std::string name_;
0132 std::vector<AnyMethodArgument> argsBeforeFixups_;
0133
0134
0135
0136 mutable InvokerMap invokers_;
0137
0138 private:
0139 const SingleInvoker& invoker(const edm::TypeWithDict&) const;
0140
0141 public:
0142 explicit LazyInvoker(const std::string& name, const std::vector<AnyMethodArgument>& args);
0143 ~LazyInvoker();
0144
0145
0146
0147
0148
0149
0150
0151 edm::ObjectWithDict invoke(const edm::ObjectWithDict& o, std::vector<StorageManager>& v) const;
0152
0153
0154 double invokeLast(const edm::ObjectWithDict& o, std::vector<StorageManager>& v) const;
0155 };
0156
0157 }
0158 }
0159
0160 #endif