ATLAS Offline Software
Loading...
Searching...
No Matches
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//
44template <class B>
45struct 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};
57template <>
58struct DVLEltBase_init<DataModel_detail::NoBase>
59{
60 template <class T>
61 static void init (SG::BaseInfoImpl<T>& /*c*/, bool /*is_virtual*/)
62 {
63 }
64};
65template <class B1, class B2, class B3>
66struct 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};
76template <class B>
77struct 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().
90template <class T>
91struct RegisterDVLEltBaseInit
92{
93 RegisterDVLEltBaseInit();
94 static void doinit (SG::BaseInfoBase* bib);
95};
96template <class T>
97RegisterDVLEltBaseInit<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}
104template <class T>
105void 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//
120template <class T> struct DVLEltBaseInit {
121 static const RegisterDVLEltBaseInit<T> s_regbase;
122};
123#ifndef __APPLE__
124template <class T> const RegisterDVLEltBaseInit<T> DVLEltBaseInit<T>::s_regbase;
125#endif
126
127#undef DVLPASTE
128#undef DVLPASTE1
129#undef DVLPASTE2