CbmRoot
Loading...
Searching...
No Matches
_GTestStructLooper.cxx
Go to the documentation of this file.
1/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
9
10#include "CbmStructLooper.h"
11#include "gtest/gtest.h"
12
13#include <unordered_map>
14#include <unordered_set>
15#include <vector>
16
18class A {
19 public:
20 using Property_t = int;
21
25 int GetStationId(uint16_t address) const { return (0xF0 & address) >> 4; }
26
28 void SetProperty(Property_t property) { fSomeProperty = property; }
29
30 private:
32};
33
34
36class B {
37 public:
38 B(std::vector<int>&& stMap) : fModuleStationMap(std::move(stMap)) {}
39
40 using Property_t = double;
41
45 int GetStationId(uint16_t address) const { return fModuleStationMap[(0xF00 & address) >> 8]; }
46
48 void SetProperty(Property_t property) { fSomeProperty = property; }
49
50 private:
51 std::vector<int> fModuleStationMap;
53};
54
55
57class C {
58 public:
59 C(std::unordered_map<uint16_t, int>&& stMap) : fModuleStationMap(std::move(stMap)) {}
60
61 using Property_t = float;
62
66 int GetStationId(uint16_t address) const { return fModuleStationMap.at(address); }
67
69 void SetProperty(Property_t property) { fSomeProperty = property; }
70
71 private:
72 std::unordered_map<uint16_t, int> fModuleStationMap;
74};
75
76// NOTE: The classes A, B and C are non-polymorphic and even don't have a common interface (but use similar API)
77
79struct Composite {
83 template<class Visitor>
84 void ForEachValue(Visitor&& visitor)
85 {
86 kLooper.ForEachValue(this, std::forward<Visitor>(visitor));
87 }
88
92 template<class Visitor>
93 void ForEachValue(Visitor&& visitor) const
94 {
95 kLooper.ForEachValue(this, std::forward<Visitor>(visitor));
96 }
97
101 template<class Visitor>
102 void ForEachVariable(Visitor&& visitor)
103 {
104 kLooper.ForEachVariable(this, std::forward<Visitor>(visitor));
105 }
106
110 template<class Visitor>
111 void ForEachVariable(Visitor&& visitor) const
112 {
113 kLooper.ForEachVariable(this, std::forward<Visitor>(visitor));
114 }
115
116 std::optional<A> fA;
117 std::optional<B> fB;
118 std::optional<C> fC;
119
120 private:
122};
123
126struct Hits {
127 template<class Class>
128 const auto& GetHitsFor() const
129 {
130 if constexpr (std::is_same_v<Class, A>) {
131 return a;
132 }
133 else if constexpr (std::is_same_v<Class, B>) {
134 return b;
135 }
136 else {
137 return c;
138 }
139 }
140
141 std::vector<uint16_t> a;
142 std::vector<uint16_t> b;
143 std::vector<uint16_t> c;
144};
145
149 static int GetNofNonNullopt(const Composite& c)
150 {
151 int res{0};
152 c.ForEachVariable([&res](const auto& var) {
153 if (var.has_value()) ++res;
154 });
155 return res;
156 }
157
161 static void SetProperty(Composite& c, double number)
162 {
163 c.ForEachValue([number](auto&& val) { val.SetProperty(number); });
164 }
165
167 static int GetPropertySum(const Composite& c)
168 {
169 int res{0};
170 c.ForEachValue([&res](const auto& val) { res += static_cast<int>(val.GetProperty()); });
171 return res;
172 }
173
177 static int GetNumberOfStationsWithHits(const Composite& c, const Hits& hits)
178 {
179 int nTotSt{0};
180 c.ForEachValue([&hits, &nTotSt](const auto& val) {
181 using Value_t = typename std::remove_const_t<std::remove_reference_t<decltype(val)>>;
182 std::unordered_set<int> uniqueStationIds;
183 for (uint16_t address : hits.GetHitsFor<Value_t>())
184 uniqueStationIds.insert(val.GetStationId(address));
185 nTotSt += uniqueStationIds.size();
186 });
187 return nTotSt;
188 }
189};
190
191static auto hits = Hits{
192 .a = std::move(std::vector<uint16_t>{0x100, 0x200, 0x320, 0x110, 0x200, 0x300, 0x130, 0x220, 0x320}), // 4 st,
193 .b = std::move(std::vector<uint16_t>{0x051, 0x141, 0x491, 0x241, 0x551, 0x821, 0x131, 0x951, 0x241}), // 3 st
194 .c = std::move(std::vector<uint16_t>{0x012, 0x022, 0x032, 0x032, 0x012, 0x012, 0x022, 0x012, 0x022}) // 2 st
195};
196
197static auto compFull =
198 Composite{.fA = std::move(A()),
199 .fB = std::move(B(std::move(std::vector<int>({1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 0, 0, 0, 0, 2, 2})))),
200 .fC = std::move(C(std::move(std::unordered_map<uint16_t, int>({{0x12, 0}, {0x22, 0}, {0x32, 1}}))))};
201
202static auto compPart =
203 Composite{.fA = std::move(A()),
204 .fB = std::nullopt,
205 .fC = std::move(C(std::move(std::unordered_map<uint16_t, int>({{0x12, 0}, {0x22, 0}, {0x32, 1}}))))};
206
207TEST(_GTestStructLooper, StructLooper_FullyDefinedComposite_LoopOverVariables)
208{
209 // Calculate number of nullopt values
210 SCOPED_TRACE("StructLooper_FullyDefinedComposite_LoopOverVariables");
212}
213
214TEST(_GTestStructLooper, StructLooper_FullyDefinedComposite_LoopOverValues_1)
215{
216 // Set and get a property
217 SCOPED_TRACE("StructLooper_FullyDefinedComposite_LoopOverValues_1");
220}
221
222TEST(_GTestStructLooper, StructLooper_FullyDefinedComposite_LoopOverValues_2)
223{
224 // Get number of stations with hits
225 SCOPED_TRACE("StructLooper_FullyDefinedComposite_LoopOverValues_2");
227}
228
229TEST(_GTestStructLooper, StructLooper_PartiallyDefinedComposite_LoopOverVariables)
230{
231 // Calculate number of nullopt values
232 SCOPED_TRACE("StructLooper_PartiallyDefinedComposite_LoopOverVariables");
234}
235
236TEST(_GTestStructLooper, StructLooper_PartiallyDefinedComposite_LoopOverValues_1)
237{
238 // Set and get a property
239 SCOPED_TRACE("StructLooper_PartiallyDefinedComposite_LoopOverValues_1");
242}
243
244TEST(_GTestStructLooper, StructLooper_PartiallyDefinedComposite_LoopOverValues_2)
245{
246 // Get number of stations with hits
247 SCOPED_TRACE("StructLooper_PartiallyDefinedComposite_LoopOverValues_2");
249}
A generic looper over selected variables of a struct/class.
static vector< vector< QAHit > > hits
static auto compFull
static auto hits
TEST(_GTestStructLooper, StructLooper_FullyDefinedComposite_LoopOverVariables)
static auto compPart
Some class A.
int GetStationId(uint16_t address) const
Maps an address of A component to a station of component.
Property_t fSomeProperty
Property_t GetProperty() const
void SetProperty(Property_t property)
Property_t GetProperty() const
Property_t fSomeProperty
B(std::vector< int > &&stMap)
std::vector< int > fModuleStationMap
double Property_t
int GetStationId(uint16_t address) const
Maps an address of B component to a station of component.
void SetProperty(Property_t property)
std::unordered_map< uint16_t, int > fModuleStationMap
Property_t GetProperty() const
void SetProperty(Property_t property)
float Property_t
int GetStationId(uint16_t address) const
Maps an address of A component to a station of component.
Property_t fSomeProperty
C(std::unordered_map< uint16_t, int > &&stMap)
An utility, which allows to apply a callable to selected variables of a class in a loop.
Hash for CbmL1LinkKey.
An application for a Composite object.
static int GetPropertySum(const Composite &c)
Gets a sum of the properties of all non-null components.
static int GetNumberOfStationsWithHits(const Composite &c, const Hits &hits)
Counts number of stations, which have a hit with a given address.
static int GetNofNonNullopt(const Composite &c)
Calculates number of non-nullopt variables.
static void SetProperty(Composite &c, double number)
Sets a common number as a property.
A composite of optional A, B and C.
static constexpr auto kLooper
std::optional< B > fB
void ForEachValue(Visitor &&visitor) const
A for-each method, which is applied to each VARIABLE.
std::optional< C > fC
std::optional< A > fA
void ForEachVariable(Visitor &&visitor)
A for-each method, which is applied to a VALUE stored in each variable.
void ForEachVariable(Visitor &&visitor) const
A for-each method, which is applied to a VALUE stored in each variable.
void ForEachValue(Visitor &&visitor)
A for-each method, which is applied to each VARIABLE.
A class, which emulates hit containers for different components.
std::vector< uint16_t > a
std::vector< uint16_t > c
const auto & GetHitsFor() const
std::vector< uint16_t > b