2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
7 * @file AthContainers/tools/DVLEltBaseInfo.icc
10 * @brief Set up BaseInfo information for DataVector/DataList elements.
12 * When we have a @c DATAVECTOR_BASE(D,B) macro, we want to record
13 * the @c D, @c B inheritance relation in @c SG::BaseInfo.
14 * We can't just invoke @c SG_BASE for this from @c DATAVECTOR_BASE because
15 * there may be duplicates, and @c SG_BASE won't compile in that case.
16 * But @c BaseInfo has a deferred initialization mechanism, so we use that:
17 * we arrange for an appropriate initializer be added to the list.
18 * We also need to walk the DV/DL type information structures
19 * rather then the @c BaseInfo ones.
21 * This is common code to be used for both @c DataVector and @c DataList.
22 * It should be included inside of the appropriate detail namespace.
23 * In addition, the macro @c DVLTYPE should be defined as either
24 * @c DataVector or @c DataList.
25 * Then, the *_BASE macros should explicitly instantiate the template
26 * @c *_detail::DVLEltBaseInit<T>.
30 // Set up for token pasting.
31 #define DVLPASTE1(y,x) y##x
32 #define DVLPASTE2(y,x) DVLPASTE1(y,x)
33 #define DVLPASTE(x) DVLPASTE2(DVLTYPE,x)
37 // The various specializations of DVLEltBase_init here walk the tree
38 // of the DataVector inheritance info classes and add information
41 // In all of these, T is the type of the BaseInfo we're working on,
42 // and B is the base we're trying to add to that BaseInfo.
45 struct DVLEltBase_init
48 static void init (SG::BaseInfoImpl<T>& c, bool is_virtual)
50 // Use this instead of calling add_base directly so that we pick
51 // up any base declarations that were added separately with SG_BASE.
52 SG::BaseInfo_init<B>::init (c, is_virtual);
54 DVLEltBase_init<typename DVLPASTE(Base)<B>::Base>::init (c, is_virtual);
58 struct DVLEltBase_init<DataModel_detail::NoBase>
61 static void init (SG::BaseInfoImpl<T>& /*c*/, bool /*is_virtual*/)
65 template <class B1, class B2, class B3>
66 struct DVLEltBase_init<VirtBases<B1,B2,B3> >
69 static void init (SG::BaseInfoImpl<T>& c, bool /*is_virtual*/)
71 DVLEltBase_init<B1>::init (c, true);
72 DVLEltBase_init<B2>::init (c, true);
73 DVLEltBase_init<B3>::init (c, true);
77 struct DVLEltBase_init<DVLTYPE<B> >
80 static void init (SG::BaseInfoImpl<T>& c, bool is_virtual)
82 DVLEltBase_init<B>::init (c, is_virtual);
87 // This class sets up the BaseInfo initialization.
88 // An instance of this class will be constructed during global initialization.
89 // At that time, it adds an initializer to the BaseInfo which runs doinit().
91 struct RegisterDVLEltBaseInit
93 RegisterDVLEltBaseInit();
94 static void doinit (SG::BaseInfoBase* bib);
97 RegisterDVLEltBaseInit<T>::RegisterDVLEltBaseInit()
99 // Make sure the BaseInfo derived class has been instantiated.
100 SG::BaseInfo<T>::maybeInit();
101 // Set up the init function.
102 SG::BaseInfoBase::addInit(&typeid(T), doinit);
105 void RegisterDVLEltBaseInit<T>::doinit (SG::BaseInfoBase* bib)
108 // Walk the base classes and add to it.
109 SG::BaseInfoImpl<T>& impl = *static_cast<SG::BaseInfoImpl<T>*> (bib);
110 DVLEltBase_init<T>::init (impl, false);
116 // This is what the _BASE macros instantiate.
117 // It arranges for an instance of RegisterDVLEltBaseInit to be created
118 // during global initialization.
120 template <class T> struct DVLEltBaseInit {
121 static const RegisterDVLEltBaseInit<T> s_regbase;
124 template <class T> const RegisterDVLEltBaseInit<T> DVLEltBaseInit<T>::s_regbase;