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