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
32namespace android {
33namespace 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
41template <class TYPE>
42class Vector : private VectorImpl
43{
44public:
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
63    inline  void            clear()             { VectorImpl::clear(); }
64
65    /*!
66     * vector stats
67     */
68
69    //! returns number of items in the vector
70    inline  size_t          size() const                { return VectorImpl::size(); }
71    //! returns wether or not the vector is empty
72    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
73    //! returns how many items can be stored without reallocating the backing store
74    inline  size_t          capacity() const            { return VectorImpl::capacity(); }
75    //! setst the capacity. capacity can never be reduced less than 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
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
162protected:
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
176template<class TYPE> inline
177Vector<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
187template<class TYPE> inline
188Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
189    : VectorImpl(rhs) {
190}
191
192template<class TYPE> inline
193Vector<TYPE>::~Vector() {
194    finish_vector();
195}
196
197template<class TYPE> inline
198Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
199    VectorImpl::operator = (rhs);
200    return *this;
201}
202
203template<class TYPE> inline
204const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
205    VectorImpl::operator = (rhs);
206    return *this;
207}
208
209template<class TYPE> inline
210const TYPE* Vector<TYPE>::array() const {
211    return static_cast<const TYPE *>(arrayImpl());
212}
213
214template<class TYPE> inline
215TYPE* Vector<TYPE>::editArray() {
216    return static_cast<TYPE *>(editArrayImpl());
217}
218
219
220template<class TYPE> inline
221const 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
227template<class TYPE> inline
228const TYPE& Vector<TYPE>::itemAt(size_t index) const {
229    return operator[](index);
230}
231
232template<class TYPE> inline
233const 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
240template<class TYPE> inline
241const TYPE& Vector<TYPE>::top() const {
242    return *(array() + size() - 1);
243}
244
245template<class TYPE> inline
246TYPE& Vector<TYPE>::editItemAt(size_t index) {
247    return *( static_cast<TYPE *>(editItemLocation(index)) );
248}
249
250template<class TYPE> inline
251TYPE& Vector<TYPE>::editTop() {
252    return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
253}
254
255template<class TYPE> inline
256ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
257    return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
258}
259
260template<class TYPE> inline
261ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
262    return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
263}
264
265template<class TYPE> inline
266ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
267    return VectorImpl::insertAt(&item, index, numItems);
268}
269
270template<class TYPE> inline
271void Vector<TYPE>::push(const TYPE& item) {
272    return VectorImpl::push(&item);
273}
274
275template<class TYPE> inline
276ssize_t Vector<TYPE>::add(const TYPE& item) {
277    return VectorImpl::add(&item);
278}
279
280template<class TYPE> inline
281ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
282    return VectorImpl::replaceAt(&item, index);
283}
284
285template<class TYPE> inline
286ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
287    return VectorImpl::insertAt(index, numItems);
288}
289
290template<class TYPE> inline
291void Vector<TYPE>::pop() {
292    VectorImpl::pop();
293}
294
295template<class TYPE> inline
296void Vector<TYPE>::push() {
297    VectorImpl::push();
298}
299
300template<class TYPE> inline
301ssize_t Vector<TYPE>::add() {
302    return VectorImpl::add();
303}
304
305template<class TYPE> inline
306ssize_t Vector<TYPE>::replaceAt(size_t index) {
307    return VectorImpl::replaceAt(index);
308}
309
310template<class TYPE> inline
311ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
312    return VectorImpl::removeItemsAt(index, count);
313}
314
315// ---------------------------------------------------------------------------
316
317template<class TYPE>
318void Vector<TYPE>::do_construct(void* storage, size_t num) const {
319    construct_type( reinterpret_cast<TYPE*>(storage), num );
320}
321
322template<class TYPE>
323void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
324    destroy_type( reinterpret_cast<TYPE*>(storage), num );
325}
326
327template<class TYPE>
328void 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
332template<class TYPE>
333void 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
337template<class TYPE>
338void 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
342template<class TYPE>
343void 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