27 using value_type = remove_cvref_t<T>;
28 using reference = value_type&;
29 using const_reference =
const value_type&;
32 using _data_type = std::vector<value_type>;
43 using _to_data_type = std::vector<size_type>;
44 using _to_id_type = std::vector<size_type>;
46 _to_data_type _toData;
51 size_type newSize = _toData.size() + count;
53 _toId.reserve(newSize);
54 _toData.reserve(newSize);
56 for (size_type i = _toData.size(); i < newSize; ++i) {
64 if (_data.size() == size()) { _append_indexes(1); }
65 return _data.insert(_data.cend(), std::forward<U>(value));
71 _data[_toData[id]] = std::forward<U>(value);
72 return std::next(_data.begin(), _toData[id]);
75 _append_indexes(id + 1 - size());
78 auto iter = _data.insert(_data.cend(), std::forward<U>(value));
80 if (_data.size() != size()) {
81 size_type toSwapId = _toId[_data.size() - 1];
84 std::swap(_toId[_data.size() - 1], _toId[id]);
87 std::swap(_toData[toSwapId], _toData[id]);
95 return _insert_at(_toId[std::distance(_data.cbegin(), pos)], std::forward<U>(value));
100 _insert(std::forward<U>(value));
104 iterator iter = end();
105 for (
const auto& idx : indexes) { iter = erase(idx); }
111 _append_indexes(count - size());
112 _data.resize(count, std::forward<U>(value));
123 _MSTD_CONSTEXPR20 stable_vector(
const size_type count,
const value_type& value) { resize(count, value); }
125 _MSTD_CONSTEXPR20 stable_vector(
const size_type count, value_type&& value) { resize(count, std::move(value)); }
127 _MSTD_CONSTEXPR20 stable_vector(std::initializer_list<value_type> init) : _data(init) { _append_indexes(_data.size()); }
130 template<mstd::iterator_of<value_type> Iter>
132 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
135 _append_indexes(_data.size());
143 #pragma region INSERT_ON_FREE_SPOT
145 _MSTD_CONSTEXPR20 iterator insert(
const value_type& value) {
return _insert<
const value_type&>(value); }
150 _append_indexes(count - (size() - _data.size()));
151 return _data.insert(_data.cend(), count, value);
155 template<mstd::iterator_of<value_type> Iter>
157 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
160 size_type count = std::distance(first, last);
161 _append_indexes(count - (size() - _data.size()));
162 return _data.insert(_data.cend(), first, last);
165 _MSTD_CONSTEXPR20 iterator insert(std::initializer_list<value_type> init) {
return insert(init.begin(), init.end()); }
167 #pragma endregion INSERT_ON_FREE_SPOT
169 #pragma region INSERT_AT_IDX
171 _MSTD_CONSTEXPR20 iterator insert_at(
const size_type id,
const value_type& value) {
return _insert_at(id, value); }
173 _MSTD_CONSTEXPR20 iterator insert_at(
const size_type id, value_type&& value) {
return _insert_at(id, std::move(value)); }
175 _MSTD_CONSTEXPR20 iterator insert_at(
const size_type id,
const value_type& value,
const size_type count) {
176 iterator iter = end();
177 for (size_t i = 0; i < count; ++i) { iter = _insert_at(id + i, value); }
182 template<iterator_of<value_type> Iter>
184 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
187 iterator iter = end();
188 for (Iter it = first; it != last; ++it, ++id) { iter = insert_at(id, *it); }
192 _MSTD_CONSTEXPR20 iterator insert_at(
const size_type id, std::initializer_list<value_type> init) {
193 return insert_at(id, init.begin(), init.end());
196 #pragma endregion INSERT_AT_IDX
198 #pragma region INSERT_AT_ITER
200 _MSTD_CONSTEXPR20 iterator insert_at(const_iterator pos,
const value_type& value) {
return _insert_at(pos, value); }
202 _MSTD_CONSTEXPR20 iterator insert_at(const_iterator pos, value_type&& value) {
return _insert_at(pos, std::move(value)); }
204 _MSTD_CONSTEXPR20 iterator insert_at(const_iterator pos,
const value_type& value,
const size_type count) {
205 return _insert_at(_toId[std::distance(_data.cbegin(), pos)], value, count);
209 template<mstd::iterator_of<value_type> Iter>
211 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
214 return insert_at(_toId[std::distance(_data.cbegin(), pos)], first, last);
217 _MSTD_CONSTEXPR20 iterator insert_at(const_iterator pos, std::initializer_list<value_type> init) {
218 return insert_at(pos, init.begin(), init.end());
221 #pragma endregion INSERT_AT_ITER
223 #pragma region EMPLACE_ON_FREE_SPOT
226 template<
class... Args>
228 template<
class... Args, std::enable_if_t<std::is_constructible_v<value_type, Args...>,
bool> =
true>
231 return insert(value_type(std::forward<Args>(args)...));
236 #pragma region EMPLACE_AT_IDX
239 template<
class... Args>
241 template<
class... Args, std::enable_if_t<std::is_constructible_v<value_type, Args...>,
bool> =
true>
244 Args&&... args)
_MSTD_REQUIRES((std::constructible_from<value_type, Args...>)) {
245 return insert_at(id, value_type(std::forward<Args>(args)...));
250 #pragma region EMPLACE_AT_ITER
253 template<
class... Args>
255 template<
class... Args, std::enable_if_t<std::is_constructible_v<value_type, Args...>,
bool> =
true>
258 Args&&... args)
_MSTD_REQUIRES((std::constructible_from<value_type, Args...>)) {
259 return insert_at(pos, value_type(std::forward<Args>(args)...));
265 template<
class... Args>
267 template<
class... Args, std::enable_if_t<std::is_constructible_v<value_type, Args...>,
bool> =
true>
271 )
_MSTD_REQUIRES((std::constructible_from<value_type, Args...>)) {
272 return *emplace(std::forward<Args>(args)...);
281 if (!has_value(id)) {
return _data.end(); }
284 size_t dataIndex = _toData[id];
285 size_t lastDataIndex = _data.size() - 1;
288 std::swap(_data[dataIndex], _data[lastDataIndex]);
291 std::swap(_toId[dataIndex], _toId[lastDataIndex]);
297 std::swap(_toData[_toId[dataIndex]], _toData[id]);
303 while (!_toData.empty() && !has_value(_toData.size() - 1)) {
304 size_t lastId = _toData.size() - 1;
306 size_t posInToId = _toData[lastId];
307 size_t lastPosInToId = _toId.size() - 1;
309 if (posInToId != lastPosInToId) {
310 size_t idAtLastPos = _toId[lastPosInToId];
312 std::swap(_toId[posInToId], _toId[lastPosInToId]);
313 std::swap(_toData[lastId], _toData[idAtLastPos]);
324 iterator iter = end();
325 for (size_t i = firstId; i < endId; ++i) { iter = erase(i); }
330 mstd_assert(pos != _data.end(),
"Pos out of bounds");
331 return erase(get_id(pos));
335 mstd_assert(pos != _data.cend(),
"Pos out of bounds");
336 return erase(get_id(pos));
340 std::vector<size_t> idsToErase = {};
341 idsToErase.reserve(std::distance(first, last));
343 for (iterator it = first; it != last; ++it) { idsToErase.push_back(get_id(it)); }
345 return _erase(idsToErase);
349 std::vector<size_t> idsToErase = {};
350 idsToErase.reserve(std::distance(first, last));
352 for (const_iterator it = first; it != last; ++it) { idsToErase.push_back(get_id(it)); }
354 return _erase(idsToErase);
358 _toData.reserve(capacity);
359 _toId.reserve(capacity);
360 _data.reserve(capacity);
364 _append_indexes(count - size());
368 _MSTD_CONSTEXPR20 void resize(
const size_type count,
const value_type& value) { _resize(count, value); }
370 _MSTD_CONSTEXPR20 void resize(
const size_type count, value_type&& value) { _resize(count, std::move(value)); }
373 _data.swap(other._data);
374 _toId.swap(other._toId);
375 _toData.swap(other._toData);
394 mstd_assert(has_value(id),
"Index is a pointer to empty element");
396 return std::next(begin(), _toData[id]);
401 mstd_assert(has_value(id),
"Index is a pointer to empty element");
403 return std::next(cbegin(), _toData[id]);
408 if (has_value(id)) {
return get(id); }
414 if (has_value(id)) {
return get(id); }
420 mstd_assert(has_value(id),
"Index is a pointer to empty element");
422 return _data[_toData[id]];
427 mstd_assert(has_value(id),
"Index is a pointer to empty element");
429 return _data[_toData[id]];
434 if (has_value(id)) {
return &at(id); }
440 if (has_value(id)) {
return &at(id); }
446 [[nodiscard]]
_MSTD_CONSTEXPR20 size_type back_id()
const {
return get_id(active_slots() - 1); }
449 if (empty_slots() != 0) {
return get_id(active_slots()); }
454 mstd_assert(dataIndex < size(),
"Data index out of bounds");
455 return _toId[dataIndex];
459 mstd_assert(pos != _data.end(),
"Pos out of bounds");
460 return get_id(std::distance(_data.begin(), pos));
464 mstd_assert(pos != _data.cend(),
"Pos out of bounds");
465 return get_id(std::distance(_data.cbegin(), pos));
470 [[nodiscard]]
_MSTD_CONSTEXPR17 size_type empty_slots()
const {
return size() - active_slots(); }
481 return id < size() && _toData[id] < _data.size();
484 [[nodiscard]]
_MSTD_CONSTEXPR20 bool has_value(iterator pos)
const {
return has_value(get_id(pos)); }
486 [[nodiscard]]
_MSTD_CONSTEXPR20 bool has_value(const_iterator pos)
const {
return has_value(get_id(pos)); }
502 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator rbegin()
const {
return _data.rbegin(); }
508 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator crbegin()
const {
return _data.crbegin(); }
514 [[nodiscard]]
_MSTD_CONSTEXPR20 const value_type& operator[](
const size_type id)
const {
return at(id); }
516 [[nodiscard]] value_type* data() {
return _data.data(); }
518 [[nodiscard]]
const value_type* data()
const {
return _data.data(); }
525 return _data == other._data && _toId == other._toId && _toData == other._toData;
534 return !(*
this == other);
539 [[nodiscard]] _MSTD_CONSTEXPR20
auto operator<=>(
const stable_vector& other)
const =
default;
541 [[nodiscard]]
_MSTD_CONSTEXPR20 bool operator<(
const stable_vector& other)
const {
542 return _data < other._data && _toId < other._toId && _toData < other._toData;
545 [[nodiscard]]
_MSTD_CONSTEXPR20 bool operator<=(
const stable_vector& other)
const {
546 return _data <= other._data && _toId <= other._toId && _toData <= other._toData;
549 [[nodiscard]]
_MSTD_CONSTEXPR20 bool operator>(
const stable_vector& other)
const {
550 return _data > other._data && _toId > other._toId && _toData > other._toData;
553 [[nodiscard]]
_MSTD_CONSTEXPR20 bool operator>=(
const stable_vector& other)
const {
554 return _data >= other._data && _toId >= other._toId && _toData >= other._toData;