Skip to content

Commit 3cbd55a

Browse files
Adding generic implemenation for descriptors
Implements a generic container for the union of a char and a uint element of the same size. Simple definition of 1 to 8 byte decriptors. The generalization for more than 8 bytes can be activated later once an appropriate test setup is available.
1 parent 28dd8b4 commit 3cbd55a

File tree

2 files changed

+88
-28
lines changed

2 files changed

+88
-28
lines changed

DataFormats/Headers/include/Headers/DataHeader.h

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct DataHeader;
7979
struct DataIdentifier;
8080

8181
//__________________________________________________________________________________________________
82-
// internal implementation
82+
// internal implementations
8383
/// @ingroup aliceo2_dataformat_tools
8484
namespace Internal {
8585
// terminating initializer implementation
@@ -104,6 +104,50 @@ template<typename T>
104104
struct getnargs<T> {
105105
static int const value = 1;
106106
};
107+
108+
/// get the number of active bits (set to 1) in a bitfield
109+
template <unsigned int N>
110+
struct NumberOfActiveBits {
111+
static int const value = NumberOfActiveBits<(N >> 1)>::value + (N & 0x1);
112+
};
113+
template <>
114+
struct NumberOfActiveBits<0> {
115+
static int const value = 0;
116+
};
117+
118+
/// evaluate the array size necessary to hold a N-byte number with type T
119+
template <int N, typename T>
120+
struct ArraySize {
121+
static_assert(N >= sizeof(T), "get this code to work first");
122+
static int const value = 1;
123+
//static int const value = std::conditional<(N > sizeof(T)), ArraySize<(N - sizeof(T)), T>, ArraySize<0, T>>::value + 1;
124+
};
125+
template <typename T>
126+
struct ArraySize<0, T> {
127+
static int const value = 0;
128+
};
129+
130+
/// select uint type depending on size, default is uint64_t
131+
template <int N>
132+
struct TraitsIntType {
133+
typedef uint64_t type;
134+
};
135+
template <>
136+
struct TraitsIntType<1> {
137+
typedef uint8_t type;
138+
};
139+
template <>
140+
struct TraitsIntType<2> {
141+
typedef uint16_t type;
142+
};
143+
template <>
144+
struct TraitsIntType<4> {
145+
typedef uint32_t type;
146+
};
147+
148+
struct defaultPrinter {
149+
void operator()(const char* str) const {}
150+
};
107151
};
108152

109153
//__________________________________________________________________________________________________
@@ -176,6 +220,45 @@ constexpr uint32_t CharArr2uint32(char c1, char c2, char c3, char c4)
176220
return String2<uint32_t>(c1, c2, c3, c4);
177221
}
178222

223+
//__________________________________________________________________________________________________
224+
/// generic descriptor class faturing the union of a char and a uint element
225+
/// of the same size
226+
/// this is currently working only for up to 8 bytes aka uint64_t, the general
227+
/// solution is working also for multiples of 64 bit, but then the itg member needs
228+
/// to be an array for all. This has not been enabled yet, first the implications
229+
/// have to be studied.
230+
template <int N, typename PrinterPolicy = Internal::defaultPrinter>
231+
struct Descriptor {
232+
static_assert(Internal::NumberOfActiveBits<N>::value == 1 && N <= 8,
233+
"size is required to be 1 or a multiple of 2");
234+
static int const size = N;
235+
static int const bitcount = size*8;
236+
static int const arraySize = 1; //Internal::ArraySize<size, uint64_t>::value;
237+
typedef typename Internal::TraitsIntType<N>::type ItgType;
238+
239+
union {
240+
char str[N];
241+
ItgType itg; // for extension > 64 bit: [arraySize];
242+
};
243+
Descriptor() {};
244+
Descriptor(const Descriptor& other) : itg(other.itg) {}
245+
Descriptor& operator=(const Descriptor& other) {
246+
if (&other != this) itg = other.itg;
247+
return *this;
248+
}
249+
// note: no operator=(const char*) as this potentially runs into trouble with this
250+
// general pointer type, use: somedescriptor = Descriptor("DESCRIPTION")
251+
constexpr Descriptor(const char* origin) : itg(String2<ItgType>(origin)) {};
252+
bool operator==(const Descriptor& other) const {return itg == other.itg;}
253+
bool operator!=(const Descriptor& other) const {return not this->operator==(other);}
254+
// print function needs to be implemented for every derivation
255+
PrinterPolicy printer;
256+
void print() const {
257+
// eventually terminate string before printing
258+
printer(str);
259+
};
260+
};
261+
179262
//__________________________________________________________________________________________________
180263
/// default int representation of 'invalid' token for 4-byte char field
181264
const uint32_t gInvalidToken32 = 0xFFFFFFFF;
@@ -479,24 +562,10 @@ struct DataDescription {
479562

480563
//__________________________________________________________________________________________________
481564
// 32bit (4 characters) for data origin, ex. the detector or subsystem name
482-
struct DataOrigin {
483-
union {
484-
char str[gSizeDataOriginString];
485-
uint32_t itg;
486-
};
487-
DataOrigin();
488-
DataOrigin(const DataOrigin& other) : itg(other.itg) {}
489-
DataOrigin& operator=(const DataOrigin& other) {
490-
if (&other != this) itg = other.itg;
491-
return *this;
492-
}
493-
// note: no operator=(const char*) as this potentially runs into trouble with this
494-
// general pointer type, use: someorigin = DataOrigin("BLA")
495-
constexpr DataOrigin(const char* origin) : itg{String2uint32(origin)} {};
496-
bool operator==(const DataOrigin&) const;
497-
bool operator!=(const DataOrigin& other) const {return not this->operator==(other);}
498-
void print() const;
565+
struct printDataOrigin {
566+
void operator()(const char* str) const;
499567
};
568+
typedef Descriptor<gSizeDataOriginString, printDataOrigin> DataOrigin;
500569

501570
//__________________________________________________________________________________________________
502571
/// @struct DataHeader

DataFormats/Headers/src/DataHeader.cxx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,7 @@ bool AliceO2::Header::DataHeader::operator==(const DataHeader& that) const
176176
}
177177

178178
//__________________________________________________________________________________________________
179-
AliceO2::Header::DataOrigin::DataOrigin() : itg(gInvalidToken32) {}
180-
181-
//__________________________________________________________________________________________________
182-
bool AliceO2::Header::DataOrigin::operator==(const DataOrigin& other) const
183-
{
184-
return itg == other.itg;
185-
}
186-
187-
//__________________________________________________________________________________________________
188-
void AliceO2::Header::DataOrigin::print() const
179+
void AliceO2::Header::printDataOrigin::operator()(const char* str) const
189180
{
190181
printf("Data origin : %s\n", str);
191182
}

0 commit comments

Comments
 (0)