1 /*
2  * Copyright 2005 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 ANDROID_PIXELFLINGER_VECTOR_H
18 #define ANDROID_PIXELFLINGER_VECTOR_H
19 
20 #include <new>
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <cutils/log.h>
25 
26 #include "Errors.h"
27 #include "VectorImpl.h"
28 #include "TypeHelpers.h"
29 
30 // ---------------------------------------------------------------------------
31 
32 namespace android {
33 namespace tinyutils {
34 
35 /*!
36  * The main templated vector class ensuring type safety
37  * while making use of VectorImpl.
38  * This is the class users want to use.
39  */
40 
41 template <class TYPE>
42 class Vector : private VectorImpl
43 {
44 public:
45             typedef TYPE    value_type;
46 
47     /*!
48      * Constructors and destructors
49      */
50 
51                             Vector();
52                             Vector(const Vector<TYPE>& rhs);
53     virtual                 ~Vector();
54 
55     /*! copy operator */
56             const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;
57             Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);
58 
59     /*
60      * empty the vector
61      */
62 
clear()63     inline  void            clear()             { VectorImpl::clear(); }
64 
65     /*!
66      * vector stats
67      */
68 
69     //! returns number of items in the vector
size()70     inline  size_t          size() const                { return VectorImpl::size(); }
71     //! returns wether or not the vector is empty
isEmpty()72     inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
73     //! returns how many items can be stored without reallocating the backing store
capacity()74     inline  size_t          capacity() const            { return VectorImpl::capacity(); }
75     //! setst the capacity. capacity can never be reduced less than size()
setCapacity(size_t size)76     inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
77 
78     /*!
79      * C-style array access
80      */
81 
82     //! read-only C-style access
83     inline  const TYPE*     array() const;
84     //! read-write C-style access
85             TYPE*           editArray();
86 
87     /*!
88      * accessors
89      */
90 
91     //! read-only access to an item at a given index
92     inline  const TYPE&     operator [] (size_t index) const;
93     //! alternate name for operator []
94     inline  const TYPE&     itemAt(size_t index) const;
95     //! stack-usage of the vector. returns the top of the stack (last element)
96             const TYPE&     top() const;
97     //! same as operator [], but allows to access the vector backward (from the end) with a negative index
98             const TYPE&     mirrorItemAt(ssize_t index) const;
99 
100     /*!
101      * modifing the array
102      */
103 
104     //! copy-on write support, grants write access to an item
105             TYPE&           editItemAt(size_t index);
106     //! grants right acces to the top of the stack (last element)
107             TYPE&           editTop();
108 
109             /*!
110              * append/insert another vector
111              */
112 
113     //! insert another vector at a given index
114             ssize_t         insertVectorAt(const Vector<TYPE>& vector, size_t index);
115 
116     //! append another vector at the end of this one
117             ssize_t         appendVector(const Vector<TYPE>& vector);
118 
119 
120             /*!
121              * add/insert/replace items
122              */
123 
124     //! insert one or several items initialized with their default constructor
125     inline  ssize_t         insertAt(size_t index, size_t numItems = 1);
126     //! insert on onr several items initialized from a prototype item
127             ssize_t         insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
128     //! pop the top of the stack (removes the last element). No-op if the stack's empty
129     inline  void            pop();
130     //! pushes an item initialized with its default constructor
131     inline  void            push();
132     //! pushes an item on the top of the stack
133             void            push(const TYPE& item);
134     //! same as push() but returns the index the item was added at (or an error)
135     inline  ssize_t         add();
136     //! same as push() but returns the index the item was added at (or an error)
137             ssize_t         add(const TYPE& item);
138     //! replace an item with a new one initialized with its default constructor
139     inline  ssize_t         replaceAt(size_t index);
140     //! replace an item with a new one
141             ssize_t         replaceAt(const TYPE& item, size_t index);
142 
143     /*!
144      * remove items
145      */
146 
147     //! remove several items
148     inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
149     //! remove one item
removeAt(size_t index)150     inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
151 
152     /*!
153      * sort (stable) the array
154      */
155 
156      typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
157      typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
158 
159      inline status_t        sort(compar_t cmp);
160      inline status_t        sort(compar_r_t cmp, void* state);
161 
162 protected:
163     virtual void    do_construct(void* storage, size_t num) const;
164     virtual void    do_destroy(void* storage, size_t num) const;
165     virtual void    do_copy(void* dest, const void* from, size_t num) const;
166     virtual void    do_splat(void* dest, const void* item, size_t num) const;
167     virtual void    do_move_forward(void* dest, const void* from, size_t num) const;
168     virtual void    do_move_backward(void* dest, const void* from, size_t num) const;
169 };
170 
171 
172 // ---------------------------------------------------------------------------
173 // No user serviceable parts from here...
174 // ---------------------------------------------------------------------------
175 
176 template<class TYPE> inline
Vector()177 Vector<TYPE>::Vector()
178     : VectorImpl(sizeof(TYPE),
179                 ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
180                 |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
181                 |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
182                 |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
183                 )
184 {
185 }
186 
187 template<class TYPE> inline
Vector(const Vector<TYPE> & rhs)188 Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
189     : VectorImpl(rhs) {
190 }
191 
192 template<class TYPE> inline
~Vector()193 Vector<TYPE>::~Vector() {
194     finish_vector();
195 }
196 
197 template<class TYPE> inline
198 Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
199     VectorImpl::operator = (rhs);
200     return *this;
201 }
202 
203 template<class TYPE> inline
204 const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
205     VectorImpl::operator = (rhs);
206     return *this;
207 }
208 
209 template<class TYPE> inline
array()210 const TYPE* Vector<TYPE>::array() const {
211     return static_cast<const TYPE *>(arrayImpl());
212 }
213 
214 template<class TYPE> inline
editArray()215 TYPE* Vector<TYPE>::editArray() {
216     return static_cast<TYPE *>(editArrayImpl());
217 }
218 
219 
220 template<class TYPE> inline
221 const TYPE& Vector<TYPE>::operator[](size_t index) const {
222     LOG_FATAL_IF( index>=size(),
223                   "itemAt: index %d is past size %d", (int)index, (int)size() );
224     return *(array() + index);
225 }
226 
227 template<class TYPE> inline
itemAt(size_t index)228 const TYPE& Vector<TYPE>::itemAt(size_t index) const {
229     return operator[](index);
230 }
231 
232 template<class TYPE> inline
mirrorItemAt(ssize_t index)233 const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
234     LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
235                   "mirrorItemAt: index %d is past size %d",
236                   (int)index, (int)size() );
237     return *(array() + ((index<0) ? (size()-index) : index));
238 }
239 
240 template<class TYPE> inline
top()241 const TYPE& Vector<TYPE>::top() const {
242     return *(array() + size() - 1);
243 }
244 
245 template<class TYPE> inline
editItemAt(size_t index)246 TYPE& Vector<TYPE>::editItemAt(size_t index) {
247     return *( static_cast<TYPE *>(editItemLocation(index)) );
248 }
249 
250 template<class TYPE> inline
editTop()251 TYPE& Vector<TYPE>::editTop() {
252     return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
253 }
254 
255 template<class TYPE> inline
insertVectorAt(const Vector<TYPE> & vector,size_t index)256 ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
257     return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
258 }
259 
260 template<class TYPE> inline
appendVector(const Vector<TYPE> & vector)261 ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
262     return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
263 }
264 
265 template<class TYPE> inline
insertAt(const TYPE & item,size_t index,size_t numItems)266 ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
267     return VectorImpl::insertAt(&item, index, numItems);
268 }
269 
270 template<class TYPE> inline
push(const TYPE & item)271 void Vector<TYPE>::push(const TYPE& item) {
272     return VectorImpl::push(&item);
273 }
274 
275 template<class TYPE> inline
add(const TYPE & item)276 ssize_t Vector<TYPE>::add(const TYPE& item) {
277     return VectorImpl::add(&item);
278 }
279 
280 template<class TYPE> inline
replaceAt(const TYPE & item,size_t index)281 ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
282     return VectorImpl::replaceAt(&item, index);
283 }
284 
285 template<class TYPE> inline
insertAt(size_t index,size_t numItems)286 ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
287     return VectorImpl::insertAt(index, numItems);
288 }
289 
290 template<class TYPE> inline
pop()291 void Vector<TYPE>::pop() {
292     VectorImpl::pop();
293 }
294 
295 template<class TYPE> inline
push()296 void Vector<TYPE>::push() {
297     VectorImpl::push();
298 }
299 
300 template<class TYPE> inline
add()301 ssize_t Vector<TYPE>::add() {
302     return VectorImpl::add();
303 }
304 
305 template<class TYPE> inline
replaceAt(size_t index)306 ssize_t Vector<TYPE>::replaceAt(size_t index) {
307     return VectorImpl::replaceAt(index);
308 }
309 
310 template<class TYPE> inline
removeItemsAt(size_t index,size_t count)311 ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
312     return VectorImpl::removeItemsAt(index, count);
313 }
314 
315 // ---------------------------------------------------------------------------
316 
317 template<class TYPE>
do_construct(void * storage,size_t num)318 void Vector<TYPE>::do_construct(void* storage, size_t num) const {
319     construct_type( reinterpret_cast<TYPE*>(storage), num );
320 }
321 
322 template<class TYPE>
do_destroy(void * storage,size_t num)323 void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
324     destroy_type( reinterpret_cast<TYPE*>(storage), num );
325 }
326 
327 template<class TYPE>
do_copy(void * dest,const void * from,size_t num)328 void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
329     copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
330 }
331 
332 template<class TYPE>
do_splat(void * dest,const void * item,size_t num)333 void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
334     splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
335 }
336 
337 template<class TYPE>
do_move_forward(void * dest,const void * from,size_t num)338 void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
339     move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
340 }
341 
342 template<class TYPE>
do_move_backward(void * dest,const void * from,size_t num)343 void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
344     move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
345 }
346 
347 } // namespace tinyutils
348 } // namespace android
349 
350 
351 // ---------------------------------------------------------------------------
352 
353 #endif // ANDROID_PIXELFLINGER_VECTOR_H
354