Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Common/include/Luau/InsertionOrderedMap.h
2727 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#pragma once
3
4
#include "Luau/Common.h"
5
6
#include <unordered_map>
7
#include <vector>
8
#include <type_traits>
9
#include <iterator>
10
11
namespace Luau
12
{
13
14
template<typename K, typename V>
15
struct InsertionOrderedMap
16
{
17
static_assert(std::is_trivially_copyable_v<K>, "key must be trivially copyable");
18
19
private:
20
using vec = std::vector<std::pair<K, V>>;
21
22
public:
23
using iterator = typename vec::iterator;
24
using const_iterator = typename vec::const_iterator;
25
26
void insert(K k, V v)
27
{
28
if (indices.count(k) != 0)
29
return;
30
31
pairs.push_back(std::make_pair(k, std::move(v)));
32
indices[k] = pairs.size() - 1;
33
}
34
35
void clear()
36
{
37
pairs.clear();
38
indices.clear();
39
}
40
41
size_t size() const
42
{
43
LUAU_ASSERT(pairs.size() == indices.size());
44
return pairs.size();
45
}
46
47
bool contains(const K& k) const
48
{
49
return indices.count(k) > 0;
50
}
51
52
const V* get(const K& k) const
53
{
54
auto it = indices.find(k);
55
if (it == indices.end())
56
return nullptr;
57
else
58
return &pairs.at(it->second).second;
59
}
60
61
V* get(const K& k)
62
{
63
auto it = indices.find(k);
64
if (it == indices.end())
65
return nullptr;
66
else
67
return &pairs.at(it->second).second;
68
}
69
70
V& operator[](const K& k)
71
{
72
auto it = indices.find(k);
73
if (it == indices.end())
74
{
75
pairs.push_back(std::make_pair(k, V()));
76
indices[k] = pairs.size() - 1;
77
return pairs.back().second;
78
}
79
else
80
return pairs.at(it->second).second;
81
}
82
83
const_iterator begin() const
84
{
85
return pairs.begin();
86
}
87
88
const_iterator end() const
89
{
90
return pairs.end();
91
}
92
93
iterator begin()
94
{
95
return pairs.begin();
96
}
97
98
iterator end()
99
{
100
return pairs.end();
101
}
102
103
const_iterator find(K k) const
104
{
105
auto indicesIt = indices.find(k);
106
if (indicesIt == indices.end())
107
return end();
108
else
109
return begin() + indicesIt->second;
110
}
111
112
iterator find(K k)
113
{
114
auto indicesIt = indices.find(k);
115
if (indicesIt == indices.end())
116
return end();
117
else
118
return begin() + indicesIt->second;
119
}
120
121
void erase(iterator it)
122
{
123
if (it == pairs.end())
124
return;
125
126
K k = it->first;
127
auto indexIt = indices.find(k);
128
if (indexIt == indices.end())
129
return;
130
131
size_t removed = indexIt->second;
132
indices.erase(indexIt);
133
pairs.erase(it);
134
135
for (auto& [_, index] : indices)
136
{
137
if (index > removed)
138
--index;
139
}
140
}
141
142
private:
143
vec pairs;
144
std::unordered_map<K, size_t> indices;
145
};
146
147
} // namespace Luau
148
149