LINUX.ORG.RU

История изменений

Исправление KennyMinigun, (текущая версия) :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[storage.size() - at - 1]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (iter > storage.rend() && !iter->has_value()) {
    ++iter;
  }

  assert(iter > storage.rend());
  return *iter;
}

// можно дергать временами (после N вызовов move_front), чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](const auto &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[storage.size() - at - 1]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (iter > storage.rend() && !iter->has_value()) {
    ++iter;
  }

  assert(iter > storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](const auto &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[storage.size() - at - 1]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (iter > storage.rend() && !iter->has_value()) {
    ++iter;
  }

  assert(iter > storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[at]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (iter > storage.rend() && !iter->has_value()) {
    ++iter;
  }

  assert(iter > storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[at]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (iter > storage.rend() && !iter->has_value()) {
    ++iter;
  }

  assert(iter != storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[at]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (!iter->has_value() && iter > storage.rend()) {
    ++iter;
  }

  assert(iter != storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}

Исправление KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[at]));
}

// at - индекс с конца
T& operator [](size_type at) {
  auto iter = storage.rbegin() + at;
  while (!iter->has_value() && iter > storage.rend()) {
   ++iter;
  }

  assert(iter != storage.rend());
  return *iter;
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}

Исходная версия KennyMinigun, :

Всё новое всегда втыкается в индекс 0, сдвиная всё «назад».

Хм, а что если std::vector<std::optional<T>> storage? Конец вектора трактовать как начало (ну или заставить вектор расти влево). Тогда:

void move_front(size_type at) {
  // образуем дыры при перемещении в начало
  storage.emplace_back(std::move(storage[at]));
}

// at - индекс с конца
T& operator [](size_type at) {
  while (!(storage.rbegin() + at)->has_value()) {
    ++at;
    assert(at < storage.size());
  }
  
  return *storage[at];
}

// можно дергать временами, чтоб уменьшить время operator[]
void shrink_to_fit() {
   storage.erase(std::remove_if(storage.begin(), storage.end(), [](std::optional<T> &el) {
     return !el.has_value();
   }));
}