1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_UTIL_FIXED_SIZE_VECTOR_H_
18 #define CHRE_UTIL_FIXED_SIZE_VECTOR_H_
19 
20 #include <cstddef>
21 #include <type_traits>
22 
23 #include "chre/util/non_copyable.h"
24 #include "chre/util/raw_storage.h"
25 
26 namespace chre {
27 
28 template <typename ElementType, size_t kCapacity>
29 class FixedSizeVector : public NonCopyable {
30  public:
31   typedef ElementType value_type;
32 
33   /**
34    * Destructs the objects
35    */
36   ~FixedSizeVector();
37 
38   /**
39    * @return A reference to the last element in the vector
40    */
41   ElementType &back();
42   const ElementType &back() const;
43 
44   /**
45    * @return A reference to the first element in the vector
46    */
47   ElementType &front();
48   const ElementType &front() const;
49 
50   /**
51    * Obtains a pointer to the underlying storage for the vector.
52    *
53    * @return A pointer to the storage used for elements in this vector.
54    */
55   ElementType *data();
56 
57   /**
58    * Obtains a const pointer to the underlying storage for the vector.
59    *
60    * @return A const pointer to the storage used for elements in this vector.
61    */
62   const ElementType *data() const;
63 
64   /**
65    * Obtains the number of elements currently stored in the static vector.
66    *
67    * @return The number of elements currently stored in the vector.
68    */
69   size_t size() const;
70 
71   /**
72    * Obtains the maximum number of elements that can be stored in the static
73    * vector.
74    *
75    * @return The maximum capacity of the vector as defined by the template
76    * argument.
77    */
78   size_t capacity() const;
79 
80   /**
81    * Determines whether the vector is empty or not.
82    *
83    * @return true if the vector is empty.
84    */
85   bool empty() const;
86 
87   /**
88    * Determines whether the vector is full or not.
89    *
90    * @return true if the vector is full.
91    */
92   bool full() const;
93 
94   /**
95    * Pushes an element onto the back of the vector. It is illegal to push an
96    * item onto a full vector. The user of the API must check the return of the
97    * full() function prior to pushing another element. All iterators and
98    * references are unaffected.
99    *
100    * @param The element to push onto the vector.
101    */
102   void push_back(const ElementType &element);
103   void push_back(ElementType &&element);
104 
105   /**
106    * Constructs an element onto the back of the vector. It is illegal to
107    * construct an item onto a full vector. The user of the API must check the
108    * return of the full() function prior to constructing another element. All
109    * iterators and references are unaffected.
110    *
111    * @param The arguments to the constructor
112    */
113   template <typename... Args>
114   void emplace_back(Args &&... args);
115 
116   /**
117    * Erases the last element in the vector. Invalid to call on an empty vector.
118    *
119    * Invalidates any references to back() and end()/cend().
120    */
121   void pop_back();
122 
123   /**
124    * Obtains an element of the vector given an index. It is illegal to index
125    * this vector out of bounds and the user of the API must check the size()
126    * function prior to indexing this vector to ensure that they will not read
127    * out of bounds.
128    *
129    * @param The index of the element.
130    * @return The element.
131    */
132   ElementType &operator[](size_t index);
133 
134   /**
135    * Obtains a const element of the vector given an index. It is illegal to
136    * index this vector out of bounds and the user of the API must check the
137    * size() function prior to indexing this vector to ensure that they will not
138    * read out of bounds.
139    *
140    * @param The index of the element.
141    * @return The element.
142    */
143   const ElementType &operator[](size_t index) const;
144 
145   /**
146    * Removes an element from the vector given an index. All elements after the
147    * indexed one are moved forward one position. The destructor is invoked on
148    * on the invalid item left at the end of the vector. The index passed in
149    * must be less than the size() of the vector. If the index is greater than or
150    * equal to the size no operation is performed. All iterators and references
151    * to elements before the indexed one are unaffected.
152    *
153    * @param index The index to remove an element at.
154    */
155   void erase(size_t index);
156 
157   /**
158    * Swaps the location of two elements stored in the vector. The indices
159    * passed in must be less than the size() of the vector. If the index is
160    * greater than or equal to the size, no operation is performed. All iterators
161    * and references to these two indexed elements are invalidated.
162    *
163    * @param index0 The index of the first element
164    * @param index1 The index of the second element
165    */
166   void swap(size_t index0, size_t index1);
167 
168   /**
169    * Resizes the fixed size vector by default-constructing from the current
170    * size() to the newly requested size. If the new size is smaller than the
171    * current size(), the elements from the new size to the current size() are
172    * destructed and the vector is shrunk. A resize operation cannot be performed
173    * that is greater than kCapacity. This will result in an assertion failure
174    * and a resize to kCapacity if assertions are disabled. All iterators and
175    * references to elements before newSize are unaffected.
176    *
177    * @param newSize The new size of the vector.
178    */
179   void resize(size_t newSize);
180 
181   /**
182    * Random-access iterator that points to some element in the container.
183    */
184   typedef ElementType *iterator;
185   typedef const ElementType *const_iterator;
186 
187   /**
188    * @return A random-access iterator to the beginning.
189    */
190   typename FixedSizeVector<ElementType, kCapacity>::iterator begin();
191   typename FixedSizeVector<ElementType, kCapacity>::const_iterator begin()
192       const;
193   typename FixedSizeVector<ElementType, kCapacity>::const_iterator cbegin()
194       const;
195 
196   /**
197    * @return A random-access iterator to the end.
198    */
199   typename FixedSizeVector<ElementType, kCapacity>::iterator end();
200   typename FixedSizeVector<ElementType, kCapacity>::const_iterator end() const;
201   typename FixedSizeVector<ElementType, kCapacity>::const_iterator cend() const;
202 
203  protected:
204   //! Provides storage for elements, initially uninitialized.
205   RawStorage<ElementType, kCapacity> mData;
206 
207   //! The number of elements in the vector. This will never be more than
208   //! kCapacity.
209   size_t mSize = 0;
210 };
211 
212 }  // namespace chre
213 
214 #include "chre/util/fixed_size_vector_impl.h"
215 
216 #endif  // CHRE_UTIL_FIXED_SIZE_VECTOR_H_
217