@@ -79,7 +79,7 @@ struct DataHeader;
7979struct DataIdentifier ;
8080
8181// __________________________________________________________________________________________________
82- // internal implementation
82+ // internal implementations
8383// / @ingroup aliceo2_dataformat_tools
8484namespace Internal {
8585// terminating initializer implementation
@@ -104,6 +104,50 @@ template<typename T>
104104struct 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
181264const 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
0 commit comments