ATLAS Offline Software
AuxTypeRegistry.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
21 #include "CxxUtils/SimpleUpdater.h"
23 #include <cassert>
24 #include <sstream>
25 #include <cstring>
26 
27 
28 namespace SG {
29 
30 
44  : public AuxTypeRegistry
45 {
46 public:
53 
54 
61 
62 
65 
66 
92  findAuxID (const std::string& name,
93  const std::string& clsname,
94  const Flags flags,
96  const std::type_info& ti,
97  const std::type_info* ti_alloc,
98  const std::string* alloc_name,
99  std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const);
100 
101 
114  const IAuxTypeVectorFactory*
115  addFactory (lock_t& lock,
116  const std::type_info& ti,
117  const std::type_info& ti_alloc,
118  const IAuxTypeVectorFactory* factory);
119 
120 
133  const IAuxTypeVectorFactory*
134  addFactory (lock_t& /*lock*/,
135  const std::type_info& ti,
136  const std::string& ti_alloc_name,
137  std::unique_ptr<const IAuxTypeVectorFactory> factory);
138 
139 
147  static bool checkName (const std::string& s);
148 
149 
161  const std::type_info& ti,
162  const std::type_info& ti_alloc);
163 
164 
166  struct typeinfo_t
167  {
169  AthContainers_detail::atomic<const IAuxTypeVectorFactory*> m_factory;
170 
172  const std::type_info* m_ti;
173 
175  const std::type_info* m_ti_alloc;
176 
178  std::string m_alloc_name;
179 
181  std::string m_name;
182 
184  std::string m_clsname;
185 
188 
191 
194  bool checkAlloc (const std::type_info* ti_alloc,
195  const std::string* alloc_name) const;
196  };
197 
198 
200  // A concurrent vector, so we don't need to take a lock to read it.
201  AthContainers_detail::concurrent_vector<typeinfo_t> m_types;
202 
204  using id_map_t = CxxUtils::ConcurrentStrMap<SG::auxid_t, CxxUtils::SimpleUpdater>;
206 
208  using ti_map_t = CxxUtils::ConcurrentStrMap<const IAuxTypeVectorFactory*, CxxUtils::SimpleUpdater>;
210 
212  std::vector<const IAuxTypeVectorFactory*> m_oldFactories;
213 
216  typedef std::unordered_map<std::string, std::string> renameMap_t;
218 
219  // Map from the TI name for T to the TI for AuxAllocator_t<T>.
220  // Filled in by addFactory(). Used in findAuxID() if the allocator
221  // type is not specified.
222  using allocMap_t = CxxUtils::ConcurrentStrMap<const std::type_info*, CxxUtils::SimpleUpdater>;
224 
226  // We originally used an upgrading mutex here.
227  // But that's relatively slow, and most of the locked sections are short,
228  // so it's not really a win.
229  // This guards write access to all members, and read access to all members
230  // except for m_types.
231  mutable mutex_t m_mutex;
232 };
233 
234 
241  : m_auxids (id_map_t::Updater_t()),
242  m_factories (ti_map_t::Updater_t()),
243  m_allocMap (allocMap_t::Updater_t())
244 {
245  m_types.reserve (auxid_set_size_hint);
246 
247  // Make sure we have factories registered for common C++ types.
248 #define ADD_FACTORY(T) AuxTypeRegistry::addFactory(typeid(T), typeid(AuxAllocator_t<T>), std::make_unique<AuxTypeVectorFactory<T> >())
249  ADD_FACTORY (bool);
250  ADD_FACTORY (char);
251  ADD_FACTORY (unsigned char);
252  ADD_FACTORY (short);
253  ADD_FACTORY (unsigned short);
254  ADD_FACTORY (int);
255  ADD_FACTORY (unsigned int);
256  ADD_FACTORY (long);
257  ADD_FACTORY (unsigned long);
258  ADD_FACTORY (long long);
259  ADD_FACTORY (unsigned long long);
260  ADD_FACTORY (float);
261  ADD_FACTORY (double);
262  ADD_FACTORY (std::string);
263 
264  ADD_FACTORY (std::vector<char>);
265  ADD_FACTORY (std::vector<unsigned char>);
266  ADD_FACTORY (std::vector<int>);
267  ADD_FACTORY (std::vector<unsigned int>);
268  ADD_FACTORY (std::vector<float>);
269  ADD_FACTORY (std::vector<double>);
270 
284 #undef ADD_FACTORY
285 }
286 
287 
294 {
295  // not using reference, because our iterator doesn't return a reference
296  for (auto p : m_factories) {
297  if (p.first.find (";TI;") == std::string::npos) {
298  delete p.second;
299  }
300  }
301  for (const IAuxTypeVectorFactory* p : m_oldFactories)
302  delete p;
303 }
304 
305 
332  const std::string& clsname,
333  const Flags flags,
334  const SG::auxid_t linkedVariable,
335  const std::type_info& ti,
336  const std::type_info* ti_alloc,
337  const std::string* alloc_name,
338  std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const)
339 {
340  // The extra test here is to avoid having to copy a string
341  // in the common case where clsname is blank.
342  const std::string& key = clsname.empty() ? name : makeKey (name, clsname);
343 
344 
345  // Fast path --- try without acquiring the lock.
346  {
347  id_map_t::const_iterator i = m_auxids.find (key);
348  if (i != m_auxids.end()) {
349  typeinfo_t& m = m_types[i->second];
350  if (!(CxxUtils::test (m.m_flags, Flags::Atomic) &&
353  (linkedVariable == m.m_linked) &&
354  (&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
355  m.checkAlloc (ti_alloc, alloc_name) &&
356  !(*m.m_factory).isDynamic())
357  {
358  return i->second;
359  }
360  }
361  }
362 
363  // Something went wrong. Acquire the lock and try again.
364  lock_t lock (m_mutex);
365  id_map_t::const_iterator i = m_auxids.find (key);
366  if (i != m_auxids.end()) {
367  typeinfo_t& m = m_types[i->second];
368 
369  if ((CxxUtils::test (m.m_flags, Flags::Atomic) &&
372  {
373  throw SG::ExcFlagMismatch (i->second, ti, m.m_flags, flags);
374  }
375 
376  if (linkedVariable != m.m_linked)
377  {
378  throw SG::ExcLinkMismatch (i->second, ti, m.m_linked, linkedVariable);
379  }
380 
381  // By all rights, these two tests should be redundant.
382  // However, there are cases where we see distinct @c type_info objects
383  // for the same type. This is usually associated with dictionaries
384  // being loaded `too early,' during python configuration processing.
385  // It's a C++ standard violation for this to ever happen, but it's
386  // not clear that it's feasible to actually eliminate the possibility
387  // of this happening. So if the @c type_info instances differ,
388  // we still accept the match as long as the names are the same.
389  if ((&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
390  m.checkAlloc (ti_alloc, alloc_name))
391  {
392  // Try to upgrade a dynamic factory.
393  if ((*m.m_factory).isDynamic()) {
394  std::unique_ptr<IAuxTypeVectorFactory> fac2 = (*this.*makeFactory)();
395  if (fac2) {
396  if (!ti_alloc) {
397  ti_alloc = fac2->tiAlloc();
398  }
399  std::string allocName = fac2->tiAllocName();
400  m.m_factory = addFactory (lock, ti, allocName, std::move (fac2));
401  if (ti_alloc) {
402  m.m_factory = addFactory (lock, ti, *ti_alloc, m.m_factory);
403  }
404  }
405  }
406  return i->second;
407  }
408  if( *m.m_ti != typeid(SG::AuxTypePlaceholder) ) {
409  throw SG::ExcAuxTypeMismatch (i->second, ti, *m.m_ti,
410  ti_alloc ? SG::normalizedTypeinfoName (*ti_alloc) : (alloc_name ? *alloc_name : ""),
411  m.m_alloc_name);
412  }
413  // fall through, get a new auxid and real type info
414  // new auxid needed so a new data vector is created in the AuxStore
415  }
416 
417  // Verify now that the variable names are ok.
418  if (!(flags & Flags::SkipNameCheck) &&
419  (!checkName (name) ||
420  (!clsname.empty() && !checkName (clsname))))
421  {
422  throw ExcBadVarName (key);
423  }
424 
425  const IAuxTypeVectorFactory* fac = nullptr;
426  if (ti_alloc) {
427  fac = getFactory (lock, ti, *ti_alloc);
428  }
429  else if (alloc_name) {
430  fac = getFactory (ti, *alloc_name);
431  }
432  else {
433  std::string def_alloc_name = SG::auxAllocatorNamePrefix + SG::normalizedTypeinfoName (ti);
434  if (def_alloc_name[def_alloc_name.size()-1] == '>') def_alloc_name += ' ';
435  def_alloc_name += '>';
436  fac = getFactory (ti,def_alloc_name);
437  }
438 
439  if (!fac || fac->isDynamic()) {
440  std::unique_ptr<IAuxTypeVectorFactory> fac2 = (*this.*makeFactory)();
441  if (fac2) {
442  if (!ti_alloc) {
443  ti_alloc = fac2->tiAlloc();
444  }
445  std::string allocName = fac2->tiAllocName();
446  fac = addFactory (lock, ti, allocName, std::move (fac2));
447  if (ti_alloc) {
448  fac = addFactory (lock, ti, *ti_alloc, fac);
449  }
450  }
451  }
452  if (!fac) return null_auxid;
453  if (!ti_alloc) ti_alloc = fac->tiAlloc();
454  SG::auxid_t auxid = m_types.size();
455  m_types.resize (auxid+1);
456  typeinfo_t& t = m_types[auxid];
457  t.m_name = name;
458  t.m_clsname = clsname;
459  t.m_ti = &ti;
460  t.m_ti_alloc = ti_alloc;
461  t.m_alloc_name = fac->tiAllocName();
462  t.m_factory = fac;
463  t.m_flags = (flags & ~Flags::SkipNameCheck);
464  t.m_linked = linkedVariable;
465  if (linkedVariable != SG::null_auxid) {
466  if (!isLinked (linkedVariable)) std::abort();
467  }
469  m_auxids.insert_or_assign (key, auxid);
470 
471  return auxid;
472 }
473 
474 
489  const std::type_info& ti,
490  const std::type_info& ti_alloc,
491  const IAuxTypeVectorFactory* factory)
492 {
493  std::string key = std::string (ti.name()) + ";TI;" + ti_alloc.name();
494  ti_map_t::const_iterator it = m_factories.find (key);
495  if (it != m_factories.end()) {
496  if (it->second->isDynamic() && !factory->isDynamic()) {
497  // Replacing a dynamic factory with a non-dynamic one.
498  // The string version should put it to m_oldFactories.
499  m_factories.insert_or_assign (key, factory);
500  }
501  else {
502  factory = it->second;
503  }
504  }
505  else
506  m_factories.insert_or_assign (key, factory);
507 
508  if (SG::normalizedTypeinfoName (ti_alloc).starts_with(
510  {
511  m_allocMap.insert_or_assign (ti.name(), &ti_alloc);
512  }
513 
514  return factory;
515 }
516 
517 
532  const std::type_info& ti,
533  const std::string& ti_alloc_name,
534  std::unique_ptr<const IAuxTypeVectorFactory> factory)
535 {
536  std::string key = ti.name();
537  key += ';';
538  key += ti_alloc_name;
539  ti_map_t::const_iterator it = m_factories.find (key);
540  const IAuxTypeVectorFactory* fac = factory.get();
541  if (it != m_factories.end()) {
542  if (it->second->isDynamic() && !factory->isDynamic()) {
543  // Replacing a dynamic factory with a non-dynamic one.
544  // But don't delete the old one, since it might still be referenced.
545  // Instead, push it on a vector to remember it so we can delete
546  // it later.
547  m_oldFactories.push_back (it->second);
548  m_factories.insert_or_assign (key, factory.release());
549  }
550  else {
551  fac = it->second;
552  }
553  }
554  else
555  m_factories.insert_or_assign (key, factory.release());
556 
557  return fac;
558 }
559 
560 
568 bool AuxTypeRegistryImpl::checkName (const std::string& s)
569 {
570  static const std::string chars1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
571  static const std::string chars2 = chars1 + "0123456789";
572 
573  if (s.empty()) return false;
574  if (chars1.find (s[0]) == std::string::npos) return false;
575  return s.find_first_not_of (chars2, 1) == std::string::npos;
576 }
577 
578 
591  const std::type_info& ti,
592  const std::type_info& ti_alloc)
593 {
594  std::string key = ti.name();
595  key += ";TI;";
596  key += ti_alloc.name();
597  ti_map_t::const_iterator it = m_factories.find (key);
598  if (it != m_factories.end())
599  return it->second;
600 
601  std::string name = SG::normalizedTypeinfoName (ti_alloc);
602  const IAuxTypeVectorFactory* fac = getFactory (ti, name);
603  if (fac) {
604  // We only really need to be holding the lock here, but doing things
605  // otherwise would require some code duplication.
606  addFactory (lock, ti, ti_alloc, fac);
607  }
608  return fac;
609 }
610 
611 
616 bool AuxTypeRegistryImpl::typeinfo_t::checkAlloc (const std::type_info* ti_alloc,
617  const std::string* alloc_name) const
618 {
619  if (ti_alloc && m_ti_alloc) {
620  if (ti_alloc == m_ti_alloc) return true;
621  return strcmp (ti_alloc->name(), m_ti_alloc->name()) == 0;
622  }
623  if (alloc_name) {
624  return *alloc_name == m_alloc_name;
625  }
626  if (ti_alloc) {
627  return SG::normalizedTypeinfoName (*ti_alloc) == m_alloc_name;
628  }
629  return true;
630 }
631 
632 
633 //***************************************************************************
634 
635 
640 {
641  static AuxTypeRegistryImpl auxTypeRegistry ATLAS_THREAD_SAFE;
642  return auxTypeRegistry;
643 }
644 
645 
652 {
653  auto* impl = static_cast<const AuxTypeRegistryImpl*> (this);
654  return impl->m_types.size();
655 }
656 
657 
672 SG::auxid_t AuxTypeRegistry::getAuxID (const std::type_info& ti,
673  const std::string& name,
674  const std::string& clsname /*= ""*/,
675  const Flags flags /*= Flags::None*/,
676  const SG::auxid_t linkedVariable /*= SG::null_auxid*/)
677 {
678  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
679  return impl->findAuxID (name, clsname, flags, linkedVariable,
680  ti, nullptr, nullptr,
682 }
683 
684 
702 SG::auxid_t AuxTypeRegistry::getAuxID (const std::type_info& ti_alloc,
703  const std::type_info& ti,
704  const std::string& name,
705  const std::string& clsname /*= ""*/,
706  const Flags flags /*= Flags::None*/,
707  const SG::auxid_t linkedVariable /*= SG::null_auxid*/,
708  std::unique_ptr<IAuxTypeVectorFactory> (AuxTypeRegistry::*makeFactory) () const /*= &AuxTypeRegistry::makeFactoryNull*/)
709 {
710  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
711  return impl->findAuxID (name, clsname, flags, linkedVariable,
712  ti, &ti_alloc, nullptr,
713  makeFactory);
714 }
715 
716 
732 SG::auxid_t AuxTypeRegistry::getAuxID (const std::string& alloc_type,
733  const std::type_info& ti,
734  const std::string& name,
735  const std::string& clsname /*= ""*/,
736  const Flags flags /*= Flags::None*/,
737  const SG::auxid_t linkedVariable /*= SG::null_auxid*/)
738 {
739  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
740  return impl->findAuxID (name, clsname, flags, linkedVariable,
741  ti, nullptr, &alloc_type,
743 }
744 
745 
756 AuxTypeRegistry::findAuxID (const std::string& name,
757  const std::string& clsname) const
758 {
759  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
760 
761  // No locking needed here.
762  // The extra test here is to avoid having to copy a string
763  // in the common case where clsname is blank.
764  AuxTypeRegistryImpl::id_map_t::const_iterator i =
765  impl->m_auxids.find (clsname.empty() ?
766  name :
767  makeKey (name, clsname));
768  if (i != impl->m_auxids.end()) {
769  return i->second;
770  }
771  return null_auxid;
772 }
773 
774 
787  const std::type_info& ti,
788  const std::type_info& ti_alloc,
789  const Flags flags)
790 {
791  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
792  AuxTypeRegistryImpl::typeinfo_t& m = impl->m_types.at (auxid);
793 
794  if ( ! ((&ti == m.m_ti || strcmp(ti.name(), m.m_ti->name()) == 0) &&
795  m.checkAlloc (&ti_alloc, nullptr)))
796  {
797  throw SG::ExcAuxTypeMismatch (auxid, ti, *m.m_ti,
798  SG::normalizedTypeinfoName (ti_alloc),
799  m.m_alloc_name);
800  }
801  if ((CxxUtils::test (m.m_flags, Flags::Atomic) &&
804  {
805  throw SG::ExcFlagMismatch (auxid, ti, m.m_flags, flags);
806  }
807 }
808 
809 
816 std::unique_ptr<IAuxTypeVector>
818  size_t size,
819  size_t capacity) const
820 {
821  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
822  assert (factory != 0);
823  return factory->create (auxid, size, capacity, isLinked (auxid));
824 }
825 
826 
844 std::unique_ptr<IAuxTypeVector>
846  void* data,
847  IAuxTypeVector* linkedVector,
848  bool isPacked,
849  bool ownMode) const
850 {
851  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
852  assert (factory != 0);
853  return factory->createFromData (auxid, data, linkedVector,
854  isPacked, ownMode, isLinked (auxid));
855 }
856 
857 
863 std::string AuxTypeRegistry::makeKey (const std::string& name,
864  const std::string& clsname)
865 {
866  if (clsname.empty()) {
867  return name;
868  }
869  std::string output = clsname;
870  output += "::";
871  output += name;
872  return output;
873 }
874 
875 
876 
881 std::string AuxTypeRegistry::getName (SG::auxid_t auxid) const
882 {
883  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
884  if (auxid >= impl->m_types.size())
885  return "";
886  return impl->m_types[auxid].m_name;
887 }
888 
889 
896 {
897  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
898  if (auxid >= impl->m_types.size())
899  return "";
900  return impl->m_types[auxid].m_clsname;
901 }
902 
903 
908 const std::type_info* AuxTypeRegistry::getType (SG::auxid_t auxid) const
909 {
910  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
911  if (auxid >= impl->m_types.size())
912  return 0;
913  return impl->m_types[auxid].m_ti;
914 }
915 
916 
923 std::string AuxTypeRegistry::getTypeName (SG::auxid_t auxid) const
924 {
925  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
926  if (auxid >= impl->m_types.size())
927  return "";
928  return normalizedTypeinfoName (*impl->m_types[auxid].m_ti);
929 }
930 
931 
936 const std::type_info* AuxTypeRegistry::getVecType (SG::auxid_t auxid) const
937 {
938  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
939  if (factory)
940  return factory->tiVec();
941  return 0;
942 }
943 
944 
952 {
953  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
954  if (factory)
955  return normalizedTypeinfoName (*factory->tiVec());
956  return "";
957 }
958 
959 
964 const std::type_info* AuxTypeRegistry::getAllocType (SG::auxid_t auxid) const
965 {
966  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
967  if (auxid >= impl->m_types.size())
968  return 0;
969  return impl->m_types[auxid].m_ti_alloc;
970 }
971 
972 
978 {
979  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
980  if (factory)
981  return factory->getEltSize();
982  return 0;
983 }
984 
985 
991 {
992  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
993  if (auxid >= impl->m_types.size())
994  return Flags::None;
995  return impl->m_types[auxid].m_flags;
996 }
997 
998 
1007 {
1008  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1009  if (auxid >= impl->m_types.size())
1010  return null_auxid;
1011  return impl->m_types[auxid].m_linked;
1012 }
1013 
1014 
1027  AuxVectorData& dst, size_t dst_index,
1028  const AuxVectorData& src, size_t src_index,
1029  size_t n) const
1030 {
1031  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1032  if (factory)
1033  factory->copy (auxid, dst, dst_index, src, src_index, n);
1034 }
1035 
1036 
1050  AuxVectorData& dst, size_t dst_index,
1051  const AuxVectorData& src, size_t src_index,
1052  size_t n) const
1053 {
1054  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1055  if (factory) {
1056  factory->copyForOutput (auxid, dst, dst_index, src, src_index, n);
1057  }
1058 }
1059 
1060 
1074  AuxVectorData& a, size_t aindex,
1075  AuxVectorData& b, size_t bindex,
1076  size_t n) const
1077 {
1078  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1079  if (factory)
1080  factory->swap (auxid, a, aindex, b, bindex, n);
1081 }
1082 
1083 
1092  AuxVectorData& dst, size_t dst_index,
1093  size_t n) const
1094 {
1095  const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
1096  if (factory)
1097  factory->clear (auxid, dst, dst_index, n);
1098 }
1099 
1100 
1109 const IAuxTypeVectorFactory*
1110 AuxTypeRegistry::getFactory (const std::type_info& ti,
1111  const std::type_info& ti_alloc)
1112 {
1113  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1114  lock_t lock (impl->m_mutex);
1115  return impl->getFactory (lock, ti, ti_alloc);
1116 }
1117 
1118 
1126 const IAuxTypeVectorFactory*
1128 {
1129  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1130  if (auxid >= impl->m_types.size())
1131  return 0;
1132  return impl->m_types[auxid].m_factory;
1133 }
1134 
1135 
1144 const IAuxTypeVectorFactory*
1145 AuxTypeRegistry::getFactory (const std::type_info& ti,
1146  const std::string& alloc_name)
1147 {
1148  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1149 
1150  std::string key = std::string (ti.name()) + ";" + alloc_name;
1151  AuxTypeRegistryImpl::ti_map_t::const_iterator it = impl->m_factories.find (key);
1152  if (it != impl->m_factories.end()) {
1153  return it->second;
1154  }
1155 
1156  return nullptr;
1157 }
1158 
1159 
1171 const IAuxTypeVectorFactory*
1172 AuxTypeRegistry::addFactory (const std::type_info& ti,
1173  const std::type_info& ti_alloc,
1174  std::unique_ptr<const IAuxTypeVectorFactory> factory)
1175 {
1176  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1177  lock_t lock (impl->m_mutex);
1178  std::string name = SG::normalizedTypeinfoName (ti_alloc);
1179  const IAuxTypeVectorFactory* fac =
1180  impl->addFactory (lock, ti, name, std::move(factory));
1181  return impl->addFactory (lock, ti, ti_alloc, fac);
1182 }
1183 
1184 
1196 const IAuxTypeVectorFactory*
1197 AuxTypeRegistry::addFactory (const std::type_info& ti,
1198  const std::string& ti_alloc_name,
1199  std::unique_ptr<const IAuxTypeVectorFactory> factory)
1200 {
1201  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1202  lock_t lock (impl->m_mutex);
1203  return impl->addFactory (lock, ti, ti_alloc_name, std::move (factory));
1204 }
1205 
1206 
1213 {
1214 }
1215 
1216 
1221 {
1222 }
1223 
1224 
1225 #ifndef XAOD_STANDALONE
1226 
1236 void
1238  const IStringPool& pool)
1239 {
1240  auto impl = static_cast<AuxTypeRegistryImpl*> (this);
1241 
1242  lock_t lock (impl->m_mutex);
1243  impl->m_renameMap.clear();
1244  if (!map) return;
1245  for (const auto& p : *map) {
1246  sgkey_t from_sgkey = p.first;
1247  sgkey_t to_sgkey = p.second.m_sgkey;
1248 
1249  const std::string* from_str = pool.keyToString (from_sgkey);
1250  if (!from_str) continue;
1251  std::string::size_type from_dpos = from_str->find (".");
1252  if (from_dpos == std::string::npos || from_dpos == from_str->size()-1) continue;
1253 
1254  const std::string* to_str = pool.keyToString (to_sgkey);
1255  if (!to_str) continue;
1256  std::string::size_type to_dpos = to_str->find (".");
1257  if (to_dpos == std::string::npos || to_dpos == to_str->size()-1) continue;
1258 
1259  impl->m_renameMap[*from_str] = to_str->substr (to_dpos+1, std::string::npos);
1260  }
1261 }
1262 #endif
1263 
1264 
1273 const std::string& AuxTypeRegistry::inputRename (const std::string& key,
1274  const std::string& name) const
1275 {
1276  auto impl = static_cast<const AuxTypeRegistryImpl*> (this);
1277  lock_t lock (impl->m_mutex);
1278  if (impl->m_renameMap.empty())
1279  return name;
1280 
1281  std::string fullkey = key + "." + name;
1282  auto it = impl->m_renameMap.find (fullkey);
1283  if (it != impl->m_renameMap.end())
1284  return it->second;
1285  return name;
1286 }
1287 
1288 
1292 bool AuxTypeRegistry::isLinkedName (const std::string& name)
1293 {
1294  return name.ends_with ("_linked");
1295 }
1296 
1297 
1302 std::string AuxTypeRegistry::linkedName (const std::string& name)
1303 {
1304  return name + "_linked";
1305 }
1306 
1307 
1313 {
1314  if (className.find ("SG::JaggedVecElt<") != std::string::npos) {
1315  return true;
1316  }
1317  if (className.find ("SG::PackedLink<") != std::string::npos) {
1318  return true;
1319  }
1320  return false;
1321 }
1322 
1323 
1324 } // namespace SG
1325 
1326 
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:1110
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:845
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
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:1172
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
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:169
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
SG::AuxTypeRegistryImpl::renameMap_t
std::unordered_map< std::string, std::string > renameMap_t
Save the information provided by setInputRenameMap.
Definition: AuxTypeRegistry.cxx:216
SG::AuxTypeRegistryImpl::~AuxTypeRegistryImpl
~AuxTypeRegistryImpl()
Destructor.
Definition: AuxTypeRegistry.cxx:293
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:756
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:863
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:881
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:951
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:1273
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:208
SG::AuxTypeRegistry::getAllocType
const std::type_info * getAllocType(SG::auxid_t auxid) const
Return the type of the vector allocator.
Definition: AuxTypeRegistry.cxx:964
SG::AuxTypeRegistryImpl::allocMap_t
CxxUtils::ConcurrentStrMap< const std::type_info *, CxxUtils::SimpleUpdater > allocMap_t
Definition: AuxTypeRegistry.cxx:222
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:1302
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
SG::AuxTypeRegistryImpl::m_allocMap
allocMap_t m_allocMap
Definition: AuxTypeRegistry.cxx:223
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:1312
SG::AuxTypeRegistry::AuxTypeRegistry
AuxTypeRegistry()
Constructor.
Definition: AuxTypeRegistry.cxx:1212
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:1049
AthContainers_detail::fence_seq_cst
void fence_seq_cst()
A sequentially-consistent fence.
SG::AuxTypeRegistry::~AuxTypeRegistry
~AuxTypeRegistry()
Destructor.
Definition: AuxTypeRegistry.cxx:1220
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::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:908
SG::AuxTypeRegistryImpl::m_mutex
mutex_t m_mutex
Mutex controlling access to the registry.
Definition: AuxTypeRegistry.cxx:231
SG::AuxTypeRegistryImpl
@Brief Implementation class for AuxTypeRegistry.
Definition: AuxTypeRegistry.cxx:45
CaloCellPos2Ntuple.None
None
Definition: CaloCellPos2Ntuple.py:23
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
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:1073
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:923
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:488
beamspotman.n
n
Definition: beamspotman.py:731
SG::AuxTypeRegistry::getFlags
Flags getFlags(SG::auxid_t auxid) const
Return flags associated with an auxiliary variable.
Definition: AuxTypeRegistry.cxx:990
SG::AuxTypeRegistryImpl::m_types
AthContainers_detail::concurrent_vector< typeinfo_t > m_types
Table of aux data items, indexed by auxid.
Definition: AuxTypeRegistry.cxx:201
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:1006
SG::AuxTypeRegistry::getEltSize
size_t getEltSize(SG::auxid_t auxid) const
Return size of an element in the STL vector.
Definition: AuxTypeRegistry.cxx:977
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:1292
SG::AuxTypeRegistryImpl::typeinfo_t::m_alloc_name
std::string m_alloc_name
Name of the vector allocator.
Definition: AuxTypeRegistry.cxx:178
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:936
SG::AuxTypeRegistry::numVariables
size_t numVariables() const
Return the total number of registered auxiliary variable.
Definition: AuxTypeRegistry.cxx:651
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:616
SG::AuxTypeRegistryImpl::typeinfo_t
Hold information about one aux data item.
Definition: AuxTypeRegistry.cxx:167
SG::AuxTypeRegistryImpl::typeinfo_t::m_clsname
std::string m_clsname
Class name associated with this aux data item. May be blank.
Definition: AuxTypeRegistry.cxx:184
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:1091
SG::AuxTypeRegistryImpl::m_factories
ti_map_t m_factories
Definition: AuxTypeRegistry.cxx:209
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:895
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:175
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:817
SG::AuxTypeRegistryImpl::m_oldFactories
std::vector< const IAuxTypeVectorFactory * > m_oldFactories
Hold additional factory instances we need to delete.
Definition: AuxTypeRegistry.cxx:212
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:331
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:77
SG::AuxTypeRegistry::setInputRenameMap
void setInputRenameMap(const Athena::InputRenameMap_t *map, const IStringPool &pool)
Declare input renaming requests.
Definition: AuxTypeRegistry.cxx:1237
SG::AuxTypeRegistryImpl::typeinfo_t::m_linked
auxid_t m_linked
auxid of a linked variable, or null_auxid.
Definition: AuxTypeRegistry.cxx:187
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: CxxUtils/CxxUtils/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:181
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.
SG::AuxTypeRegistryImpl::checkName
static bool checkName(const std::string &s)
Check for valid variable name.
Definition: AuxTypeRegistry.cxx:568
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.
SG::AuxTypeRegistryImpl::m_auxids
id_map_t m_auxids
Definition: AuxTypeRegistry.cxx:205
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:590
SG::AuxVectorData
Manage lookup of vectors of auxiliary data.
Definition: AuxVectorData.h:168
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
SG::AuxTypeRegistryImpl::m_renameMap
renameMap_t m_renameMap
Definition: AuxTypeRegistry.cxx:217
SG::AuxTypeRegistryImpl::typeinfo_t::m_flags
Flags m_flags
Additional type flags.
Definition: AuxTypeRegistry.cxx:190
checker_macros.h
Define macros for attributes used to control the static checker.
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:1026
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:172
SG::AuxTypeRegistryImpl::id_map_t
CxxUtils::ConcurrentStrMap< SG::auxid_t, CxxUtils::SimpleUpdater > id_map_t
Map from name -> auxid.
Definition: AuxTypeRegistry.cxx:204
SG::ExcAuxTypeMismatch
Exception — Type mismatch for aux variable.
Definition: Control/AthContainers/AthContainers/exceptions.h:132
SG::AuxTypeRegistryImpl::AuxTypeRegistryImpl
AuxTypeRegistryImpl()
Constructor.
Definition: AuxTypeRegistry.cxx:240
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.
SG::auxAllocatorNamePrefix
constexpr const char * auxAllocatorNamePrefix
Definition: AuxDataTraits.h:29
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37