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 
25 namespace chre {
26 
27 template <typename ElementType, size_t kCapacity>
28 class FixedSizeVector : public NonCopyable {
29  public:
30   /**
31    * Destructs the objects
32    */
33   ~FixedSizeVector();
34 
35   /**
36    * @return A reference to the last element in the vector
37    */
38   ElementType &back();
39   const ElementType &back() const;
40 
41   /**
42    * @return A reference to the first element in the vector
43    */
44   ElementType &front();
45   const ElementType &front() const;
46 
47   /**
48    * Obtains a pointer to the underlying storage for the vector.
49    *
50    * @return A pointer to the storage used for elements in this vector.
51    */
52   ElementType *data();
53 
54   /**
55    * Obtains a const pointer to the underlying storage for the vector.
56    *
57    * @return A const pointer to the storage used for elements in this vector.
58    */
59   const ElementType *data() const;
60 
61   /**
62    * Obtains the number of elements currently stored in the static vector.
63    *
64    * @return The number of elements currently stored in the vector.
65    */
66   size_t size() const;
67 
68   /**
69    * Obtains the maximum number of elements that can be stored in the static
70    * vector.
71    *
72    * @return The maximum capacity of the vector as defined by the template
73    * argument.
74    */
75   size_t capacity() const;
76 
77   /**
78    * Determines whether the vector is empty or not.
79    *
80    * @return true if the vector is empty.
81    */
82   bool empty() const;
83 
84   /**
85    * Determines whether the vector is full or not.
86    *
87    * @return true if the vector is full.
88    */
89   bool full() const;
90 
91   /**
92    * Pushes an element onto the back of the vector. It is illegal to push an
93    * item onto a full vector. The user of the API must check the return of the
94    * full() function prior to pushing another element. All iterators and
95    * references are unaffected.
96    *
97    * @param The element to push onto the vector.
98    */
99   void push_back(const ElementType &element);
100 
101   /**
102    * Constructs an element onto the back of the vector. It is illegal to
103    * construct an item onto a full vector. The user of the API must check the
104    * return of the full() function prior to constructing another element. All
105    * iterators and references are unaffected.
106    *
107    * @param The arguments to the constructor
108    */
109   template <typename... Args>
110   void emplace_back(Args &&... args);
111 
112   /**
113    * Erases the last element in the vector. Invalid to call on an empty vector.
114    *
115    * Invalidates any references to back() and end()/cend().
116    */
117   void pop_back();
118 
119   /**
120    * Obtains an element of the vector given an index. It is illegal to index
121    * this vector out of bounds and the user of the API must check the size()
122    * function prior to indexing this vector to ensure that they will not read
123    * out of bounds.
124    *
125    * @param The index of the element.
126    * @return The element.
127    */
128   ElementType &operator[](size_t index);
129 
130   /**
131    * Obtains a const element of the vector given an index. It is illegal to
132    * index this vector out of bounds and the user of the API must check the
133    * size() function prior to indexing this vector to ensure that they will not
134    * read out of bounds.
135    *
136    * @param The index of the element.
137    * @return The element.
138    */
139   const ElementType &operator[](size_t index) const;
140 
141   /**
142    * Removes an element from the vector given an index. All elements after the
143    * indexed one are moved forward one position. The destructor is invoked on
144    * on the invalid item left at the end of the vector. The index passed in
145    * must be less than the size() of the vector. If the index is greater than or
146    * equal to the size no operation is performed. All iterators and references
147    * to elements before the indexed one are unaffected.
148    *
149    * @param index The index to remove an element at.
150    */
151   void erase(size_t index);
152 
153   /**
154    * Swaps the location of two elements stored in the vector. The indices
155    * passed in must be less than the size() of the vector. If the index is
156    * greater than or equal to the size, no operation is performed. All iterators
157    * and references to these two indexed elements are invalidated.
158    *
159    * @param index0 The index of the first element
160    * @param index1 The index of the second element
161    */
162   void swap(size_t index0, size_t index1);
163 
164   /**
165    * Resizes the fixed size vector by default-constructing from the current
166    * size() to the newly requested size. If the new size is smaller than the
167    * current size(), the elements from the new size to the current size() are
168    * destructed and the vector is shrunk. A resize operation cannot be performed
169    * that is greater than kCapacity. This will result in an assertion failure
170    * and a resize to kCapacity if assertions are disabled. All iterators and
171    * references to elements before newSize are unaffected.
172    *
173    * @param newSize The new size of the vector.
174    */
175   void resize(size_t newSize);
176 
177   /**
178    * Random-access iterator that points to some element in the container.
179    */
180   typedef ElementType *iterator;
181   typedef const ElementType *const_iterator;
182 
183   /**
184    * @return A random-access iterator to the beginning.
185    */
186   typename FixedSizeVector<ElementType, kCapacity>::iterator begin();
187   typename FixedSizeVector<ElementType, kCapacity>::const_iterator begin()
188       const;
189   typename FixedSizeVector<ElementType, kCapacity>::const_iterator cbegin()
190       const;
191 
192   /**
193    * @return A random-access iterator to the end.
194    */
195   typename FixedSizeVector<ElementType, kCapacity>::iterator end();
196   typename FixedSizeVector<ElementType, kCapacity>::const_iterator end() const;
197   typename FixedSizeVector<ElementType, kCapacity>::const_iterator cend() const;
198 
199  private:
200   //! Storage for vector elements. To avoid static initialization of members,
201   //! std::aligned_storage is used.
202   typename std::aligned_storage<sizeof(ElementType), alignof(ElementType)>::type
203       mData[kCapacity];
204 
205   //! The number of elements in the vector. This will never be more than
206   //! kCapacity.
207   size_t mSize = 0;
208 };
209 
210 }  // namespace chre
211 
212 #include "chre/util/fixed_size_vector_impl.h"
213 
214 #endif  // CHRE_UTIL_FIXED_SIZE_VECTOR_H_
215