14#include "TInterpreter.h"
27 using BitsGetter = std::function<std::string(
const SG::AuxElement&)>;
28 using BitsSetter = std::function<void(
SG::AuxElement&,
const std::string&)>;
30 constexpr std::string_view s_prefix{
"GlobalSim::"};
37 const std::set<std::string>& registeredSpecs() {
38 static const std::set<std::string>
specs = [] {
39 std::set<std::string>
found;
40 const TEnv* mapfile = gInterpreter->GetMapfile();
41 if (mapfile ==
nullptr or mapfile->GetTable() ==
nullptr) {
return found; }
43 for (
const TObject* record : *mapfile->GetTable()) {
44 const std::string_view
cls{record->GetName()};
45 if (not
cls.starts_with(s_prefix)) {
continue; }
46 const std::string_view
name =
cls.substr(s_prefix.size());
47 if (
name.empty() or
name.front() ==
'_' or
48 name.find(
'<') != std::string_view::npos) {
continue; }
50 if(
auto tcls = TClass::GetClass(
cls.data()); tcls && (tcls->Property()&kIsNamespace)) {
66 std::shared_ptr<T> interpret(
const std::string& code, std::string& error) {
67 TInterpreter::EErrorCode
err = TInterpreter::kNoError;
68 const Longptr_t address = gInterpreter->ProcessLine(
code.c_str(), &err);
69 if (address == 0 or err != TInterpreter::kNoError) {
70 error =
"the interpreter would not compile:\n" +
code;
73 return std::shared_ptr<T>(
reinterpret_cast<T*
>(address));
80 bool prepareInterpreter(
const std::string& spec, std::string& error) {
81 if (TClass::GetClass(
spec.c_str()) ==
nullptr) {
82 error =
"no dictionary could be loaded for " +
spec;
85 static const bool declared =
86 gInterpreter->Declare(
"#include \"GlobalSimulation/Object.h\"");
88 error =
"the interpreter could not read GlobalSimulation/Object.h";
93 SpecEntry buildEntry(
const std::string& name, std::string& error) {
94 const std::string
spec =
"GlobalSim::" +
name;
95 const std::string
object =
"GlobalSim::Object<" +
spec +
">";
97 if (not prepareInterpreter(spec, error)) {
return {}; }
102 auto getter = interpret<BitsGetter>(
103 "new std::function<std::string(const SG::AuxElement&)>("
104 "[](const SG::AuxElement& tob) {"
105 " return " +
object +
"(tob).bits().to_string();"
107 if (not getter) {
return {}; }
109 auto setter = interpret<BitsSetter>(
110 "new std::function<void(SG::AuxElement&, const std::string&)>("
111 "[](SG::AuxElement& tob, const std::string& bits) {"
112 " " +
object +
" obj(tob);"
113 " obj = " + spec +
"::bitset_type(bits);"
115 if (not setter) {
return {}; }
117 auto width = interpret<std::size_t>(
"new std::size_t(" + spec +
"::width);",
119 if (not
width) {
return {}; }
128 [
s = std::move(setter)](
SG::AuxElement& tob,
const std::string& token) {
142 static std::mutex
mutex;
146 const auto cached = cache.find(name);
147 if (cached != cache.end()) {
return &cached->second; }
149 if (not registeredSpecs().
contains(name)) {
150 error =
"not listed in GlobalSimulation/selection.xml. Known specs are: "
156 if (entry.width == 0) {
return nullptr; }
158 return &cache.emplace(name, std::move(entry)).first->second;
163 for (
const auto& spec : registeredSpecs()) {
164 if (not names.empty()) { names +=
", "; }
168 return "none -- no GlobalSim classes found in the rootmap";
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
AlgTool to read in LArStripNeighborhoods, and run the BDT Algorithm.
const SpecEntry * specEntry(const std::string &name, std::string &error)
The entry for one spec, or nullptr if there is not one.
std::string hexStrToBinStr(std::string s)
std::string knownSpecNames()
Comma-separated list of the names in the dictionary, for error messages.
std::string binStrToHexStr(std::string_view s)
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.