15 #include <type_traits>
28 template <
typename T, std::size_t... BitsPerLevel>
31 static_assert(std::is_integral_v<T> and std::is_unsigned_v<T>,
32 "The underlying storage type must be an unsigned integer");
33 static_assert(0 <
sizeof...(BitsPerLevel),
34 "At least one level must be defined");
35 static_assert((
sizeof(
T) * CHAR_BIT) == (... + BitsPerLevel),
36 "The sum of bits per level must match the underlying storage");
53 template <
typename... Us>
56 "Can only encode as many levels as in the MultiIndex");
60 for (
Value val : std::array<
Value,
sizeof...(Us)>{
us...}) {
61 index.
set(lvl++, val);
84 assert((lvl <
NumLevels) and
"Index level outside allowed range");
89 assert((lvl <
NumLevels) and
"Index level outside allowed range");
101 assert((lvl <
NumLevels) and
"Index level outside allowed range");
105 return ((upper + 1
u) <<
shift(lvl));
109 assert((lvl <
NumLevels) and
"Index level outside allowed range");
113 return (
m_value & ~maskLower) | maskLower;
118 static constexpr std::array<std::size_t, NumLevels>
s_bits{BitsPerLevel...};
119 static constexpr std::size_t
shift(std::size_t lvl) {
122 for (std::size_t i = (lvl + 1); i <
s_bits.size(); ++i) {
142 for (std::size_t lvl = 1; lvl <
NumLevels; ++lvl) {
143 os <<
'|' << idx.
level(lvl);
153 template <
typename Storage, std::size_t... BitsPerLevel>
154 struct hash<Acts::MultiIndex<Storage, BitsPerLevel...>> {
157 return std::hash<Storage>()(
idx.value());