1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef UTILS_BASE_SORTED_VECTOR_H
17 #define UTILS_BASE_SORTED_VECTOR_H
18
19 #include <algorithm>
20 #include <functional>
21 #include <iostream>
22 #include <sys/types.h>
23 #include <vector>
24
25 namespace OHOS {
26
27 /**
28 * @brief Provides a sorted vector, in which all items are sorted automatically.
29 */
30 template <class TYPE, bool AllowDuplicate = true>
31 class SortedVector {
32 public:
33 using value_type = TYPE;
34 using size_type = std::size_t;
35 using iterator = typename std::vector<TYPE>::iterator;
36 using const_iterator = typename std::vector<TYPE>::const_iterator;
37
38 /**
39 * @brief Creates a `SortedVector` object.
40 */
41 SortedVector();
42
43 SortedVector(const SortedVector<TYPE, false>& rhs);
44
45 SortedVector(const SortedVector<TYPE, true>& rhs);
46
47 SortedVector(const std::vector<TYPE>& orivect);
48
49 /**
50 * @brief Destroys this `SortedVector` object.
51 */
~SortedVector()52 virtual ~SortedVector() {}
53
54 /**
55 * @brief An overloaded assignment operator function that assigns a sorted
56 * vector to this vector.
57 *
58 * @param TYPE Indicates the type of items.
59 * @param AllowDuplicate Specifies whether duplicated items are allowed.
60 */
61 SortedVector<TYPE, AllowDuplicate>& operator=(const SortedVector<TYPE, false>& rhs);
62 SortedVector<TYPE, AllowDuplicate>& operator=(const SortedVector<TYPE, true>& rhs);
63
64 /**
65 * @brief Clears this vector.
66 */
Clear()67 inline void Clear() { vec_.clear(); }
68
69 /**
70 * @brief Obtains the number of items in this vector.
71 */
Size()72 inline size_t Size() const { return vec_.size(); }
73
74 /**
75 * @brief Checks whether this vector is empty.
76 *
77 * @return Returns `true` if the vector is empty; returns `false` otherwise.
78 */
IsEmpty()79 inline bool IsEmpty() const { return vec_.empty(); }
80
81 /**
82 * @brief Obtains the capacity of this vector, that is, the number of items
83 * that can be stored before the system reallocates new storage space.
84 */
Capacity()85 inline size_t Capacity() const { return vec_.capacity(); }
86
87 /**
88 * @brief Sets the capacity of this vector.
89 *
90 * @param size Indicates the capacity to set.
91 *
92 * @return Returns the capacity if the operation is successful;
93 * returns `CAPACITY_NOT_CHANGED`(-1) otherwise.
94 */
SetCapcity(size_t size)95 ssize_t SetCapcity(size_t size)
96 {
97 if (size < vec_.capacity()) {
98 return CAPCITY_NOT_CHANGED;
99 }
100
101 vec_.reserve(size);
102 return size;
103 }
104
105 // Cstyle access
106 /**
107 * @brief Accesses the first item in this vector.
108 *
109 * @return Returns a constant pointer to the first item.
110 */
Array()111 inline const TYPE* Array() const { return vec_.data(); }
112
113 /**
114 * @brief Accesses the first item in this vector while editing it.
115 *
116 * @note When using this function, you should ensure that the vector
117 * is sorted.
118 *
119 * @return Returns a non-constant pointer to the first item.
120 */
EditArray()121 TYPE* EditArray() { return vec_.data(); }
122
123 /**
124 * @brief Obtains the index of the first occurrence of an item
125 * in this vector.
126 *
127 * @param item Indicates the item.
128 *
129 * @return Returns the index if the item is found;
130 * returns `NOT_FOUND`(-1) otherwise.
131 *
132 */
133 ssize_t IndexOf(const TYPE& item) const;
134
135 /**
136 * @brief Obtains the index where an item should be inserted into
137 * this vector.
138 *
139 * @param item Indicates the item.
140 *
141 * @return Returns the index.
142 */
143 size_t OrderOf(const TYPE& item) const;
144
145 /**
146 * @brief Accesses an item with the specified index.
147 *
148 * @param index Indicates the index.
149 *
150 * @return Returns the item value.
151 */
152 inline const TYPE& operator[](size_t index) const { return vec_[index]; }
153
154 /**
155 * @brief Obtains the reference to the last item in this vector.
156 *
157 * @return Returns the reference to the last item.
158 */
Back()159 const TYPE& Back() const { return vec_.back(); }
160
161 /**
162 * @brief Obtains the reference to the first item in this vector.
163 *
164 * @return Returns the reference to the first item.
165 */
Front()166 const TYPE& Front() const { return vec_.front(); }
167
168 /**
169 * @brief Removes the last item from this vector.
170 */
PopBack()171 void PopBack() { return vec_.pop_back(); }
172
173 /**
174 * @brief Obtains the value of an item with the specified index
175 * in this vector.
176 *
177 * @param index Indicates the index.
178 *
179 * @return Returns vector[vector.size() + `index`] if `index` is
180 * less than 0; returns vector[`index`] otherwise.
181 */
MirrorItemAt(ssize_t index)182 const TYPE& MirrorItemAt(ssize_t index) const
183 {
184 if (index < 0) {
185 return *(vec_.end() + index);
186 }
187 return *(vec_.begin() + index);
188 };
189
190 // Modify the array.
191 /**
192 * @brief Adds an item to this vector.
193 *
194 * @return Returns the index of the item if the operation is successful;
195 * returns `ADD_FAIL`(-1) otherwise.
196 */
197 ssize_t Add(const TYPE& item);
198
199 /**
200 * @brief Obtains the reference to an item with the specified index
201 * in this vector.
202 *
203 * @param index Indicates the index.
204 *
205 * @return Returns the reference to the item.
206 */
EditItemAt(size_t index)207 TYPE& EditItemAt(size_t index)
208 {
209 return vec_[index];
210 }
211
212 /**
213 * @brief Merges a vector into this vector.
214 *
215 * If `AllowDuplicate` is set to `false`, the current vector should
216 * perform deduplication.
217 *
218 * @param invec Indicates the vector to be merged.
219 *
220 * @return Returns the size of the merged vector.
221 */
222 size_t Merge(const std::vector<TYPE>& invec);
223 size_t Merge(const SortedVector<TYPE, AllowDuplicate>& sortedVector);
224
225 /**
226 * @brief Erases the item with the specified index from this vector.
227 *
228 * @param index Indicates the index.
229 *
230 * @return Returns an iterator to the last item if the index is
231 * greater than or equal to the size of the vector;
232 * returns the item next to the deleted item otherwise.
233 */
Erase(size_t index)234 iterator Erase(size_t index)
235 {
236 if (index >= vec_.size()) {
237 return vec_.end();
238 }
239 return vec_.erase(vec_.begin() + index);
240 }
241
242 /**
243 * @brief Obtains an iterator of the non-const type to the first item
244 * in this vector.
245 *
246 * @return Returns an iterator to the first item.
247 */
Begin()248 iterator Begin()
249 {
250 return vec_.begin();
251 }
252
253 /**
254 * @brief Obtains an iterator of the const type to the first item
255 * in this vector.
256 *
257 * @return Returns an iterator to the first item.
258 */
Begin()259 const_iterator Begin() const
260 {
261 return vec_.begin();
262 }
263
264 /**
265 * @brief Obtains an iterator of the non-const type to the last item
266 * in this vector.
267 *
268 * @return Returns an iterator to the last item.
269 */
End()270 iterator End()
271 {
272 return vec_.end();
273 }
274
275 /**
276 * @brief Obtains an iterator of the const type to the last item
277 * in this vector.
278 *
279 * @return Returns an iterator to the last item.
280 */
End()281 const_iterator End() const
282 {
283 return vec_.end();
284 }
285
286 static const ssize_t NOT_FOUND = -1;
287 static const ssize_t ADD_FAIL = -1;
288 static const ssize_t CAPCITY_NOT_CHANGED = -1;
289
290 private:
291 std::vector<TYPE> vec_;
292 };
293
294 template <class TYPE, bool AllowDuplicate>
SortedVector()295 inline SortedVector<TYPE, AllowDuplicate>::SortedVector()
296 : vec_() {}
297
298 template <class TYPE, bool AllowDuplicate>
SortedVector(const SortedVector<TYPE,false> & rhs)299 SortedVector<TYPE, AllowDuplicate>::SortedVector(const SortedVector<TYPE, false>& rhs)
300 {
301 // this class: AllowDuplicate or Not AllowDuplicate same type
302 std::copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
303 }
304
305 template <class TYPE, bool AllowDuplicate>
SortedVector(const SortedVector<TYPE,true> & rhs)306 SortedVector<TYPE, AllowDuplicate>::SortedVector(const SortedVector<TYPE, true>& rhs)
307 {
308 if (AllowDuplicate) {
309 std::copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
310 } else {
311 // AllowDuplicate to Not AllowDuplicate
312 std::unique_copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
313 }
314 }
315
316 // copy operator
317 template <class TYPE, bool AllowDuplicate>
318 SortedVector<TYPE, AllowDuplicate>& SortedVector<TYPE, AllowDuplicate>::operator=(const SortedVector<TYPE, false>& rhs)
319 {
320 // this class: AllowDuplicate or Not AllowDuplicate same type
321 vec_.clear();
322 std::copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
323 return *this;
324 }
325
326 // copy operator
327 template <class TYPE, bool AllowDuplicate>
328 SortedVector<TYPE, AllowDuplicate>& SortedVector<TYPE, AllowDuplicate>::operator=(const SortedVector<TYPE, true>& rhs)
329 {
330 vec_.clear();
331
332 if (AllowDuplicate) {
333 std::copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
334 } else {
335 // AllowDuplicate to Not AllowDuplicate
336 std::unique_copy(rhs.Begin(), rhs.End(), std::back_inserter(vec_));
337 }
338
339 return *this;
340 }
341
342 template <class TYPE, bool AllowDuplicate>
IndexOf(const TYPE & item)343 ssize_t SortedVector<TYPE, AllowDuplicate>::IndexOf(const TYPE& item) const
344 {
345 if (vec_.empty()) {
346 return NOT_FOUND;
347 }
348
349 auto it = std::lower_bound(std::begin(vec_), std::end(vec_), item);
350 if (it == vec_.end() || !(*it == item)) {
351 return NOT_FOUND;
352 }
353 return it - vec_.begin();
354 }
355
356 template <class TYPE, bool AllowDuplicate>
OrderOf(const TYPE & item)357 size_t SortedVector<TYPE, AllowDuplicate>::OrderOf(const TYPE& item) const
358 {
359 auto it = std::upper_bound(vec_.begin(), vec_.end(), item);
360 return it - vec_.begin();
361 }
362
363 template <class TYPE, bool AllowDuplicate>
Add(const TYPE & item)364 ssize_t SortedVector<TYPE, AllowDuplicate>::Add(const TYPE& item)
365 {
366 ssize_t index = IndexOf(item);
367 if (index != NOT_FOUND && !AllowDuplicate) {
368 return ADD_FAIL;
369 }
370
371 auto it = std::upper_bound(vec_.begin(), vec_.end(), item);
372 it = vec_.insert(it, item);
373 return it - vec_.begin();
374 }
375
376 template <class TYPE, bool AllowDuplicate>
SortedVector(const std::vector<TYPE> & invec)377 SortedVector<TYPE, AllowDuplicate>::SortedVector(const std::vector<TYPE>& invec)
378 {
379 if (invec.empty()) {
380 return;
381 }
382
383 std::vector<TYPE> newvector(invec);
384 std::sort(newvector.begin(), newvector.end());
385 if (AllowDuplicate) {
386 vec_.swap(newvector);
387 } else {
388 std::unique_copy(newvector.begin(), newvector.end(), std::back_inserter(vec_));
389 }
390 }
391
392 template <class TYPE, bool AllowDuplicate>
Merge(const std::vector<TYPE> & invec)393 size_t SortedVector<TYPE, AllowDuplicate>::Merge(const std::vector<TYPE>& invec)
394 {
395 SortedVector<TYPE, AllowDuplicate> sortedVector(invec);
396 Merge(sortedVector);
397 return vec_.size();
398 }
399
400 template <class TYPE, bool AllowDuplicate>
Merge(const SortedVector<TYPE,AllowDuplicate> & sortedVector)401 size_t SortedVector<TYPE, AllowDuplicate>::Merge(const SortedVector<TYPE, AllowDuplicate>& sortedVector)
402 {
403 std::vector<TYPE> newVec;
404 std::merge(vec_.begin(), vec_.end(), sortedVector.Begin(), sortedVector.End(), std::back_inserter(newVec));
405 if (!AllowDuplicate) {
406 vec_.clear();
407 std::unique_copy(newVec.begin(), newVec.end(), std::back_inserter(vec_));
408 } else {
409 vec_.swap(newVec);
410 }
411 return vec_.size();
412 }
413
414 } // namespace OHOS
415 #endif
416