26 using key_type = remove_cvref_t<Key>;
27 using mapped_type = remove_cvref_t<T>;
28 using value_type = std::pair<key_type, mapped_type>;
29 using reference = value_type&;
30 using const_reference =
const value_type&;
33 using _data_type = std::vector<value_type>;
44 using _map_type = std::unordered_map<key_type, size_type>;
46 _data_type _orderedElements;
47 _map_type _elementsMap;
50 static_assert(std::is_copy_constructible_v<key_type>,
"Key is not copy constructible!");
51 for (size_type i = from; i != _orderedElements.size(); ++i) { _elementsMap[_orderedElements[i].first] = i; }
54 template<
class UK,
class U>
56 return _insert(where, std::make_pair(std::forward<UK>(key), std::forward<U>(value)));
59 template<
class UK,
class U>
61 return _emplace(cend(), std::forward<UK>(key), std::forward<U>(value));
66 const key_type key = value.first;
69 size_type whereOffset = std::distance(_orderedElements.cbegin(), where);
71 _orderedElements.insert(where, std::forward<U>(value));
73 _update_indexes(whereOffset);
75 return _orderedElements.at(_elementsMap.at(key)).second;
79 size_type whereOffset =
80 std::clamp<size_type>(std::distance(_orderedElements.cbegin(), where), 0, _orderedElements.size() - 1);
81 const size_type& elemOffset = _elementsMap.at(key);
84 _orderedElements.erase(std::next(_orderedElements.begin(), elemOffset));
87 _orderedElements.insert(std::next(_orderedElements.begin(), whereOffset), std::forward<U>(value));
90 if (whereOffset > elemOffset) { _update_indexes(elemOffset); }
91 else { _update_indexes(whereOffset); }
93 return _orderedElements.at(_elementsMap.at(key)).second;
98 return _insert(cend(), std::forward<U>(value));
103 if (!contains(std::forward<UK>(key))) {
return; }
105 size_type elementOffset = _elementsMap.at(std::forward<UK>(key));
107 _orderedElements.erase(std::next(_orderedElements.begin(), elementOffset));
108 _elementsMap.erase(std::forward<UK>(key));
110 _update_indexes(elementOffset);
116 mstd_assert(contains(std::forward<UK>(key)),
"Key '{}' not found", std::forward<UK>(key));
118 else { mstd_assert(contains(std::forward<UK>(key)),
"Key not found"); }
119 return _orderedElements.at(_elementsMap.at(std::forward<UK>(key))).second;
125 mstd_assert(contains(std::forward<UK>(key)),
"Key '{}' not found", std::forward<UK>(key));
127 else { mstd_assert(contains(std::forward<UK>(key)),
"Key not found"); }
128 return _orderedElements.at(_elementsMap.at(std::forward<UK>(key))).second;
134 return _elementsMap.contains(std::forward<UK>(key));
136 return _elementsMap.find(std::forward<UK>(key)) != _elementsMap.end();
142 auto it = _elementsMap.find(std::forward<UK>(key));
143 return it != _elementsMap.end() ? std::next(_orderedElements.begin(), it->second) : _orderedElements.end();
148 auto it = _elementsMap.find(std::forward<UK>(key));
149 return it != _elementsMap.end() ? std::next(_orderedElements.begin(), it->second) : _orderedElements.end();
155 if (it == end()) {
return emplace_back(std::forward<UK>(key), mapped_type()); }
165 _MSTD_CONSTEXPR20 ordered_map(std::initializer_list<value_type> init) { insert_back(init.begin(), init.end()); }
168 template<mstd::iterator_of<value_type> Iter>
170 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
173 insert_back(begin, end);
181 _MSTD_CONSTEXPR20 mapped_type& emplace(const_iterator where,
const key_type& key,
const mapped_type& value) {
182 return _emplace(where, key, value);
185 _MSTD_CONSTEXPR20 mapped_type& emplace(const_iterator where, key_type&& key, mapped_type&& value) {
186 return _emplace(where, std::move(key), std::move(value));
190 return _emplace_back(key, value);
194 return _emplace_back(std::move(key), std::move(value));
197 _MSTD_CONSTEXPR20 mapped_type& insert(const_iterator where,
const value_type& value) {
return _insert(where, value); }
200 return _insert(where, std::move(value));
204 template<mstd::iterator_of<value_type> Iter>
206 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
209 size_t currWhereOffset = std::distance(_orderedElements.cbegin(), where);
210 for (Iter iter = begin; iter != end; ++iter, ++currWhereOffset) {
211 currWhereOffset = std::clamp<size_t>(currWhereOffset, 0, _orderedElements.size());
212 insert(std::next(_orderedElements.begin(), currWhereOffset), *iter);
217 insert(where, init.begin(), init.end());
220 _MSTD_CONSTEXPR20 mapped_type& insert_back(
const value_type& value) {
return _insert_back(value); }
222 _MSTD_CONSTEXPR20 mapped_type& insert_back(value_type&& value) {
return _insert_back(std::move(value)); }
225 template<mstd::iterator_of<value_type> Iter>
227 template<
class Iter, std::enable_if_t<is_iterator_of_v<Iter, value_type>,
bool> =
true>
230 insert(cend(), begin, end);
233 _MSTD_CONSTEXPR20 void insert_back(std::initializer_list<value_type> init) { insert_back(init.begin(), init.end()); }
243 [[nodiscard]]
_MSTD_CONSTEXPR20 const mapped_type& at(
const key_type& key)
const {
return _at(key); }
245 [[nodiscard]]
_MSTD_CONSTEXPR20 const mapped_type& at(key_type&& key)
const {
return _at(std::move(key)); }
251 [[nodiscard]]
_MSTD_CONSTEXPR20 bool contains(
const key_type& key)
const {
return _contains(key); }
253 [[nodiscard]]
_MSTD_CONSTEXPR20 bool contains(key_type&& key)
const {
return _contains(std::move(key)); }
259 [[nodiscard]]
_MSTD_CONSTEXPR20 const_iterator find(
const key_type& key)
const {
return _find(key); }
261 [[nodiscard]]
_MSTD_CONSTEXPR20 const_iterator find(key_type&& key)
const {
return _find(std::move(key)); }
264 _elementsMap.clear();
265 _orderedElements.clear();
272 [[nodiscard]]
_MSTD_CONSTEXPR20 const_iterator begin()
const {
return _orderedElements.cbegin(); }
276 [[nodiscard]]
_MSTD_CONSTEXPR20 const_iterator cbegin()
const {
return _orderedElements.cbegin(); }
284 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator rbegin()
const {
return _orderedElements.crbegin(); }
286 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator rend()
const {
return _orderedElements.crend(); }
288 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator crbegin()
const {
return _orderedElements.crbegin(); }
290 [[nodiscard]]
_MSTD_CONSTEXPR20 const_reverse_iterator crend()
const {
return _orderedElements.crend(); }
293 if _MSTD_CONSTEXPR17 (std::is_default_constructible_v<mapped_type>) {
return _at_with_construct(key); }
294 else {
return _at(key); }
298 if _MSTD_CONSTEXPR17 (std::is_default_constructible_v<mapped_type>) {
return _at_with_construct(std::move(key)); }
299 else {
return _at(std::move(key)); }
302 [[nodiscard]]
_MSTD_CONSTEXPR20 const mapped_type& operator[](
const key_type& key)
const {
return _at(key); }
304 [[nodiscard]]
_MSTD_CONSTEXPR20 const mapped_type& operator[](key_type&& key)
const {
return _at(std::move(key)); }
307 return _orderedElements == other._orderedElements && _elementsMap == other._elementsMap;
310 [[nodiscard]]
_MSTD_CONSTEXPR20 bool operator!=(
const ordered_map& other)
const {
return !(*
this == other); }