ATLAS Offline Software
|
Provide an interface for finding inheritance information at run time. More...
#include "CxxUtils/checker_macros.h"
#include "AthenaKernel/Bases.h"
#include "GaudiKernel/ClassID.h"
#include <vector>
#include <typeinfo>
#include <type_traits>
#include "AthenaKernel/BaseInfo.icc"
Go to the source code of this file.
Classes | |
struct | SG::BaseType< T > |
Helper metafunction to get base class types. More... | |
class | SG::BaseInfoImpl< T > |
class | SG::CopyConversionBase |
Base class for copy conversions. More... | |
class | SG::CopyConversion< SRC, DST > |
Base class for copy conversions, templated on source and destination classes. More... | |
struct | SG::RegisterAddBaseInit< D, B > |
struct | SG::RegisterAddCopyConversionInit< D, B > |
class | SG::BaseInfoBase |
The non-template portion of the BaseInfo implementation. More... | |
class | SG::BaseInfo< T > |
Provide an interface for finding inheritance information at run time. More... | |
Namespaces | |
SG | |
Forward declaration. | |
Macros | |
#define | SG_VIRTUAL(T) Virtual<T> |
Used to mark virtual derivation. More... | |
#define | SG_BASES(D, ...) |
Declare the base classes from which D derives. More... | |
#define | SG_BASE(D, B) SG_BASES(D, B) |
Declare that class D derives from class B. More... | |
#define | SG_BASES1(D, B) SG_BASES(D, B) |
Declare that class D derives from class B. More... | |
#define | SG_BASES2(D, B1, B2) SG_BASES(D, B1, B2) |
Declare that class D derives from classes B1 and B2. More... | |
#define | SG_BASES3(D, B1, B2, B3) SG_BASES(D, B1, B2, B3) |
Declare that class D derives from classes B1, B2, and B3. More... | |
#define | SG_BASES4(D, B1, B2, B3, B4) SG_BASES(D, B1, B2, B3, B4) |
Declare that class D derives from classes B1, B2, B3, and B4. More... | |
#define | SG_ADD_BASE(D, B) |
Add a new base class B to class D . More... | |
#define | SG_ADD_COPY_CONVERSION(D, C) |
Declare a copy conversion from class T using converter C . More... | |
Provide an interface for finding inheritance information at run time.
SG_BASES can take any number of base classes as arguments:
For backwards compatibility, there are also macros which take a fixed number of base class arguments: SG_BASE, SG_BASES1, SG_BASES2, SG_BASES3, and SG_BASES4.
If any of the derivations are virtual, the corresponding base class should be within a SG_VIRTUAL macro:
Note that these macros will only work with non-templated types, or with specific instantiations of templated types. If you want a templated SG_BASES, you'll need to declare the specialization yourself. You should specialize SG::Bases<T>, defining the type bases to be a BaseList
of the bases. Example:
Once these declarations are in place, what can you do with it? The interface is provided by the SG::BaseInfo<T> class. (This is a wrapper around a singleton, so it's not expensive to create instances of this class.) You can specify the base classes either by the Gaudi class ID or by the C++ std::type_info
. Of course, you'll only be able to get information by class ID if the classes actually have IDs defined.
Here are the available methods of SG::BaseInfo<T>:
Test to see if the type given by clid or tinfo is a base of T. Note that T counts as its own base.
Test to see if the type given by clid or tinfo is a virtual base of T. This should always be false for T itself.
Cast a pointer from T* to a pointer to the type given by clid or tinfo, which must be a base if T known to BaseInfo. The result is returned as a void*. If the conversion cannot be done (because the target is not known to be a base of T), then 0 is returned.
Similar, except converts from a pointer to the type given by clid or tinfo (which must be a base of T) to T*. This involves a dynamic_cast. Returns 0 if the cast fails.
Return all the known bases of T (that have class IDs). T itself will be included in this list.
Return all the known bases of T. T itself will be included in this list.
It is also possible to get a non-templated version of SG::BaseInfo<T>
. This is called SG::BaseInfoBase
. These objects can be found using SG::BaseInfoBase::find
, by either class ID or std::type_info
(in order for this to work, the corresponding SG::BaseInfo<T>
class must have been used somewhere in the program). The interface of SG::BaseInfoBase
is the same as SG::BaseInfo<T>
, except that void*
replaces T*
in the cast
methods.
Initialization issues: We don't want to build the SG::BaseInfo<T>
objects at static initialization time. But we do need to remember which ones are available. Thus, BaseInfoBase
maintains a list of CLIDs and std::type_info's
for which we may not have done initialization, along with a function to call to do the initialization. The initialization list is filled during static initialization. When we look for an instance, if we don't find one, we look in the initialization list; if there's a match there, we run the initialization and remove it from the list.
Copy conversions: The conversion machinery above provides access to the standard C++ base<>derived conversions. However, sometimes you'd like to allow additional conversions as well, for example between a vector<ElementLink<T> > and DataVector<T>. For those cases, you can register a conversion function with the source type that can initialize an instance of the destination type from the source type. Then, when you try to retrieve the object from StoreGate with the destination type, your conversion function will be called.
Your conversion function should be the method convert of a class deriving from the SG::CopyConversion template; for example,
You then declare this using the macro
Copy conversions are enabled only for objects that have been marked as const.
Definition in file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_ADD_BASE | ( | D, | |
B | |||
) |
Add a new base class B
to class D
.
Sometimes, the SG_BASES macro for a class isn't present in its header.
One can try to put the appropriate SG_BASES macro somewhere else, but this doesn't always work: if the BaseInfoBase
for D
has already been created by the time the SG_BASES
initialization runs, then that SG_BASES
macro won't do anything.
SG_ADD_BASE
, however, will add a new base to an existing BaseInfoBase
.
Beware, though. that any bases added this way will not be visited by Bases<T>::bases::foreach_.
Definition at line 326 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_ADD_COPY_CONVERSION | ( | D, | |
C | |||
) |
Declare a copy conversion from class T
using converter C
.
See the comments in the header for a detailed description.
Definition at line 337 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_BASE | ( | D, | |
B | |||
) | SG_BASES(D, B) |
#define SG_BASES | ( | D, | |
... | |||
) |
Declare the base classes from which D derives.
Example:
Definition at line 225 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_BASES1 | ( | D, | |
B | |||
) | SG_BASES(D, B) |
#define SG_BASES2 | ( | D, | |
B1, | |||
B2 | |||
) | SG_BASES(D, B1, B2) |
Declare that class D derives from classes B1 and B2.
Example:
Definition at line 271 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_BASES3 | ( | D, | |
B1, | |||
B2, | |||
B3 | |||
) | SG_BASES(D, B1, B2, B3) |
Declare that class D derives from classes B1, B2, and B3.
Example:
Definition at line 286 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_BASES4 | ( | D, | |
B1, | |||
B2, | |||
B3, | |||
B4 | |||
) | SG_BASES(D, B1, B2, B3, B4) |
Declare that class D derives from classes B1, B2, B3, and B4.
Example:
Definition at line 302 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.
#define SG_VIRTUAL | ( | T | ) | Virtual<T> |
Used to mark virtual derivation.
When using the SG_BASES macros below, use this in the case of virtual derivation. Example:
Definition at line 212 of file Control/AthenaKernel/AthenaKernel/BaseInfo.h.