ATLAS Offline Software
Loading...
Searching...
No Matches
AuxTypeRegistry.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
10
11
23#include <cassert>
24#include <sstream>
25#include <cstring>
26#include <algorithm>
27
28
29namespace SG {
30
31
45 : public AuxTypeRegistry
46{
47public:
54
55
62
63
66
67
93 findAuxID (const std::string& name,
94 const std::string& clsname,
95 const Flags flags,
97 const std::type_info& ti,
98 const std::type_info* ti_alloc,
99 const std::string* alloc_name,
100 std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const);
101
102
116 addFactory (lock_t& lock,
117 const std::type_info& ti,
118 const std::type_info& ti_alloc,
119 const IAuxTypeVectorFactory* factory);
120
121
135 addFactory (lock_t& /*lock*/,
136 const std::type_info& ti,
137 const std::string& ti_alloc_name,
138 std::unique_ptr<const IAuxTypeVectorFactory> factory);
139
140
148 static bool checkName (std::string_view s) noexcept;
149
150
162 const std::type_info& ti,
163 const std::type_info& ti_alloc);
164
165
168 {
170 AthContainers_detail::atomic<const IAuxTypeVectorFactory*> m_factory;
171
173 const std::type_info* m_ti;
174
176 const std::type_info* m_ti_alloc;
177
179 std::string m_alloc_name;
180
182 std::string m_name;
183
185 std::string m_clsname;
186
189
192
195 bool checkAlloc (const std::type_info* ti_alloc,
196 const std::string* alloc_name) const;
197 };
198
199
201 // A concurrent vector, so we don't need to take a lock to read it.
202 AthContainers_detail::concurrent_vector<typeinfo_t> m_types;
203
207
211
213 std::vector<const IAuxTypeVectorFactory*> m_oldFactories;
214
217 typedef std::unordered_map<std::string, std::string> renameMap_t;
219
220 // Map from the TI name for T to the TI for AuxAllocator_t<T>.
221 // Filled in by addFactory(). Used in findAuxID() if the allocator
222 // type is not specified.
225
227 // We originally used an upgrading mutex here.
228 // But that's relatively slow, and most of the locked sections are short,
229 // so it's not really a win.
230 // This guards write access to all members, and read access to all members
231 // except for m_types.
233};
234
235
242 : m_auxids (id_map_t::Updater_t()),
243 m_factories (ti_map_t::Updater_t()),
244 m_allocMap (allocMap_t::Updater_t())
245{
247
248 // Make sure we have factories registered for common C++ types.
249#define ADD_FACTORY(T) AuxTypeRegistry::addFactory(typeid(T), typeid(AuxAllocator_t<T>), std::make_unique<AuxTypeVectorFactory<T> >())
250 ADD_FACTORY (bool);
251 ADD_FACTORY (char);
252 ADD_FACTORY (unsigned char);
253 ADD_FACTORY (short);
254 ADD_FACTORY (unsigned short);
255 ADD_FACTORY (int);
256 ADD_FACTORY (unsigned int);
257 ADD_FACTORY (long);
258 ADD_FACTORY (unsigned long);
259 ADD_FACTORY (long long);
260 ADD_FACTORY (unsigned long long);
261 ADD_FACTORY (float);
262 ADD_FACTORY (double);
263 ADD_FACTORY (std::string);
264
265 ADD_FACTORY (std::vector<char>);
266 ADD_FACTORY (std::vector<unsigned char>);
267 ADD_FACTORY (std::vector<int>);
268 ADD_FACTORY (std::vector<unsigned int>);
269 ADD_FACTORY (std::vector<float>);
270 ADD_FACTORY (std::vector<double>);
271
285#undef ADD_FACTORY
286}
287
288
295{
296 // not using reference, because our iterator doesn't return a reference
297 for (auto p : m_factories) {
298 if (p.first.find (";TI;") == std::string::npos) {
299 delete p.second;
300 }
301 }
303 delete p;
304}
305
306
332AuxTypeRegistryImpl::findAuxID (const std::string& name,
333 const std::string& clsname,
334 const Flags flags,
336 const std::type_info& ti,
337 const std::type_info* ti_alloc,
338 const std::string* alloc_name,
339 std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const)
340{
341 // The extra test here is to avoid having to copy a string
342 // in the common case where clsname is blank.
343 const std::string& key = clsname.empty() ? name : makeKey (name, clsname);
344
345
346 // Fast path --- try without acquiring the lock.
347 {
348 id_map_t::const_iterator i = m_auxids.find (key);
349 if (i != m_auxids.end()) {
350 typeinfo_t& m = m_types[i->second];
351 if (!(CxxUtils::test (m.m_flags, Flags::Atomic) &&
352 !CxxUtils::test (flags, Flags::Atomic)) &&
353 (CxxUtils::test (m.m_flags, Flags::Linked) == CxxUtils::test (flags, Flags::Linked)) &&
354 (linkedVariable == m.m_linked) &&
355 (&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
356 m.checkAlloc (ti_alloc, alloc_name) &&
357 !(*m.m_factory).isDynamic())
358 {
359 return i->second;
360 }
361 }
362 }
363
364 // Something went wrong. Acquire the lock and try again.
365 lock_t lock (m_mutex);
366 id_map_t::const_iterator i = m_auxids.find (key);
367 if (i != m_auxids.end()) {
368 typeinfo_t& m = m_types[i->second];
369
370 if ((CxxUtils::test (m.m_flags, Flags::Atomic) &&
371 !CxxUtils::test (flags, Flags::Atomic)) ||
372 (CxxUtils::test (m.m_flags, Flags::Linked) != CxxUtils::test (flags, Flags::Linked)))
373 {
374 throw SG::ExcFlagMismatch (i->second, ti, m.m_flags, flags);
375 }
376
377 if (linkedVariable != m.m_linked)
378 {
379 throw SG::ExcLinkMismatch (i->second, ti, m.m_linked, linkedVariable);
380 }
381
382 // By all rights, these two tests should be redundant.
383 // However, there are cases where we see distinct @c type_info objects
384 // for the same type. This is usually associated with dictionaries
385 // being loaded `too early,' during python configuration processing.
386 // It's a C++ standard violation for this to ever happen, but it's
387 // not clear that it's feasible to actually eliminate the possibility
388 // of this happening. So if the @c type_info instances differ,
389 // we still accept the match as long as the names are the same.
390 if ((&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
391 m.checkAlloc (ti_alloc, alloc_name))
392 {
393 // Try to upgrade a dynamic factory.
394 if ((*m.m_factory).isDynamic()) {
395 std::unique_ptr<IAuxTypeVectorFactory> fac2 = (*this.*makeFactory)();
396 if (fac2) {
397 if (!ti_alloc) {
398 ti_alloc = fac2->tiAlloc();
399 }
400 std::string allocName = fac2->tiAllocName();
401 m.m_factory = addFactory (lock, ti, allocName, std::move (fac2));
402 if (ti_alloc) {
403 m.m_factory = addFactory (lock, ti, *ti_alloc, m.m_factory);
404 }
405 }
406 }
407 return i->second;
408 }
409 if( *m.m_ti != typeid(SG::AuxTypePlaceholder) ) {
410 throw SG::ExcAuxTypeMismatch (i->second, ti, *m.m_ti,
411 ti_alloc ? SG::normalizedTypeinfoName (*ti_alloc) : (alloc_name ? *alloc_name : ""),
412 m.m_alloc_name);
413 }
414 // fall through, get a new auxid and real type info
415 // new auxid needed so a new data vector is created in the AuxStore
416 }
417
418 // Verify now that the variable names are ok.
419 if (!(flags & Flags::SkipNameCheck) &&
420 (!checkName (name) ||
421 (!clsname.empty() && !checkName (clsname))))
422 {
423 throw ExcBadVarName (key);
424 }
425
426 const IAuxTypeVectorFactory* fac = nullptr;
427 if (ti_alloc) {
428 fac = getFactory (lock, ti, *ti_alloc);
430 else if (alloc_name) {
431 fac = getFactory (ti, *alloc_name);
432 }
433 else {
434 std::string def_alloc_name = SG::auxAllocatorNamePrefix + SG::normalizedTypeinfoName (ti);
435 if (def_alloc_name[def_alloc_name.size()-1] == '>') def_alloc_name += ' ';
436 def_alloc_name += '>';
437 fac = getFactory (ti,def_alloc_name);
438 }
439
440 if (!fac || fac->isDynamic()) {
441 std::unique_ptr<IAuxTypeVectorFactory> fac2 = (*this.*makeFactory)();
442 if (fac2) {
443 if (!ti_alloc) {
444 ti_alloc = fac2->tiAlloc();
445 }
446 std::string allocName = fac2->tiAllocName();
447 fac = addFactory (lock, ti, allocName, std::move (fac2));
448 if (ti_alloc) {
449 fac = addFactory (lock, ti, *ti_alloc, fac);
450 }
451 }
453 if (!fac) return null_auxid;
454 if (!ti_alloc) ti_alloc = fac->tiAlloc();
455 SG::auxid_t auxid = m_types.size();
456 m_types.resize (auxid+1);
457 typeinfo_t& t = m_types[auxid];
458 t.m_name = name;
459 t.m_clsname = clsname;
460 t.m_ti = &ti;
461 t.m_ti_alloc = ti_alloc;
462 t.m_alloc_name = fac->tiAllocName();
463 t.m_factory = fac;
464 t.m_flags = (flags & ~Flags::SkipNameCheck);
465 t.m_linked = linkedVariable;
467 if (!isLinked (linkedVariable)) std::abort();
468 }
470 m_auxids.insert_or_assign (key, auxid);
471
472 return auxid;
473}
474
475
484 * an element type of @c ti. If a mapping already exists, the new
485 * factory is discarded, unless the old one is a dynamic factory and
486 * the new one isn't, in which case the new replaces the old one.
487 */
490 const std::type_info& ti,
491 const std::type_info& ti_alloc,
492 const IAuxTypeVectorFactory* factory)
493{
494 std::string key = std::string (ti.name()) + ";TI;" + ti_alloc.name();
495 ti_map_t::const_iterator it = m_factories.find (key);
496 if (it != m_factories.end()) {
497 if (it->second->isDynamic() && !factory->isDynamic()) {
498 // Replacing a dynamic factory with a non-dynamic one.
499 // The string version should put it to m_oldFactories.
500 m_factories.insert_or_assign (key, factory);
501 }
502 else {
503 factory = it->second;
504 }
505 }
506 else
507 m_factories.insert_or_assign (key, factory);
508
509 if (SG::normalizedTypeinfoName (ti_alloc).starts_with(
511 {
512 m_allocMap.insert_or_assign (ti.name(), &ti_alloc);
513 }
514
515 return factory;
516}
517
518
533 const std::type_info& ti,
534 const std::string& ti_alloc_name,
535 std::unique_ptr<const IAuxTypeVectorFactory> factory)
536{
537 std::string key = ti.name();
538 key += ';';
539 key += ti_alloc_name;
540 ti_map_t::const_iterator it = m_factories.find (key);
541 const IAuxTypeVectorFactory* fac = factory.get();
542 if (it != m_factories.end()) {
543 if (it->second->isDynamic() && !factory->isDynamic()) {
544 // Replacing a dynamic factory with a non-dynamic one.
545 // But don't delete the old one, since it might still be referenced.
546 // Instead, push it on a vector to remember it so we can delete
547 // it later.
548 m_oldFactories.push_back (it->second);
549 fac = m_factories.insert_or_assign (key, factory.release()).first->second;
550 }
551 else {
552 fac = it->second;
553 }
554 }
555 else
556 fac = m_factories.insert_or_assign (key, factory.release()).first->second;
557
558 return fac;
559}
560
561
569bool AuxTypeRegistryImpl::checkName (std::string_view s) noexcept
570{
571 if (s.empty()) return false;
572 char first = s[0];
573 if (!std::isalpha(static_cast<unsigned char>(first)) && first != '_') return false;
574 return std::all_of(s.begin() + 1, s.end(), [](char c) {
575 return std::isalnum(static_cast<unsigned char>(c)) || c == '_';
576 });
577}
578
579
592 const std::type_info& ti,
593 const std::type_info& ti_alloc)
594{
595 std::string key = ti.name();
596 key += ";TI;";
597 key += ti_alloc.name();
598 ti_map_t::const_iterator it = m_factories.find (key);
599 if (it != m_factories.end())
600 return it->second;
601
602 std::string name = SG::normalizedTypeinfoName (ti_alloc);
603 const IAuxTypeVectorFactory* fac = getFactory (ti, name);
604 if (fac) {
605 // We only really need to be holding the lock here, but doing things
606 // otherwise would require some code duplication.
607 addFactory (lock, ti, ti_alloc, fac);
608 }
609 return fac;
610}
611
612
617bool AuxTypeRegistryImpl::typeinfo_t::checkAlloc (const std::type_info* ti_alloc,
618 const std::string* alloc_name) const
619{
620 if (ti_alloc && m_ti_alloc) {
621 if (ti_alloc == m_ti_alloc) return true;
622 return strcmp (ti_alloc->name(), m_ti_alloc->name()) == 0;
623 }
624 if (alloc_name) {
625 return *alloc_name == m_alloc_name;
626 }
627 if (ti_alloc) {
628 return SG::normalizedTypeinfoName (*ti_alloc) == m_alloc_name;
629 }
630 return true;
631}
632
633
634//***************************************************************************
635
636
641{
642 static AuxTypeRegistryImpl auxTypeRegistry ATLAS_THREAD_SAFE;
643 return auxTypeRegistry;
644}
645
646
653{
654 auto* impl = static_cast<const AuxTypeRegistryImpl*> (this);
655 return impl->m_types.size();
656}
657
658
673SG::auxid_t AuxTypeRegistry::getAuxID (const std::type_info& ti,
674 const std::string& name,
675 const std::string& clsname /*= ""*/,
676 const Flags flags /*= Flags::None*/,
677 const SG::auxid_t linkedVariable /*= SG::null_auxid*/)
678{
679 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
680 return impl->findAuxID (name, clsname, flags, linkedVariable,
681 ti, nullptr, nullptr,
683}
684
685
703SG::auxid_t AuxTypeRegistry::getAuxID (const std::type_info& ti_alloc,
704 const std::type_info& ti,
705 const std::string& name,
706 const std::string& clsname /*= ""*/,
707 const Flags flags /*= Flags::None*/,
708 const SG::auxid_t linkedVariable /*= SG::null_auxid*/,
709 std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const /*= &AuxTypeRegistry::makeFactoryNull*/)
710{
711 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
712 return impl->findAuxID (name, clsname, flags, linkedVariable,
713 ti, &ti_alloc, nullptr,
715}
716
717
733SG::auxid_t AuxTypeRegistry::getAuxID (const std::string& alloc_type,
734 const std::type_info& ti,
735 const std::string& name,
736 const std::string& clsname /*= ""*/,
737 const Flags flags /*= Flags::None*/,
738 const SG::auxid_t linkedVariable /*= SG::null_auxid*/)
739{
740 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
741 return impl->findAuxID (name, clsname, flags, linkedVariable,
742 ti, nullptr, &alloc_type,
744}
745
746
757AuxTypeRegistry::findAuxID (const std::string& name,
758 const std::string& clsname) const
759{
760 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
761
762 // No locking needed here.
763 // The extra test here is to avoid having to copy a string
764 // in the common case where clsname is blank.
765 AuxTypeRegistryImpl::id_map_t::const_iterator i =
766 impl->m_auxids.find (clsname.empty() ?
767 name :
768 makeKey (name, clsname));
769 if (i != impl->m_auxids.end()) {
770 return i->second;
771 }
772 return null_auxid;
773}
774
775
788 const std::type_info& ti,
789 const std::type_info& ti_alloc,
790 const Flags flags)
791{
792 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
793 AuxTypeRegistryImpl::typeinfo_t& m = impl->m_types.at (auxid);
794
795 if ( ! ((&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
796 m.checkAlloc (&ti_alloc, nullptr)))
797 {
798 throw SG::ExcAuxTypeMismatch (auxid, ti, *m.m_ti,
800 m.m_alloc_name);
801 }
802 if ((CxxUtils::test (m.m_flags, Flags::Atomic) &&
803 !CxxUtils::test (flags, Flags::Atomic)) ||
804 (CxxUtils::test (m.m_flags, Flags::Linked) != CxxUtils::test (flags, Flags::Linked)))
805 {
806 throw SG::ExcFlagMismatch (auxid, ti, m.m_flags, flags);
807 }
808}
809
810
817std::unique_ptr<IAuxTypeVector>
819 size_t size,
820 size_t capacity) const
821{
822 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
823 assert (factory != 0);
824 return factory->create (auxid, size, capacity, isLinked (auxid));
825}
826
827
845std::unique_ptr<IAuxTypeVector>
847 void* data,
848 IAuxTypeVector* linkedVector,
849 bool isPacked,
850 bool ownMode) const
851{
852 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
853 assert (factory != 0);
854 return factory->createFromData (auxid, data, linkedVector,
855 isPacked, ownMode, isLinked (auxid));
856}
857
858
864std::string AuxTypeRegistry::makeKey (const std::string& name,
865 const std::string& clsname)
866{
867 if (clsname.empty()) {
868 return name;
869 }
870 std::string output = clsname;
871 output += "::";
872 output += name;
873 return output;
874}
875
876
877
882std::string AuxTypeRegistry::getName (SG::auxid_t auxid) const
883{
884 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
885 if (auxid >= impl->m_types.size())
886 return "";
887 return impl->m_types[auxid].m_name;
888}
889
890
897{
898 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
899 if (auxid >= impl->m_types.size())
900 return "";
901 return impl->m_types[auxid].m_clsname;
902}
903
904
909const std::type_info* AuxTypeRegistry::getType (SG::auxid_t auxid) const
910{
911 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
912 if (auxid >= impl->m_types.size())
913 return 0;
914 return impl->m_types[auxid].m_ti;
915}
916
917
925{
926 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
927 if (auxid >= impl->m_types.size())
928 return "";
929 return normalizedTypeinfoName (*impl->m_types[auxid].m_ti);
930}
931
932
937const std::type_info* AuxTypeRegistry::getVecType (SG::auxid_t auxid) const
938{
939 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
940 if (factory)
941 return factory->tiVec();
942 return 0;
943}
944
945
953{
954 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
955 if (factory)
956 return normalizedTypeinfoName (*factory->tiVec());
957 return "";
958}
959
960
965const std::type_info* AuxTypeRegistry::getAllocType (SG::auxid_t auxid) const
966{
967 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
968 if (auxid >= impl->m_types.size())
969 return 0;
970 return impl->m_types[auxid].m_ti_alloc;
971}
972
973
979{
980 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
981 if (factory)
982 return factory->getEltSize();
983 return 0;
984}
985
986
992{
993 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
994 if (auxid >= impl->m_types.size())
995 return Flags::None;
996 return impl->m_types[auxid].m_flags;
997}
998
999
1008{
1009 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1010 if (auxid >= impl->m_types.size())
1011 return null_auxid;
1012 return impl->m_types[auxid].m_linked;
1013}
1014
1015
1028 AuxVectorData& dst, size_t dst_index,
1029 const AuxVectorData& src, size_t src_index,
1030 size_t n) const
1031{
1032 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1033 if (factory)
1034 factory->copy (auxid, dst, dst_index, src, src_index, n);
1035}
1036
1037
1051 AuxVectorData& dst, size_t dst_index,
1052 const AuxVectorData& src, size_t src_index,
1053 size_t n) const
1054{
1055 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1056 if (factory) {
1057 factory->copyForOutput (auxid, dst, dst_index, src, src_index, n);
1058 }
1059}
1060
1061
1075 AuxVectorData& a, size_t aindex,
1076 AuxVectorData& b, size_t bindex,
1077 size_t n) const
1078{
1079 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1080 if (factory)
1081 factory->swap (auxid, a, aindex, b, bindex, n);
1082}
1083
1084
1093 AuxVectorData& dst, size_t dst_index,
1094 size_t n) const
1095{
1096 const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1097 if (factory)
1098 factory->clear (auxid, dst, dst_index, n);
1099}
1100
1101
1111AuxTypeRegistry::getFactory (const std::type_info& ti,
1112 const std::type_info& ti_alloc)
1113{
1114 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1115 lock_t lock (impl->m_mutex);
1116 return impl->getFactory (lock, ti, ti_alloc);
1117}
1118
1119
1129{
1130 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1131 if (auxid >= impl->m_types.size())
1132 return 0;
1133 return impl->m_types[auxid].m_factory;
1134}
1135
1136
1146AuxTypeRegistry::getFactory (const std::type_info& ti,
1147 const std::string& alloc_name)
1148{
1149 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1150
1151 std::string key = std::string (ti.name()) + ";" + alloc_name;
1152 AuxTypeRegistryImpl::ti_map_t::const_iterator it = impl->m_factories.find (key);
1153 if (it != impl->m_factories.end()) {
1154 return it->second;
1155 }
1156
1157 return nullptr;
1158}
1159
1160
1173AuxTypeRegistry::addFactory (const std::type_info& ti,
1174 const std::type_info& ti_alloc,
1175 std::unique_ptr<const IAuxTypeVectorFactory> factory)
1176{
1177 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1178 lock_t lock (impl->m_mutex);
1179 std::string name = SG::normalizedTypeinfoName (ti_alloc);
1180 const IAuxTypeVectorFactory* fac =
1181 impl->addFactory (lock, ti, name, std::move(factory));
1182 return impl->addFactory (lock, ti, ti_alloc, fac);
1183}
1184
1185
1198AuxTypeRegistry::addFactory (const std::type_info& ti,
1199 const std::string& ti_alloc_name,
1200 std::unique_ptr<const IAuxTypeVectorFactory> factory)
1201{
1202 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1203 lock_t lock (impl->m_mutex);
1204 return impl->addFactory (lock, ti, ti_alloc_name, std::move (factory));
1205}
1206
1207
1216
1217
1224
1225
1226#ifndef XAOD_STANDALONE
1237void
1239 const IStringPool& pool)
1240{
1241 auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1242
1243 lock_t lock (impl->m_mutex);
1244 impl->m_renameMap.clear();
1245 if (!map) return;
1246 for (const auto& p : *map) {
1247 sgkey_t from_sgkey = p.first;
1248 sgkey_t to_sgkey = p.second.m_sgkey;
1249
1250 const std::string* from_str = pool.keyToString (from_sgkey);
1251 if (!from_str) continue;
1252 std::string::size_type from_dpos = from_str->find ('.');
1253 if (from_dpos == std::string::npos || from_dpos == from_str->size()-1) continue;
1254
1255 const std::string* to_str = pool.keyToString (to_sgkey);
1256 if (!to_str) continue;
1257 std::string::size_type to_dpos = to_str->find ('.');
1258 if (to_dpos == std::string::npos || to_dpos == to_str->size()-1) continue;
1259
1260 impl->m_renameMap[*from_str] = to_str->substr (to_dpos+1, std::string::npos);
1261 }
1262}
1263#endif
1264
1265
1274const std::string& AuxTypeRegistry::inputRename (const std::string& key,
1275 const std::string& name) const
1276{
1277 auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1278 lock_t lock (impl->m_mutex);
1279 if (impl->m_renameMap.empty())
1280 return name;
1281
1282 std::string fullkey = key + "." + name;
1283 auto it = impl->m_renameMap.find (fullkey);
1284 if (it != impl->m_renameMap.end())
1285 return it->second;
1286 return name;
1287}
1288
1289
1293bool AuxTypeRegistry::isLinkedName (const std::string& name)
1294{
1295 return name.ends_with ("_linked");
1296}
1297
1298
1303std::string AuxTypeRegistry::linkedName (const std::string& name)
1304{
1305 return name + "_linked";
1306}
1307
1308
1313bool AuxTypeRegistry::classNameHasLink (const std::string& className)
1314{
1315 if (className.find ("SG::JaggedVecElt<") != std::string::npos) {
1316 return true;
1317 }
1318 if (className.find ("SG::PackedLink<") != std::string::npos) {
1319 return true;
1320 }
1321 return false;
1322}
1323
1324
1325} // namespace SG
1326
1327
#define ADD_FACTORY(T)
Handle mappings between names and auxid_t.
Implementation of IAuxTypeVector for specific types.
Hash map from strings allowing concurrent, lockless reads.
Auxiliary variable type allowing storage as a jagged vector. That is, the payloads for all the DataVe...
Exceptions that can be thrown from AthContainers.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t a
Simple (non-deleting) Updater implementation.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Hash map from strings allowing concurrent, lockless reads.
std::pair< const_iterator, bool > insert_or_assign(const key_type &key, mapped_type val, const Context_t &ctx=Updater_t::defaultContext())
Add an element to the map, or overwrite an existing one.
Abstract interface for looking up strings/CLIDs in a pool.
Definition IStringPool.h:28
Used as type_info when we read an aux data item but it doesn't exist in the registry.
Definition AuxTypes.h:34
mutex_t m_mutex
Mutex controlling access to the registry.
std::vector< const IAuxTypeVectorFactory * > m_oldFactories
Hold additional factory instances we need to delete.
AthContainers_detail::concurrent_vector< typeinfo_t > m_types
Table of aux data items, indexed by auxid.
CxxUtils::ConcurrentStrMap< const std::type_info *, CxxUtils::SimpleUpdater > allocMap_t
static bool checkName(std::string_view s) noexcept
Check for valid variable name.
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname, const Flags flags, const SG::auxid_t linkedVariable, const std::type_info &ti, const std::type_info *ti_alloc, const std::string *alloc_name, std::unique_ptr< IAuxTypeVectorFactory >(AuxTypeRegistry::*makeFactory)() const)
Look up a name -> auxid_t mapping.
std::unordered_map< std::string, std::string > renameMap_t
Save the information provided by setInputRenameMap.
CxxUtils::ConcurrentStrMap< const IAuxTypeVectorFactory *, CxxUtils::SimpleUpdater > ti_map_t
Map from type_info name + allocator ti name -> IAuxTypeVectorFactory.
CxxUtils::ConcurrentStrMap< SG::auxid_t, CxxUtils::SimpleUpdater > id_map_t
Map from name -> auxid.
const IAuxTypeVectorFactory * getFactory(lock_t &lock, const std::type_info &ti, const std::type_info &ti_alloc)
Return the vector factory for a given vector element type.
const IAuxTypeVectorFactory * addFactory(lock_t &lock, const std::type_info &ti, const std::type_info &ti_alloc, const IAuxTypeVectorFactory *factory)
Add a new type -> factory mapping.
Flags getFlags(SG::auxid_t auxid) const
Return flags associated with an auxiliary variable.
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
SG::auxid_t getAuxID(const std::string &name, const std::string &clsname="", const Flags flags=Flags::None, const SG::auxid_t linkedVariable=SG::null_auxid)
Look up a name -> auxid_t mapping.
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
size_t getEltSize(SG::auxid_t auxid) const
Return size of an element in the STL vector.
std::unique_ptr< IAuxTypeVector > makeVectorFromData(SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag) const
Construct an IAuxTypeVector object from a vector.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
const std::string & inputRename(const std::string &key, const std::string &name) const
Check for an input renaming of an auxiliary variable.
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
static std::string linkedName(const std::string &name)
Given a variable name, return the name of the corresponding linked variable.
friend class AuxTypeRegistryImpl
AuxTypeRegistry()
Constructor.
const std::type_info * getAllocType(SG::auxid_t auxid) const
Return the type of the vector allocator.
void checkAuxID(const SG::auxid_t auxid, const Flags flags=Flags::None)
Verify type for an aux variable.
void clear(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n) const
Clear a range of elements within a vector.
std::unique_ptr< IAuxTypeVectorFactory > makeFactoryNull() const
makeFactory implementation that always returns nullptr.
void setInputRenameMap(const Athena::InputRenameMap_t *map, const IStringPool &pool)
Declare input renaming requests.
AthContainers_detail::mutex mutex_t
const IAuxTypeVectorFactory * getFactory(const std::type_info &ti, const std::type_info &ti_alloc)
Return the vector factory for a given vector element type.
std::string getVecTypeName(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
size_t numVariables() const
Return the total number of registered auxiliary variable.
SG::auxid_t linkedVariable(SG::auxid_t auxid) const
Return the auxid if the linked variable, if there is one.
static bool classNameHasLink(const std::string &className)
Test to see if a class name corresponds to a class with a linked variable.
void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
Copy elements between vectors.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
const IAuxTypeVectorFactory * addFactory(const std::type_info &ti, const std::type_info &ti_alloc, std::unique_ptr< const IAuxTypeVectorFactory > factory)
Add a new type -> factory mapping.
std::unique_ptr< IAuxTypeVectorFactory > makeFactory() const
Create an AuxTypeVectorFactory instance.
AthContainers_detail::lock_guard< mutex_t > lock_t
SG::AuxVarFlags Flags
Additional flags to qualify an auxiliary variable.
void swap(SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const
Swap elements between vectors.
void copyForOutput(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
Copy elements between vectors.
std::unique_ptr< IAuxTypeVector > makeVector(SG::auxid_t auxid, size_t size, size_t capacity) const
Construct a new vector to hold an aux item.
std::string getClassName(SG::auxid_t auxid) const
Return the class name associated with an aux data item (may be blank).
bool isLinked(SG::auxid_t auxid) const
Test whether this is a linked variable.
static std::string makeKey(const std::string &name, const std::string &clsname)
Return the key used to look up an entry in m_auxids.
Manage lookup of vectors of auxiliary data.
Exception — Type mismatch for aux variable.
Exception — Bad name for auxiliary variable.
Exception — Flag mismatch for aux variable.
Exception — Linked variable mismatch.
Interface for factory objects that create vectors.
virtual std::unique_ptr< IAuxTypeVector > create(SG::auxid_t auxid, size_t size, size_t capacity, bool isLinked) const =0
Create a vector object of this type.
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
virtual void clear(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n) const =0
Clear a range of elements within a vector.
virtual void copyForOutput(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors, possibly applying thinning.
virtual const std::type_info * tiVec() const =0
Return the type_info of the vector.
virtual size_t getEltSize() const =0
Return the size of an element of this vector type.
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors.
virtual std::unique_ptr< IAuxTypeVector > createFromData(SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag, bool isLinked) const =0
Create a vector object of this type from a data blob.
virtual bool isDynamic() const =0
True if the vectors created by this factory work by dynamic emulation (via TVirtualCollectionProxy or...
virtual std::string tiAllocName() const =0
Return the (demangled) name of the vector allocator.
virtual void swap(SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const =0
Swap elements between vectors.
Abstract interface for manipulating vectors of arbitrary types.
Describe one element of a jagged vector.
STL class.
Helper for emitting error messages.
void fence_seq_cst()
A sequentially-consistent fence.
SG::SGKeyMap< InputRenameEntry > InputRenameMap_t
constexpr std::enable_if_t< is_bitmask_v< E >, bool > test(E lhs, E rhs)
Convenience function to test bits in a class enum bitmask.
Definition bitmask.h:270
Forward declaration.
constexpr const char * auxAllocatorNamePrefix
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition AuxTypes.h:58
@ SkipNameCheck
Definition AuxTypes.h:81
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
static const auxid_t auxid_set_size_hint
A hint for how large we should make the auxid bitsets.
Definition AuxTypes.h:40
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
Framework include files.
Definition libname.h:15
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Hold information about one aux data item.
std::string m_clsname
Class name associated with this aux data item. May be blank.
bool checkAlloc(const std::type_info *ti_alloc, const std::string *alloc_name) const
Check that the allocator type for this entry matches the requested type.
const std::type_info * m_ti_alloc
Type of the vector allocator. May be null for a dynamic type;.
AthContainers_detail::atomic< const IAuxTypeVectorFactory * > m_factory
Factory object.
const std::type_info * m_ti
Type of the aux data item.
std::string m_alloc_name
Name of the vector allocator.
auxid_t m_linked
auxid of a linked variable, or null_auxid.
Flags m_flags
Additional type flags.
Threading definitions.