• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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