• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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_VECTOR_H
18 #define ANDROID_VECTOR_H
19 
20 #include <new>
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <cutils/log.h>
25 
26 #include <utils/VectorImpl.h>
27 #include <utils/TypeHelpers.h>
28 
29 // ---------------------------------------------------------------------------
30 
31 namespace android {
32 
33 template <typename TYPE>
34 class SortedVector;
35 
36 /*!
37  * The main templated vector class ensuring type safety
38  * while making use of VectorImpl.
39  * This is the class users want to use.
40  */
41 
42 template <class TYPE>
43 class Vector : private VectorImpl
44 {
45 public:
46             typedef TYPE    value_type;
47 
48     /*!
49      * Constructors and destructors
50      */
51 
52                             Vector();
53                             Vector(const Vector<TYPE>& rhs);
54     explicit                Vector(const SortedVector<TYPE>& rhs);
55     virtual                 ~Vector();
56 
57     /*! copy operator */
58             const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;
59             Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);
60 
61             const Vector<TYPE>&     operator = (const SortedVector<TYPE>& rhs) const;
62             Vector<TYPE>&           operator = (const SortedVector<TYPE>& rhs);
63 
64             /*
65      * empty the vector
66      */
67 
clear()68     inline  void            clear()             { VectorImpl::clear(); }
69 
70     /*!
71      * vector stats
72      */
73 
74     //! returns number of items in the vector
size()75     inline  size_t          size() const                { return VectorImpl::size(); }
76     //! returns whether or not the vector is empty
isEmpty()77     inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
78     //! returns how many items can be stored without reallocating the backing store
capacity()79     inline  size_t          capacity() const            { return VectorImpl::capacity(); }
80     //! sets the capacity. capacity can never be reduced less than size()
setCapacity(size_t size)81     inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
82 
83     /*!
84      * C-style array access
85      */
86 
87     //! read-only C-style access
88     inline  const TYPE*     array() const;
89     //! read-write C-style access
90             TYPE*           editArray();
91 
92     /*!
93      * accessors
94      */
95 
96     //! read-only access to an item at a given index
97     inline  const TYPE&     operator [] (size_t index) const;
98     //! alternate name for operator []
99     inline  const TYPE&     itemAt(size_t index) const;
100     //! stack-usage of the vector. returns the top of the stack (last element)
101             const TYPE&     top() const;
102 
103     /*!
104      * modifying the array
105      */
106 
107     //! copy-on write support, grants write access to an item
108             TYPE&           editItemAt(size_t index);
109     //! grants right access to the top of the stack (last element)
110             TYPE&           editTop();
111 
112             /*!
113              * append/insert another vector
114              */
115 
116     //! insert another vector at a given index
117             ssize_t         insertVectorAt(const Vector<TYPE>& vector, size_t index);
118 
119     //! append another vector at the end of this one
120             ssize_t         appendVector(const Vector<TYPE>& vector);
121 
122 
123     //! insert an array at a given index
124             ssize_t         insertArrayAt(const TYPE* array, size_t index, size_t length);
125 
126     //! append an array at the end of this vector
127             ssize_t         appendArray(const TYPE* array, size_t length);
128 
129             /*!
130              * add/insert/replace items
131              */
132 
133     //! insert one or several items initialized with their default constructor
134     inline  ssize_t         insertAt(size_t index, size_t numItems = 1);
135     //! insert one or several items initialized from a prototype item
136             ssize_t         insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
137     //! pop the top of the stack (removes the last element). No-op if the stack's empty
138     inline  void            pop();
139     //! pushes an item initialized with its default constructor
140     inline  void            push();
141     //! pushes an item on the top of the stack
142             void            push(const TYPE& item);
143     //! same as push() but returns the index the item was added at (or an error)
144     inline  ssize_t         add();
145     //! same as push() but returns the index the item was added at (or an error)
146             ssize_t         add(const TYPE& item);
147     //! replace an item with a new one initialized with its default constructor
148     inline  ssize_t         replaceAt(size_t index);
149     //! replace an item with a new one
150             ssize_t         replaceAt(const TYPE& item, size_t index);
151 
152     /*!
153      * remove items
154      */
155 
156     //! remove several items
157     inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
158     //! remove one item
removeAt(size_t index)159     inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
160 
161     /*!
162      * sort (stable) the array
163      */
164 
165      typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
166      typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
167 
168      inline status_t        sort(compar_t cmp);
169      inline status_t        sort(compar_r_t cmp, void* state);
170 
171      // for debugging only
getItemSize()172      inline size_t getItemSize() const { return itemSize(); }
173 
174 
175      /*
176       * these inlines add some level of compatibility with STL. eventually
177       * we should probably turn things around.
178       */
179      typedef TYPE* iterator;
180      typedef TYPE const* const_iterator;
181 
begin()182      inline iterator begin() { return editArray(); }
end()183      inline iterator end()   { return editArray() + size(); }
begin()184      inline const_iterator begin() const { return array(); }
end()185      inline const_iterator end() const   { return array() + size(); }
reserve(size_t n)186      inline void reserve(size_t n) { setCapacity(n); }
empty()187      inline bool empty() const{ return isEmpty(); }
push_back(const TYPE & item)188      inline void push_back(const TYPE& item)  { insertAt(item, size(), 1); }
push_front(const TYPE & item)189      inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
erase(iterator pos)190      inline iterator erase(iterator pos) {
191          return begin() + removeItemsAt(pos-array());
192      }
193 
194 protected:
195     virtual void    do_construct(void* storage, size_t num) const;
196     virtual void    do_destroy(void* storage, size_t num) const;
197     virtual void    do_copy(void* dest, const void* from, size_t num) const;
198     virtual void    do_splat(void* dest, const void* item, size_t num) const;
199     virtual void    do_move_forward(void* dest, const void* from, size_t num) const;
200     virtual void    do_move_backward(void* dest, const void* from, size_t num) const;
201 };
202 
203 // Vector<T> can be trivially moved using memcpy() because moving does not
204 // require any change to the underlying SharedBuffer contents or reference count.
205 template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };
206 
207 // ---------------------------------------------------------------------------
208 // No user serviceable parts from here...
209 // ---------------------------------------------------------------------------
210 
211 template<class TYPE> inline
212 Vector<TYPE>::Vector()
213     : VectorImpl(sizeof(TYPE),
214                 ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
215                 |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
216                 |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))
217                 )
218 {
219 }
220 
221 template<class TYPE> inline
222 Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
223     : VectorImpl(rhs) {
224 }
225 
226 template<class TYPE> inline
227 Vector<TYPE>::Vector(const SortedVector<TYPE>& rhs)
228     : VectorImpl(static_cast<const VectorImpl&>(rhs)) {
229 }
230 
231 template<class TYPE> inline
232 Vector<TYPE>::~Vector() {
233     finish_vector();
234 }
235 
236 template<class TYPE> inline
237 Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
238     VectorImpl::operator = (rhs);
239     return *this;
240 }
241 
242 template<class TYPE> inline
243 const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
244     VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
245     return *this;
246 }
247 
248 template<class TYPE> inline
249 Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
250     VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
251     return *this;
252 }
253 
254 template<class TYPE> inline
255 const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
256     VectorImpl::operator = (rhs);
257     return *this;
258 }
259 
260 template<class TYPE> inline
261 const TYPE* Vector<TYPE>::array() const {
262     return static_cast<const TYPE *>(arrayImpl());
263 }
264 
265 template<class TYPE> inline
266 TYPE* Vector<TYPE>::editArray() {
267     return static_cast<TYPE *>(editArrayImpl());
268 }
269 
270 
271 template<class TYPE> inline
272 const TYPE& Vector<TYPE>::operator[](size_t index) const {
273     LOG_FATAL_IF(index>=size(),
274             "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
275             int(index), int(size()));
276     return *(array() + index);
277 }
278 
279 template<class TYPE> inline
280 const TYPE& Vector<TYPE>::itemAt(size_t index) const {
281     return operator[](index);
282 }
283 
284 template<class TYPE> inline
285 const TYPE& Vector<TYPE>::top() const {
286     return *(array() + size() - 1);
287 }
288 
289 template<class TYPE> inline
290 TYPE& Vector<TYPE>::editItemAt(size_t index) {
291     return *( static_cast<TYPE *>(editItemLocation(index)) );
292 }
293 
294 template<class TYPE> inline
295 TYPE& Vector<TYPE>::editTop() {
296     return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
297 }
298 
299 template<class TYPE> inline
300 ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
301     return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
302 }
303 
304 template<class TYPE> inline
305 ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
306     return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
307 }
308 
309 template<class TYPE> inline
310 ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {
311     return VectorImpl::insertArrayAt(array, index, length);
312 }
313 
314 template<class TYPE> inline
315 ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {
316     return VectorImpl::appendArray(array, length);
317 }
318 
319 template<class TYPE> inline
320 ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
321     return VectorImpl::insertAt(&item, index, numItems);
322 }
323 
324 template<class TYPE> inline
325 void Vector<TYPE>::push(const TYPE& item) {
326     return VectorImpl::push(&item);
327 }
328 
329 template<class TYPE> inline
330 ssize_t Vector<TYPE>::add(const TYPE& item) {
331     return VectorImpl::add(&item);
332 }
333 
334 template<class TYPE> inline
335 ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
336     return VectorImpl::replaceAt(&item, index);
337 }
338 
339 template<class TYPE> inline
340 ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
341     return VectorImpl::insertAt(index, numItems);
342 }
343 
344 template<class TYPE> inline
345 void Vector<TYPE>::pop() {
346     VectorImpl::pop();
347 }
348 
349 template<class TYPE> inline
350 void Vector<TYPE>::push() {
351     VectorImpl::push();
352 }
353 
354 template<class TYPE> inline
355 ssize_t Vector<TYPE>::add() {
356     return VectorImpl::add();
357 }
358 
359 template<class TYPE> inline
360 ssize_t Vector<TYPE>::replaceAt(size_t index) {
361     return VectorImpl::replaceAt(index);
362 }
363 
364 template<class TYPE> inline
365 ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
366     return VectorImpl::removeItemsAt(index, count);
367 }
368 
369 template<class TYPE> inline
370 status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
371     return VectorImpl::sort((VectorImpl::compar_t)cmp);
372 }
373 
374 template<class TYPE> inline
375 status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
376     return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
377 }
378 
379 // ---------------------------------------------------------------------------
380 
381 template<class TYPE>
382 void Vector<TYPE>::do_construct(void* storage, size_t num) const {
383     construct_type( reinterpret_cast<TYPE*>(storage), num );
384 }
385 
386 template<class TYPE>
387 void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
388     destroy_type( reinterpret_cast<TYPE*>(storage), num );
389 }
390 
391 template<class TYPE>
392 void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
393     copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
394 }
395 
396 template<class TYPE>
397 void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
398     splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
399 }
400 
401 template<class TYPE>
402 void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
403     move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
404 }
405 
406 template<class TYPE>
407 void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
408     move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
409 }
410 
411 }; // namespace android
412 
413 
414 // ---------------------------------------------------------------------------
415 
416 #endif // ANDROID_VECTOR_H
417