@@ -78,62 +78,102 @@ constexpr uint32_t gSizeHeaderDescriptionString = 8;
7878struct DataHeader ;
7979struct DataIdentifier ;
8080
81+ // __________________________________________________________________________________________________
82+ // internal implementation
83+ // / @ingroup aliceo2_dataformat_tools
84+ namespace Internal {
85+ // terminating initializer implementation
86+ template <typename T>
87+ constexpr T String2__ ()
88+ {
89+ return 0 ;
90+ }
91+ // recursive initializer implementation
92+ template <typename T, typename ... Targs>
93+ constexpr T String2__ (char c, Targs... Fargs)
94+ {
95+ return (T) c | String2__<T>(Fargs...) << 8 ;
96+ }
97+
98+ // / compile time evaluation of the number of arguments in argument pack
99+ template <typename T, typename ... Targs>
100+ struct getnargs {
101+ static int const value = getnargs<Targs...>::value + 1 ;
102+ };
103+ template <typename T>
104+ struct getnargs <T> {
105+ static int const value = 1 ;
106+ };
107+ };
108+
81109// __________________________________________________________________________________________________
82110// / constexpr intializer, evaluated at compile time
111+ // / generic intializer for variable char argument list
112+ template <typename T, typename ... Targs>
113+ constexpr T String2 (char c, Targs... Fargs)
114+ {
115+ // number of arguments has either to match the size of the type, or the last element is treated
116+ // as '0' if missing
117+ static_assert (Internal::getnargs<T, Targs...>::value == sizeof (T) ||
118+ Internal::getnargs<T, Targs...>::value == sizeof (T) - 1 ,
119+ " number of arguments does not match the uint type width"
120+ );
121+ return Internal::String2__<T>(c, Fargs...);
122+ }
123+
124+ // / constexpr intializer, evaluated at compile time
125+ // / backward compatibility, might be removed in the future
83126constexpr uint64_t String2uint64 (char c1, char c2, char c3, char c4,
84127 char c5, char c6, char c7, char c8)
85128{
86- return ((uint64_t ) c1 | (uint64_t ) c2 << 8 | (uint64_t ) c3 << 16 | (uint64_t ) c4 << 24 |
87- (uint64_t ) c5 << 32 | (uint64_t ) c6 << 40 | (uint64_t ) c7 << 48 | (uint64_t ) c8 << 56 );
129+ return String2<uint64_t >(c1, c2, c3, c4, c5, c6, c7, c8);
88130}
89131
90132// / constexpr intializer, evaluated at compile time
91- constexpr uint64_t String2uint64 (const char * str, int pos=0 )
133+ // / generic initializer, convert a string to unsigned integer of different width
134+ // / Example usage: String2<uint64_t>("IDENTIFY")
135+ // / @ingroup aliceo2_dataformat_tools
136+ template <typename T>
137+ constexpr T String2 (const char * str, int pos=0 )
92138{
93- return ((uint64_t ) str[0 +pos] |
94- (str[0 +pos] ? ((uint64_t ) str[1 +pos] << 8 |
95- (str[1 +pos] ? ((uint64_t ) str[2 +pos] << 16 |
96- (str[2 +pos] ? ((uint64_t ) str[3 +pos] << 24 |
97- (str[3 +pos] ? ((uint64_t ) str[4 +pos] << 32 |
98- (str[4 +pos] ? ((uint64_t ) str[5 +pos] << 40 |
99- (str[5 +pos] ? ((uint64_t ) str[6 +pos] << 48 |
100- (str[6 +pos] ? ((uint64_t ) str[7 +pos] << 56 )
139+ return ((T ) str[0 +pos] |
140+ (str[0 +pos] && sizeof (T) >= 2 ? ((T ) str[1 +pos] << ( sizeof (T) >= 2 ? 8 : 0 ) |
141+ (str[1 +pos] && sizeof (T) >= 4 ? ((T ) str[2 +pos] << ( sizeof (T) >= 4 ? 16 : 0 ) |
142+ (str[2 +pos] && sizeof (T) >= 4 ? ((T ) str[3 +pos] << ( sizeof (T) >= 4 ? 24 : 0 ) |
143+ (str[3 +pos] && sizeof (T) >= 8 ? ((T ) str[4 +pos] << ( sizeof (T) >= 8 ? 32 : 0 ) |
144+ (str[4 +pos] && sizeof (T) >= 8 ? ((T ) str[5 +pos] << ( sizeof (T) >= 8 ? 40 : 0 ) |
145+ (str[5 +pos] && sizeof (T) >= 8 ? ((T ) str[6 +pos] << ( sizeof (T) >= 8 ? 48 : 0 ) |
146+ (str[6 +pos] && sizeof (T) >= 8 ? ((T ) str[7 +pos] << ( sizeof (T) >= 8 ? 56 : 0 ) )
101147 : 0 )) : 0 )) : 0 )) : 0 )) : 0 )) : 0 )) : 0 ));
102148}
103149
104- // / constexpr intializer, evaluated at compile time
105- constexpr uint32_t String2uint32 (char c1, char c2, char c3)
150+ // / backward compatibility, can be removed
151+ // / forwards to generic function
152+ constexpr uint64_t String2uint64 (const char * str, int pos=0 )
106153{
107- return (( uint32_t ) c1 | ( uint32_t ) c2 << 8 | ( uint32_t ) c3 << 16 );
154+ return String2< uint64_t >(str, pos );
108155}
109156
110- // / constexpr intializer, evaluated at compile time
111- constexpr uint32_t String2uint32 (const char * str)
157+ // / backward compatibility, can be removed
158+ // / forwards to generic function
159+ constexpr uint32_t String2uint32 (const char * str, int pos=0 )
112160{
113- return ((uint32_t ) str[0 ] |
114- (str[0 ] ? ((uint32_t ) str[1 ] << 8 |
115- (str[1 ] ? ((uint32_t ) str[2 ] << 16 |
116- (str[2 ] ? ((uint32_t ) str[3 ] << 24 )
117- :0 )) : 0 )) : 0 ));
161+ return String2<uint32_t >(str, pos);
118162}
119163
164+
120165// / constexpr intializer, evaluated at compile time
121- constexpr uint32_t CharArr2uint32 (char c1, char c2, char c3, char c4)
166+ // / backward compatibility, might be removed in the future
167+ constexpr uint32_t String2uint32 (char c1, char c2, char c3)
122168{
123- return ((uint32_t ) c1 |
124- (uint32_t ) c2 << 8 |
125- (uint32_t ) c3 << 16 |
126- (uint32_t ) c4 << 24 );
169+ return String2<uint32_t >(c1, c2, c3);
127170}
128171
129172// / constexpr intializer, evaluated at compile time
130- constexpr uint32_t CharArr2uint32 (const char * str)
173+ // / backward compatibility, might be removed in the future
174+ constexpr uint32_t CharArr2uint32 (char c1, char c2, char c3, char c4)
131175{
132- return ((uint32_t ) str[0 ] |
133- (str[0 ] ? ((uint32_t ) str[1 ] << 8 |
134- (str[1 ] ? ((uint32_t ) str[2 ] << 16 |
135- (str[2 ] ? ((uint32_t ) str[3 ] << 24 )
136- : 0 )) : 0 )) : 0 ));
176+ return String2<uint32_t >(c1, c2, c3, c4);
137177}
138178
139179// __________________________________________________________________________________________________
0 commit comments