ATLAS Offline Software
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-2020 CERN for the benefit of the ATLAS collaboration.
4  */
23 #ifndef ATHENAKERNEL_BASES_H
24 #define ATHENAKERNEL_BASES_H
25 
26 
27 #include <type_traits>
28 
29 
30 namespace SG {
31 
32 
37 template <class T> struct Virtual {};
38 
39 
40 // Helper metafunction to get base class types.
41 // Generic case.
42 template <class T>
43 struct BaseType
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.
52 template <class T>
53 struct BaseType<Virtual<T> >
54 {
55  typedef T type;
56  typedef std::true_type is_virtual;
57 };
58 
59 
63 struct NoBase {};
64 
65 
72 template <class... T>
73 struct BaseList
74 {
75 public:
76  // First base in the list.
77  using Base1 = NoBase;
78 
79 
88  template <class CALLABLE>
89  static
90  auto foreach_ (CALLABLE f, bool /*is_virtual*/ = false)
91  {
92  // Need to find the return type.
93  using return_t = decltype (f (static_cast<void*> (nullptr), false));
94  return return_t (false);
95  }
96 };
97 
98 
108 template <class T>
109 struct Bases
110 {
111 public:
112  using bases = BaseList<>;
113 };
114 
115 
119 template <class BASE, class... REST>
120 struct BaseList<BASE, REST...>
121 {
122 public:
123  // First base in the list.
124  using Base1 = BASE;
125 
126 
180  template <class CALLABLE>
181  static
182  auto foreach_ (CALLABLE f, bool is_virtual = false)
183  {
184  // Unwrap a SG::Virtual if needed.
185  using base_t = typename BaseType<BASE>::type;
186  const bool base_is_virtual = is_virtual || BaseType<BASE>::is_virtual::value;
187 
188  // Call the function on our first base.
189  auto ret1 = f (static_cast<base_t*> (nullptr), base_is_virtual);
190  if (static_cast<bool> (ret1)) {
191  return ret1;
192  }
193 
194  // Call it on bases of our first base.
195  auto ret2 = Bases<base_t>::bases::foreach_ (f, base_is_virtual);
196  if (static_cast<bool> (ret2)) {
197  return ret2;
198  }
199 
200  // Call it on our remaining bases.
201  if constexpr (sizeof... (REST) > 0) {
202  auto ret3 = BaseList<REST...>::foreach_ (f, is_virtual);
203  if (static_cast<bool> (ret3)) {
204  return ret3;
205  }
206  }
207 
208  // Got to the end; return false;
209  using return_t = decltype (ret1);
210  return return_t (false);
211  }
212 };
213 
214 
215 } // namespace SG
216 
217 
218 #endif // not ATHENAKERNEL_BASES_H
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::BaseType< Virtual< T > >::is_virtual
std::true_type is_virtual
Definition: Bases.h:56
SG::BaseList< BASE, REST... >::Base1
BASE Base1
Definition: Bases.h:124
SG::Bases
Traits class to hold derivation information.
Definition: Bases.h:110
SG::NoBase
Marker to indicate a nonexistent base class.
Definition: Bases.h:63
SG::Virtual
Wrapper to indicate virtual derivation.
Definition: Bases.h:37
SG::BaseType::is_virtual
std::false_type is_virtual
Definition: Bases.h:46
SG::BaseList::foreach_
static auto foreach_(CALLABLE f, bool=false)
Iterate over base classes.
Definition: Bases.h:90
SG::BaseType::type
T type
Definition: Bases.h:45
SG::BaseType< Virtual< T > >::type
T type
Definition: Bases.h:55
SG::BaseList< BASE, REST... >::foreach_
static auto foreach_(CALLABLE f, bool is_virtual=false)
Iterate over base classes.
Definition: Bases.h:182
SG::BaseType
Helper metafunction to get base class types.
Definition: Control/AthenaKernel/AthenaKernel/BaseInfo.h:364
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
SG::BaseList
Represent a list of base classes.
Definition: Bases.h:74