42 : groups_(identity & mask(
unsigned(4 * ((count + 15) / 16)))),
43 count_(std::uint16_t(count)) {
45 for (std::size_t group = 0; group < (count + 15) / 16; ++group) {
46 const auto n = count - group * 16 < 16 ? count - group * 16 : 16;
47 slots_[group] = identity & mask(
unsigned(n * 4));
48 occupied_[group] = std::uint16_t(mask(
unsigned(n)));
95 std::size_t distance)
noexcept {
96 assert(left <= right && right <=
size());
97 const auto length = right - left;
98 if (length == 0 || (distance %= length) == 0) {
101 if (left / 16 == (right - 1) / 16) {
102 const auto group = physical_group(left / 16);
104 rotate_word(slots_[group], left % 16, (right - 1) % 16 + 1, distance);
107 if (left % 16 == 0 && right % 16 == 0) {
108 const auto begin = left / 16;
109 const auto end = right / 16;
110 const auto remainder = distance % 16;
111 const bool backwards = remainder > 8;
112 groups_ = rotate_word(groups_, begin, end,
113 distance / 16 + std::size_t(backwards));
114 if (remainder == 0) {
117 for (
auto i = begin; i < end; ++i) {
118 auto& word = slots_[physical_group(i)];
119 word = rotate_word(word, 0, 16, remainder);
123 const auto spill = backwards ? 16 - remainder : remainder;
124 for (std::size_t j = 0; j < spill; ++j) {
126 auto* saved = pointers[(*this)[(end - 1) * 16 + j]];
127 for (
auto i = end - 1; i > begin; --i) {
128 pointers[(*this)[i * 16 + j]] = pointers[(*this)[(i - 1) * 16 + j]];
130 pointers[(*this)[begin * 16 + j]] = saved;
132 const auto offset = 16 - spill + j;
133 auto* saved = pointers[(*this)[begin * 16 + offset]];
134 for (
auto i = begin; i + 1 < end; ++i) {
135 pointers[(*this)[i * 16 + offset]] =
136 pointers[(*this)[(i + 1) * 16 + offset]];
138 pointers[(*this)[(end - 1) * 16 + offset]] = saved;
141 return (end - begin) * spill;
143 std::array<void*, capacity> scratch;
144 for (std::size_t i = 0; i < length; ++i) {
145 scratch[i] = pointers[(*this)[left + i]];
147 auto source = distance;
148 for (std::size_t i = 0; i < length; ++i) {
149 pointers[(*this)[left + i]] = scratch[source];
150 if (++source == length) {