ATLAS Offline Software
DVLEltBaseInfo.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id$
6 /**
7  * @file AthContainers/tools/DVLEltBaseInfo.icc
8  * @author scott snyder
9  * @date Jul 2009
10  * @brief Set up BaseInfo information for DataVector/DataList elements.
11  *
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.
20  *
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>.
27  */
28 
29 
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)
34 
35 
36 //
37 // The various specializations of DVLEltBase_init here walk the tree
38 // of the DataVector inheritance info classes and add information
39 // to the BaseInfo.
40 //
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.
43 //
44 template <class B>
45 struct DVLEltBase_init
46 {
47  template <class T>
48  static void init (SG::BaseInfoImpl<T>& c, bool is_virtual)
49  {
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);
53 
54  DVLEltBase_init<typename DVLPASTE(Base)<B>::Base>::init (c, is_virtual);
55  }
56 };
57 template <>
58 struct DVLEltBase_init<DataModel_detail::NoBase>
59 {
60  template <class T>
61  static void init (SG::BaseInfoImpl<T>& /*c*/, bool /*is_virtual*/)
62  {
63  }
64 };
65 template <class B1, class B2, class B3>
66 struct DVLEltBase_init<VirtBases<B1,B2,B3> >
67 {
68  template <class T>
69  static void init (SG::BaseInfoImpl<T>& c, bool /*is_virtual*/)
70  {
71  DVLEltBase_init<B1>::init (c, true);
72  DVLEltBase_init<B2>::init (c, true);
73  DVLEltBase_init<B3>::init (c, true);
74  }
75 };
76 template <class B>
77 struct DVLEltBase_init<DVLTYPE<B> >
78 {
79  template <class T>
80  static void init (SG::BaseInfoImpl<T>& c, bool is_virtual)
81  {
82  DVLEltBase_init<B>::init (c, is_virtual);
83  }
84 };
85 
86 
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().
90 template <class T>
91 struct RegisterDVLEltBaseInit
92 {
93  RegisterDVLEltBaseInit();
94  static void doinit (SG::BaseInfoBase* bib);
95 };
96 template <class T>
97 RegisterDVLEltBaseInit<T>::RegisterDVLEltBaseInit()
98 {
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);
103 }
104 template <class T>
105 void RegisterDVLEltBaseInit<T>::doinit (SG::BaseInfoBase* bib)
106 {
107  if (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);
111  }
112 }
113 
114 
115 //
116 // This is what the _BASE macros instantiate.
117 // It arranges for an instance of RegisterDVLEltBaseInit to be created
118 // during global initialization.
119 //
120 template <class T> struct DVLEltBaseInit {
121  static const RegisterDVLEltBaseInit<T> s_regbase;
122 };
123 #ifndef __APPLE__
124 template <class T> const RegisterDVLEltBaseInit<T> DVLEltBaseInit<T>::s_regbase;
125 #endif
126 
127 #undef DVLPASTE
128 #undef DVLPASTE1
129 #undef DVLPASTE2