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