1
+ #pragma once
2
+
3
+ #include < iostream>
4
+ #include < algorithm>
5
+ #include < functional>
6
+ #include < string>
7
+ #include < sstream>
8
+ #include < initializer_list>
9
+
10
+ const int newCells = 4 ;
11
+
12
+ template <typename KeyT, typename ValueT>
13
+ struct object {
14
+ KeyT key;
15
+ ValueT value;
16
+ };
17
+
18
+ template <typename KeyT, typename ValueT,
19
+ class Compare = std::less<KeyT>,
20
+ class Allocator = std::allocator<object<KeyT, ValueT>>>
21
+ class FlatMap {
22
+ Allocator alloc;
23
+ object<KeyT, ValueT>* map;
24
+ int capacity;
25
+ int count;
26
+
27
+ using traits = std::allocator_traits<decltype(alloc)>;
28
+
29
+ static int binSearch (object<KeyT, ValueT> arr[], int low, int high, const KeyT& x, Compare comp = Compare());
30
+ static void shift (object<KeyT, ValueT>* place, int border, int index, const std::string& mode);
31
+
32
+ template <typename KeyTS, typename ValueTS>
33
+ friend void swap (FlatMap<KeyTS, ValueTS>& m1, FlatMap<KeyTS, ValueTS>& m2);
34
+
35
+ public:
36
+ FlatMap ();
37
+ FlatMap (const FlatMap& other_map);
38
+ ~FlatMap ();
39
+
40
+ FlatMap& operator = (const FlatMap& other_map);
41
+ [[nodiscard]] std::size_t size () const ;
42
+ ValueT& operator [] (const KeyT& key);
43
+
44
+ bool contains (const KeyT& key);
45
+ std::size_t erase (const KeyT& key);
46
+ void clear ();
47
+
48
+ FlatMap (FlatMap&& x) noexcept ;
49
+ FlatMap& operator = (FlatMap&& x) noexcept ;
50
+
51
+ object<KeyT, ValueT>* begin ();
52
+ object<KeyT, ValueT>* end ();
53
+ object<KeyT, ValueT>* find (const KeyT& x);
54
+
55
+ };
56
+
57
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
58
+ int FlatMap<KeyT, ValueT, Compare, Allocator>::binSearch(object<KeyT, ValueT> arr[], int low, int high, const KeyT& x, Compare comp) {
59
+ while (low <= high) {
60
+ int mid = low + (high - low) / 2 ;
61
+
62
+ if (arr[mid].key == x) {
63
+ return mid;
64
+ }
65
+
66
+ if (comp (arr[mid].key , x)) {
67
+ low = mid + 1 ;
68
+ }
69
+ else {
70
+ high = mid - 1 ;
71
+ }
72
+ }
73
+
74
+ return (-1 * low - 1 );
75
+ }
76
+
77
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
78
+ void FlatMap<KeyT, ValueT, Compare, Allocator>::shift(object<KeyT, ValueT>* place, int border, int index, const std::string& mode) {
79
+ if (mode == " r" ) {
80
+ int end = border;
81
+
82
+ while (end != index ) {
83
+ place[end] = place[end - 1 ];
84
+ end--;
85
+ }
86
+ }
87
+ else {
88
+ int begin = index ;
89
+
90
+ while (begin != border - 1 ) {
91
+ place[begin] = place[begin + 1 ];
92
+ begin++;
93
+ }
94
+ }
95
+ }
96
+
97
+ template <typename KeyTS, typename ValueTS>
98
+ void swap (FlatMap<KeyTS, ValueTS>& m1, FlatMap<KeyTS, ValueTS>& m2) {
99
+ using std::swap;
100
+
101
+ swap (m1.map , m2.map );
102
+ swap (m1.capacity , m2.capacity );
103
+ swap (m1.count , m2.count );
104
+ }
105
+
106
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
107
+ FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap() : capacity{ newCells }, count { 0 } {
108
+ // map = new object<KeyT, ValueT>[newCells];
109
+ map = traits::allocate (alloc, newCells);
110
+ for (int i = 0 ; i < newCells; ++i) {
111
+ traits::construct (alloc, map + i, object<KeyT, ValueT>());
112
+ }
113
+ }
114
+
115
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
116
+ FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap(const FlatMap& other_map) : capacity{ other_map.capacity }, count{ other_map.count } {
117
+ // map = new object<KeyT, ValueT>[other_map.capacity];
118
+ map = traits::allocate (alloc, other_map.capacity );
119
+ for (int i = 0 ; i < other_map.capacity ; ++i) {
120
+ traits::construct (alloc, map + i, object<KeyT, ValueT>());
121
+ }
122
+
123
+ std::copy (other_map.map , other_map.map + other_map.count , map);
124
+ }
125
+
126
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
127
+ FlatMap<KeyT, ValueT, Compare, Allocator>::~FlatMap () {
128
+ // delete[] map;
129
+
130
+ for (int i = 0 ; i < capacity; ++i) {
131
+ traits::destroy (alloc, map + i);
132
+ }
133
+
134
+ }
135
+
136
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
137
+ FlatMap<KeyT, ValueT, Compare, Allocator>& FlatMap<KeyT, ValueT, Compare, Allocator>::operator =(const FlatMap& other_map) {
138
+ if (this == &other_map) {
139
+ return *this ;
140
+ }
141
+
142
+ FlatMap copy (other_map);
143
+ swap (copy, *this );
144
+
145
+ return *this ;
146
+ }
147
+
148
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
149
+ std::size_t FlatMap<KeyT, ValueT, Compare, Allocator>::size() const {
150
+ return count;
151
+ }
152
+
153
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
154
+ ValueT& FlatMap<KeyT, ValueT, Compare, Allocator>::operator [] (const KeyT& key) {
155
+ if (capacity == 0 ) {
156
+ FlatMap copy (*this );
157
+
158
+ // copy.map = new object<KeyT, ValueT>[newCells];
159
+ copy.map = traits::allocate (alloc, newCells);
160
+ for (int i = 0 ; i < newCells; ++i) {
161
+ traits::construct (alloc, copy.map + i, object<KeyT, ValueT>());
162
+ }
163
+
164
+ copy.capacity = newCells;
165
+
166
+ swap (copy, *this );
167
+ }
168
+
169
+ if (count == 0 ) {
170
+ map[0 ].key = key;
171
+ count++;
172
+
173
+ return map[0 ].value ;
174
+ }
175
+
176
+ if (count == capacity) {
177
+ FlatMap copy (*this );
178
+
179
+ // auto altMap = new object<KeyT, ValueT>[copy.capacity + newCells];
180
+ auto altMap = traits::allocate (alloc, copy.capacity + newCells);
181
+ for (int i = 0 ; i < copy.capacity + newCells; ++i) {
182
+ traits::construct (alloc, map + i, object<KeyT, ValueT>());
183
+ }
184
+
185
+ std::copy (copy.map , copy.map + copy.count , altMap);
186
+
187
+ // delete[] copy.map;
188
+ for (int i = 0 ; i < copy.capacity ; ++i) {
189
+ traits::destroy (alloc, copy.map + i);
190
+ }
191
+
192
+ copy.map = altMap;
193
+ copy.capacity += newCells;
194
+
195
+ swap (copy, *this );
196
+ }
197
+
198
+ int id = binSearch (map, 0 , count - 1 , key);
199
+
200
+ if (id < 0 ) {
201
+ id = (id + 1 ) * -1 ;
202
+
203
+ shift (map, count, id, " r" );
204
+
205
+ map[id].key = key;
206
+ count++;
207
+ }
208
+
209
+ return map[id].value ;
210
+ }
211
+
212
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
213
+ bool FlatMap<KeyT, ValueT, Compare, Allocator>::contains(const KeyT& key) {
214
+ if (count == 0 ) {
215
+ return false ;
216
+ }
217
+
218
+ return binSearch (map, 0 , count - 1 , key) >= 0 ;
219
+ }
220
+
221
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
222
+ std::size_t FlatMap<KeyT, ValueT, Compare, Allocator>::erase(const KeyT& key) {
223
+ if (count == 0 ) {
224
+ return 0 ;
225
+ }
226
+
227
+ int id = binSearch (map, 0 , count - 1 , key);
228
+
229
+ if (id < 0 ) {
230
+ return 0 ;
231
+ }
232
+ else {
233
+ shift (map, count, id, " l" );
234
+
235
+ map[count - 1 ].key = KeyT ();
236
+ map[count - 1 ].value = ValueT ();
237
+ count--;
238
+
239
+ return 1 ;
240
+ }
241
+ }
242
+
243
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
244
+ void FlatMap<KeyT, ValueT, Compare, Allocator>::clear() {
245
+ while (count > 0 ) {
246
+ map[count - 1 ].key = KeyT ();
247
+ map[count - 1 ].value = ValueT ();
248
+
249
+ count--;
250
+ }
251
+ }
252
+
253
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
254
+ FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap(FlatMap&& x) noexcept : map{ x.map }, capacity{ x.capacity }, count{ x.count } {
255
+ x.map = nullptr ;
256
+ x.capacity = 0 ;
257
+ x.count = 0 ;
258
+ }
259
+
260
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
261
+ FlatMap<KeyT, ValueT, Compare, Allocator>& FlatMap<KeyT, ValueT, Compare, Allocator>::operator =(FlatMap&& x) noexcept {
262
+ if (this == &x) {
263
+ return *this ;
264
+ }
265
+
266
+ FlatMap copy (std::move (x));
267
+ swap (copy, *this );
268
+
269
+ return *this ;
270
+ }
271
+
272
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
273
+ typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::begin() {
274
+ return map;
275
+ }
276
+
277
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
278
+ typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::end() {
279
+ return map + count;
280
+ }
281
+
282
+ template <typename KeyT, typename ValueT, class Compare , class Allocator >
283
+ typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::find(const KeyT& x) {
284
+ if (count == 0 ) {
285
+ return map;
286
+ }
287
+
288
+ int id = binSearch (map, 0 , count - 1 , x);
289
+
290
+ return id < 0 ? map + count : map + id;
291
+ }
0 commit comments