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