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