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");
61 index.
set(lvl++, val);
105 return ((upper + 1
u) <<
shift(lvl));
113 return (
m_value & ~maskLower) | maskLower;
117 static constexpr std::size_t
bits(std::size_t lvl) {
124 static constexpr std::array<std::size_t, NumLevels>
s_bits{BitsPerLevel...};
125 static constexpr std::size_t
shift(std::size_t lvl) {
128 for (std::size_t
i = (lvl + 1);
i <
s_bits.size(); ++
i) {
148 for (std::size_t lvl = 1; lvl <
NumLevels; ++lvl) {
149 os <<
'|' << idx.
level(lvl);
159 template <
typename Storage, std::size_t... BitsPerLevel>
160 struct hash<Acts::MultiIndex<Storage, BitsPerLevel...>> {
163 return std::hash<Storage>()(
idx.value());