Skip to content

Commit 28dd8b4

Browse files
Generic initializer methods for string to uint conversions
1 parent 6a3d7b2 commit 28dd8b4

File tree

2 files changed

+73
-33
lines changed

2 files changed

+73
-33
lines changed

DataFormats/Headers/include/Headers/DataHeader.h

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -78,62 +78,102 @@ constexpr uint32_t gSizeHeaderDescriptionString = 8;
7878
struct DataHeader;
7979
struct 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
83126
constexpr 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
//__________________________________________________________________________________________________

DataFormats/Headers/src/DataHeader.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include <cstring> // strncpy
1616

1717
//the answer to life and everything
18-
const uint32_t AliceO2::Header::BaseHeader::sMagicString = CharArr2uint32("O2O2");
18+
const uint32_t AliceO2::Header::BaseHeader::sMagicString = String2<uint32_t>("O2O2");
1919

2020
//possible serialization types
2121
const AliceO2::Header::SerializationMethod AliceO2::Header::gSerializationMethodAny ("*******");

0 commit comments

Comments
 (0)