ATLAS Offline Software
AuxTypeRegistry.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
21 #include "CxxUtils/SimpleUpdater.h"
23 #include <cassert>
24 #include <sstream>
25 #include <cstring>
26 #include <algorithm>
27 
28 
29 namespace SG {
30 
31 
45  : public AuxTypeRegistry
46 {
47 public:
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 
115  const IAuxTypeVectorFactory*
117  const std::type_info& ti,
118  const std::type_info& ti_alloc,
119  const IAuxTypeVectorFactory* factory);
120 
121 
134  const IAuxTypeVectorFactory*
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 
167  struct typeinfo_t
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 
205  using id_map_t = CxxUtils::ConcurrentStrMap<SG::auxid_t, CxxUtils::SimpleUpdater>;
207 
209  using ti_map_t = CxxUtils::ConcurrentStrMap<const IAuxTypeVectorFactory*, CxxUtils::SimpleUpdater>;
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.
223  using allocMap_t = CxxUtils::ConcurrentStrMap<const std::type_info*, CxxUtils::SimpleUpdater>;
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.
232  mutable mutex_t m_mutex;
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 {
246  m_types.reserve (auxid_set_size_hint);
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  }
302  for (const IAuxTypeVectorFactory* p : m_oldFactories)
303  delete p;
304 }
305 
306 
333  const std::string& clsname,
334  const Flags flags,
335  const SG::auxid_t linkedVariable,
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) &&
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) &&
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);
429  }
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  }
452  }
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;
466  if (linkedVariable != SG::null_auxid) {
467  if (!isLinked (linkedVariable)) std::abort();
468  }
470  m_auxids.insert_or_assign (key, auxid);
471 
472  return auxid;
473 }
474 
475 
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 
569 bool 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 
617 bool 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 
673 SG::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 
703 SG::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,
714  makeFactory);
715 }
716 
717 
733 SG::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 
757 AuxTypeRegistry::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,
799  SG::normalizedTypeinfoName (ti_alloc),
800  m.m_alloc_name);
801  }
802  if ((CxxUtils::test (m.m_flags, Flags::Atomic) &&
805  {
806  throw SG::ExcFlagMismatch (auxid, ti, m.m_flags, flags);
807  }
808 }
809 
810 
817 std::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 
845 std::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 
864 std::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 
882 std::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 
909 const 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 
924 std::string AuxTypeRegistry::getTypeName (SG::auxid_t auxid) const
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 
937 const 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 
965 const 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 
1110 const IAuxTypeVectorFactory*
1111 AuxTypeRegistry::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 
1127 const IAuxTypeVectorFactory*
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 
1145 const IAuxTypeVectorFactory*
1146 AuxTypeRegistry::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 
1172 const IAuxTypeVectorFactory*
1173 AuxTypeRegistry::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 
1197 const IAuxTypeVectorFactory*
1198 AuxTypeRegistry::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 
1214 {
1215 }
1216 
1217 
1222 {
1223 }
1224 
1225 
1226 #ifndef XAOD_STANDALONE
1227 
1237 void
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 
1274 const 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 
1293 bool AuxTypeRegistry::isLinkedName (const std::string& name)
1294 {
1295  return name.ends_with ("_linked");
1296 }
1297 
1298 
1303 std::string AuxTypeRegistry::linkedName (const std::string& name)
1304 {
1305  return name + "_linked";
1306 }
1307 
1308 
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 
SG::AuxTypeRegistry::getFactory
const IAuxTypeVectorFactory * getFactory(const std::type_info &ti, const std::type_info &ti_alloc)
Return the vector factory for a given vector element type.
Definition: AuxTypeRegistry.cxx:1111
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
IStringPool
Abstract interface for looking up strings/CLIDs in a pool.
Definition: IStringPool.h:28
SG::IAuxTypeVectorFactory::createFromData
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.
SG::AuxTypeRegistry::makeVectorFromData
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.
Definition: AuxTypeRegistry.cxx:846
SG::AuxTypeRegistry::addFactory
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.
Definition: AuxTypeRegistry.cxx:1173
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::SkipNameCheck
@ SkipNameCheck
Definition: AuxTypes.h:81
SG::IAuxTypeVectorFactory::getEltSize
virtual size_t getEltSize() const =0
Return the size of an element of this vector type.
SG::AuxTypeRegistryImpl::typeinfo_t::m_factory
AthContainers_detail::atomic< const IAuxTypeVectorFactory * > m_factory
Factory object.
Definition: AuxTypeRegistry.cxx:170
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:640
SG::AuxTypeRegistryImpl::renameMap_t
std::unordered_map< std::string, std::string > renameMap_t
Save the information provided by setInputRenameMap.
Definition: AuxTypeRegistry.cxx:217
SG::AuxTypeRegistryImpl::~AuxTypeRegistryImpl
~AuxTypeRegistryImpl()
Destructor.
Definition: AuxTypeRegistry.cxx:294
SG::AuxTypeRegistry::findAuxID
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
Definition: AuxTypeRegistry.cxx:757
WriteCellNoiseToCool.src
src
Definition: WriteCellNoiseToCool.py:513
SG::normalizedTypeinfoName
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...
Definition: normalizedTypeinfoName.cxx:120
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
SG::AuxTypeRegistry::lock_t
AthContainers_detail::lock_guard< mutex_t > lock_t
Definition: AuxTypeRegistry.h:541
SG::AuxTypeRegistry::makeKey
static std::string makeKey(const std::string &name, const std::string &clsname)
Return the key used to look up an entry in m_auxids.
Definition: AuxTypeRegistry.cxx:864
SG::IAuxTypeVectorFactory::create
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.
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:882
SG::AuxTypeRegistry::getVecTypeName
std::string getVecTypeName(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
Definition: AuxTypeRegistry.cxx:952
pool
pool namespace
Definition: libname.h:15
exceptions.h
Exceptions that can be thrown from AthContainers.
ConcurrentStrMap.h
Hash map from strings allowing concurrent, lockless reads.
skel.it
it
Definition: skel.GENtoEVGEN.py:407
SG::IAuxTypeVectorFactory::clear
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.
SG::AuxTypeRegistry::inputRename
const std::string & inputRename(const std::string &key, const std::string &name) const
Check for an input renaming of an auxiliary variable.
Definition: AuxTypeRegistry.cxx:1274
SG::AuxTypeRegistryImpl::ti_map_t
CxxUtils::ConcurrentStrMap< const IAuxTypeVectorFactory *, CxxUtils::SimpleUpdater > ti_map_t
Map from type_info name + allocator ti name -> IAuxTypeVectorFactory.
Definition: AuxTypeRegistry.cxx:209
SG::AuxTypeRegistry::getAllocType
const std::type_info * getAllocType(SG::auxid_t auxid) const
Return the type of the vector allocator.
Definition: AuxTypeRegistry.cxx:965
SG::AuxTypeRegistryImpl::allocMap_t
CxxUtils::ConcurrentStrMap< const std::type_info *, CxxUtils::SimpleUpdater > allocMap_t
Definition: AuxTypeRegistry.cxx:223
ADD_FACTORY
#define ADD_FACTORY(T)
SG::AuxTypeRegistry::linkedName
static std::string linkedName(const std::string &name)
Given a variable name, return the name of the corresponding linked variable.
Definition: AuxTypeRegistry.cxx:1303
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
SG::AuxTypeRegistryImpl::m_allocMap
allocMap_t m_allocMap
Definition: AuxTypeRegistry.cxx:224
SG::AuxTypeRegistry::classNameHasLink
static bool classNameHasLink(const std::string &className)
Test to see if a class name corresponds to a class with a linked variable.
Definition: AuxTypeRegistry.cxx:1313
SG::AuxTypeRegistry::AuxTypeRegistry
AuxTypeRegistry()
Constructor.
Definition: AuxTypeRegistry.cxx:1213
SG::AuxTypeRegistry::copyForOutput
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.
Definition: AuxTypeRegistry.cxx:1050
AthContainers_detail::fence_seq_cst
void fence_seq_cst()
A sequentially-consistent fence.
SG::AuxTypeRegistry::~AuxTypeRegistry
~AuxTypeRegistry()
Destructor.
Definition: AuxTypeRegistry.cxx:1221
concurrent_vector.h
SG::IAuxTypeVectorFactory::tiAllocName
virtual std::string tiAllocName() const =0
Return the (demangled) name of the vector allocator.
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
SG::AuxTypeRegistryImpl::checkName
static bool checkName(std::string_view s) noexcept
Check for valid variable name.
Definition: AuxTypeRegistry.cxx:569
SG::IAuxTypeVectorFactory::swap
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.
SG::AuxTypeRegistry::mutex_t
AthContainers_detail::mutex mutex_t
Definition: AuxTypeRegistry.h:540
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
SG::Linked
@ Linked
Mark that this variable is linked to another one.
Definition: AuxTypes.h:77
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::AuxTypeRegistry::getType
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
Definition: AuxTypeRegistry.cxx:909
SG::AuxTypeRegistryImpl::m_mutex
mutex_t m_mutex
Mutex controlling access to the registry.
Definition: AuxTypeRegistry.cxx:232
SG::AuxTypeRegistryImpl
@Brief Implementation class for AuxTypeRegistry.
Definition: AuxTypeRegistry.cxx:46
CaloCellPos2Ntuple.None
None
Definition: CaloCellPos2Ntuple.py:23
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
SG::AuxTypeRegistry::swap
void swap(SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const
Swap elements between vectors.
Definition: AuxTypeRegistry.cxx:1074
Athena::InputRenameMap_t
SG::SGKeyMap< InputRenameEntry > InputRenameMap_t
Definition: InputRenameMap.h:32
SG::AuxTypeRegistry::getTypeName
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
Definition: AuxTypeRegistry.cxx:924
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::AuxTypeRegistryImpl::addFactory
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.
Definition: AuxTypeRegistry.cxx:489
beamspotman.n
n
Definition: beamspotman.py:727
SG::AuxTypeRegistry::getFlags
Flags getFlags(SG::auxid_t auxid) const
Return flags associated with an auxiliary variable.
Definition: AuxTypeRegistry.cxx:991
SG::AuxTypeRegistryImpl::m_types
AthContainers_detail::concurrent_vector< typeinfo_t > m_types
Table of aux data items, indexed by auxid.
Definition: AuxTypeRegistry.cxx:202
SG::IAuxTypeVectorFactory
Interface for factory objects that create vectors.
Definition: IAuxTypeVectorFactory.h:50
SG::IAuxTypeVectorFactory::copyForOutput
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.
SG::IAuxTypeVectorFactory::tiAlloc
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
SG::AuxTypeRegistry::linkedVariable
SG::auxid_t linkedVariable(SG::auxid_t auxid) const
Return the auxid if the linked variable, if there is one.
Definition: AuxTypeRegistry.cxx:1007
SG::AuxTypeRegistry::getEltSize
size_t getEltSize(SG::auxid_t auxid) const
Return size of an element in the STL vector.
Definition: AuxTypeRegistry.cxx:978
SG::AuxTypeRegistry::makeFactory
std::unique_ptr< IAuxTypeVectorFactory > makeFactory() const
Create an AuxTypeVectorFactory instance.
error.h
Helper for emitting error messages.
SG::AuxTypePlaceholder
Used as type_info when we read an aux data item but it doesn't exist in the registry.
Definition: AuxTypes.h:34
SG::AuxTypeRegistry::isLinkedName
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
Definition: AuxTypeRegistry.cxx:1293
SG::AuxTypeRegistryImpl::typeinfo_t::m_alloc_name
std::string m_alloc_name
Name of the vector allocator.
Definition: AuxTypeRegistry.cxx:179
SG::IAuxTypeVectorFactory::copy
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.
SG::AuxTypeRegistry::getVecType
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
Definition: AuxTypeRegistry.cxx:937
SG::AuxTypeRegistry::numVariables
size_t numVariables() const
Return the total number of registered auxiliary variable.
Definition: AuxTypeRegistry.cxx:652
SG::AuxTypeRegistryImpl::typeinfo_t::checkAlloc
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.
Definition: AuxTypeRegistry.cxx:617
SG::AuxTypeRegistryImpl::typeinfo_t
Hold information about one aux data item.
Definition: AuxTypeRegistry.cxx:168
SG::AuxTypeRegistryImpl::typeinfo_t::m_clsname
std::string m_clsname
Class name associated with this aux data item. May be blank.
Definition: AuxTypeRegistry.cxx:185
SG::AuxVarFlags
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition: AuxTypes.h:58
SG::AuxTypeRegistry::clear
void clear(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n) const
Clear a range of elements within a vector.
Definition: AuxTypeRegistry.cxx:1092
SG::AuxTypeRegistryImpl::m_factories
ti_map_t m_factories
Definition: AuxTypeRegistry.cxx:210
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
SG::AuxTypeRegistry::getClassName
std::string getClassName(SG::auxid_t auxid) const
Return the class name associated with an aux data item (may be blank).
Definition: AuxTypeRegistry.cxx:896
SG::ExcFlagMismatch
Exception — Flag mismatch for aux variable.
Definition: Control/AthContainers/AthContainers/exceptions.h:376
AuxTypeVector.h
Implementation of IAuxTypeVector for specific types.
CxxUtils::test
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
SG::IAuxTypeVectorFactory::isDynamic
virtual bool isDynamic() const =0
True if the vectors created by this factory work by dynamic emulation (via TVirtualCollectionProxy or...
SG::AuxTypeRegistryImpl::typeinfo_t::m_ti_alloc
const std::type_info * m_ti_alloc
Type of the vector allocator. May be null for a dynamic type;.
Definition: AuxTypeRegistry.cxx:176
SG::AuxTypeRegistry::makeVector
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.
Definition: AuxTypeRegistry.cxx:818
SG::AuxTypeRegistryImpl::m_oldFactories
std::vector< const IAuxTypeVectorFactory * > m_oldFactories
Hold additional factory instances we need to delete.
Definition: AuxTypeRegistry.cxx:213
SG::AuxTypeRegistryImpl::findAuxID
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.
Definition: AuxTypeRegistry.cxx:332
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
SG::AuxTypeRegistry::isLinked
bool isLinked(SG::auxid_t auxid) const
Test whether this is a linked variable.
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
SG::AuxTypeRegistry::setInputRenameMap
void setInputRenameMap(const Athena::InputRenameMap_t *map, const IStringPool &pool)
Declare input renaming requests.
Definition: AuxTypeRegistry.cxx:1238
SG::AuxTypeRegistryImpl::typeinfo_t::m_linked
auxid_t m_linked
auxid of a linked variable, or null_auxid.
Definition: AuxTypeRegistry.cxx:188
SG::IAuxTypeVectorFactory::tiVec
virtual const std::type_info * tiVec() const =0
Return the type_info of the vector.
JaggedVec.h
Auxiliary variable type allowing storage as a jagged vector. That is, the payloads for all the DataVe...
SG::sgkey_t
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition: sgkey_t.h:32
SG::AuxTypeRegistry::checkAuxID
void checkAuxID(const SG::auxid_t auxid, const Flags flags=Flags::None)
Verify type for an aux variable.
threading.h
Threading definitions.
SG::Atomic
@ Atomic
Mark that this variable should only be accessed atomically.
Definition: AuxTypes.h:70
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
SG::AuxTypeRegistryImpl::typeinfo_t::m_name
std::string m_name
Aux data name.
Definition: AuxTypeRegistry.cxx:182
a
TList * a
Definition: liststreamerinfos.cxx:10
SG::AuxTypeRegistry::makeFactoryNull
std::unique_ptr< IAuxTypeVectorFactory > makeFactoryNull() const
makeFactory implementation that always returns nullptr.
SimpleUpdater.h
Simple (non-deleting) Updater implementation.
DeMoScan.first
bool first
Definition: DeMoScan.py:534
SG::IAuxTypeVector
Abstract interface for manipulating vectors of arbitrary types.
Definition: IAuxTypeVector.h:42
SG::JaggedVecElt
Describe one element of a jagged vector.
Definition: JaggedVecImpl.h:132
SG::ExcLinkMismatch
Exception — Linked variable mismatch.
Definition: Control/AthContainers/AthContainers/exceptions.h:397
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
SG::AuxTypeRegistryImpl::m_auxids
id_map_t m_auxids
Definition: AuxTypeRegistry.cxx:206
SG::AuxTypeRegistryImpl::getFactory
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.
Definition: AuxTypeRegistry.cxx:591
SG::AuxVectorData
Manage lookup of vectors of auxiliary data.
Definition: AuxVectorData.h:164
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
SG::AuxTypeRegistryImpl::m_renameMap
renameMap_t m_renameMap
Definition: AuxTypeRegistry.cxx:218
SG::AuxTypeRegistryImpl::typeinfo_t::m_flags
Flags m_flags
Additional type flags.
Definition: AuxTypeRegistry.cxx:191
checker_macros.h
Define macros for attributes used to control the static checker.
python.compressB64.c
def c
Definition: compressB64.py:93
SG::AuxTypeRegistry::copy
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.
Definition: AuxTypeRegistry.cxx:1027
LArL1Calo_ComputeHVCorr.className
className
Definition: LArL1Calo_ComputeHVCorr.py:135
SG::AuxTypeRegistryImpl::typeinfo_t::m_ti
const std::type_info * m_ti
Type of the aux data item.
Definition: AuxTypeRegistry.cxx:173
SG::AuxTypeRegistryImpl::id_map_t
CxxUtils::ConcurrentStrMap< SG::auxid_t, CxxUtils::SimpleUpdater > id_map_t
Map from name -> auxid.
Definition: AuxTypeRegistry.cxx:205
SG::ExcAuxTypeMismatch
Exception — Type mismatch for aux variable.
Definition: Control/AthContainers/AthContainers/exceptions.h:132
SG::AuxTypeRegistryImpl::AuxTypeRegistryImpl
AuxTypeRegistryImpl()
Constructor.
Definition: AuxTypeRegistry.cxx:241
SG::ExcBadVarName
Exception — Bad name for auxiliary variable.
Definition: Control/AthContainers/AthContainers/exceptions.h:498
SG::AuxTypeRegistry::getAuxID
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.
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
SG::auxAllocatorNamePrefix
constexpr const char * auxAllocatorNamePrefix
Definition: AuxDataTraits.h:29
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37