ATLAS Offline Software
Loading...
Searching...
No Matches
Bases.h
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2/*
3 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
4 */
21
22
23#ifndef ATHENAKERNEL_BASES_H
24#define ATHENAKERNEL_BASES_H
25
26
27#include <type_traits>
28
29
30namespace SG {
31
32
37template <class T> struct Virtual {};
38
39
40// Helper metafunction to get base class types.
41// Generic case.
42template <class T>
44{
45 typedef T type;
46 typedef std::false_type is_virtual;
47};
48
49
50// Helper metafunction to get base class types.
51// Virtual derivation case.
52template <class T>
53struct BaseType<Virtual<T> >
54{
55 typedef T type;
56 typedef std::true_type is_virtual;
57};
58
59
60// _t version to reduce typing.
61template <class T>
63
64
68struct NoBase {};
69
70
77template <class... T>
79{
80public:
81 // First base in the list.
82 using Base1 = NoBase;
83
84
93 template <class CALLABLE>
94 static
95 auto foreach_ (CALLABLE f, bool /*is_virtual*/ = false)
96 {
97 // Need to find the return type.
98 using return_t = decltype (f (static_cast<void*> (nullptr), false));
99 return return_t (false);
100 }
101};
102
103
113template <class T>
114struct Bases
115{
116public:
118};
119
120
124template <class BASE, class... REST>
125struct BaseList<BASE, REST...>
126{
127public:
128 // First base in the list.
129 using Base1 = BASE;
130
131
185 template <class CALLABLE>
186 static
187 auto foreach_ (CALLABLE f, bool is_virtual = false)
188 {
189 // Unwrap a SG::Virtual if needed.
190 using base_t = typename BaseType<BASE>::type;
191 const bool base_is_virtual = is_virtual || BaseType<BASE>::is_virtual::value;
192
193 // Call the function on our first base.
194 auto ret1 = f (static_cast<base_t*> (nullptr), base_is_virtual);
195 if (static_cast<bool> (ret1)) {
196 return ret1;
197 }
198
199 // Call it on bases of our first base.
200 auto ret2 = Bases<base_t>::bases::foreach_ (f, base_is_virtual);
201 if (static_cast<bool> (ret2)) {
202 return ret2;
203 }
204
205 // Call it on our remaining bases.
206 if constexpr (sizeof... (REST) > 0) {
207 auto ret3 = BaseList<REST...>::foreach_ (f, is_virtual);
208 if (static_cast<bool> (ret3)) {
209 return ret3;
210 }
211 }
212
213 // Got to the end; return false;
214 using return_t = decltype (ret1);
215 return return_t (false);
216 }
217};
218
219
220} // namespace SG
221
222
223#endif // not ATHENAKERNEL_BASES_H
Forward declaration.
typename SG::BaseType< T >::type BaseType_t
Definition Bases.h:62
static auto foreach_(CALLABLE f, bool is_virtual=false)
Iterate over base classes.
Definition Bases.h:187
Represent a list of base classes.
Definition Bases.h:79
static auto foreach_(CALLABLE f, bool=false)
Iterate over base classes.
Definition Bases.h:95
std::true_type is_virtual
Definition Bases.h:56
Helper metafunction to get base class types.
Definition Bases.h:44
std::false_type is_virtual
Definition Bases.h:46
Traits class to hold derivation information.
Definition Bases.h:115
BaseList<> bases
Definition Bases.h:117
Marker to indicate a nonexistent base class.
Definition Bases.h:68
Wrapper to indicate virtual derivation.
Definition Bases.h:37