void shift_to_back_by()

in fatal/container/circular_queue.h [387:428]


  void shift_to_back_by(size_type count, Shifter &&shifter = Shifter()) {
    assert(!queue_.empty());

    FATAL_ASSUME_LE(count, size_);
    if (count == size_) {
      return;
    }
    FATAL_ASSUME_LT(count, size_);

    FATAL_ASSUME_LE(size_, queue_.size());
    if (size_ == queue_.size()) {
      // no empty slots, just need to adjust the offset
      FATAL_ASSUME_LT(offset_, queue_.size());
      auto const gap = queue_.size() - offset_;

      if (count < gap) {
        offset_ += count;
      } else {
        offset_ = count - gap;
      }

      FATAL_ASSUME_LT(offset_, queue_.size());
    } else {
      // empty slots, move back chunk to front
      FATAL_ASSUME_LT(size_, queue_.size());

      while (count--) {
        FATAL_ASSUME_LT(offset_, queue_.size());
        auto &from = queue_[offset_].value;
        shifter(
          std::addressof(queue_[append_index()].value),
          std::move(from)
        );
        from.~value_type();

        if (++offset_ == queue_.size()) {
          offset_ = 0;
        }
        FATAL_ASSUME_LT(offset_, queue_.size());
      }
    }
  }