src/Vector.h
author David Anderson <dvander@alliedmods.net>
Tue Jan 01 15:34:07 2013 -0800 (2013-01-01)
changeset 251 ca99a81745fe
parent 195 c1ba166f3fc4
permissions -rw-r--r--
Refactor compilation process around the new concept of packages.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
    20 #define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
    21 
    22 #include <new>
    23 #include <stdlib.h>
    24 #include "AllocatorPolicies.h"
    25 #include "Utility.h"
    26 
    27 namespace ke {
    28 
    29 template <typename T, typename AllocPolicy = ZoneAllocatorPolicy>
    30 class Vector : public AllocPolicy
    31 {
    32   public:
    33     Vector(AllocPolicy = AllocPolicy())
    34       : data(NULL),
    35         nitems(0),
    36         maxsize(0)
    37     { }
    38     ~Vector() {
    39         for (size_t i = 0; i < nitems; i++)
    40             data[i].~T();
    41         this->free(data);
    42     }
    43     bool append(const T& item) {
    44         if (!GrowIfNeeded(1))
    45             return false;
    46         new (&data[nitems]) T(item);
    47         nitems++;
    48         return true;
    49     }
    50     void infallibleAppend(const T &item) {
    51         assert(GrowIfNeeded(1));
    52         new (&data[nitems]) T(item);
    53         nitems++;
    54     }
    55     T popCopy() {
    56         T t = at(length() - 1);
    57         pop();
    58         return t;
    59     }
    60     void pop() {
    61         assert(nitems);
    62         data[nitems - 1].~T();
    63         nitems--;
    64     }
    65     bool empty() const {
    66         return length() == 0;
    67     }
    68     size_t length() const {
    69         return nitems;
    70     }
    71     T& at(size_t i) {
    72         assert(i < length());
    73         return data[i];
    74     }
    75     const T& at(size_t i) const {
    76         assert(i < length());
    77         return data[i];
    78     }
    79     T& operator [](size_t i) {
    80         return at(i);
    81     }
    82     const T& operator [](size_t i) const {
    83         return at(i);
    84     }
    85     void clear() {
    86         nitems = 0;
    87     }
    88 
    89     T *buffer() const {
    90         return data;
    91     }
    92 
    93     bool ensure(size_t desired) {
    94         if (desired <= length())
    95             return true;
    96 
    97         return GrowIfNeeded(desired - length());
    98     }
    99 
   100   private:
   101     bool GrowIfNeeded(size_t needed)
   102     {
   103         if (!IsUintPtrAddSafe(nitems, needed)) {
   104             this->reportAllocationOverflow();
   105             return false;
   106         }
   107         if (maxsize == 0)
   108             maxsize = 8;
   109         while (nitems + needed > maxsize) {
   110             if (!IsUintPtrMultiplySafe(maxsize, 2)) {
   111                 this->reportAllocationOverflow();
   112                 return false;
   113             }
   114             maxsize *= 2;
   115         }
   116         T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
   117         if (newdata == NULL)
   118             return false;
   119         for (size_t i = 0; i < nitems; i++) {
   120             new (&newdata[i]) T(data[i]);
   121             data[i].~T();
   122         }
   123         this->free(data);
   124         data = newdata;
   125         return true;
   126     }
   127 
   128   private:
   129     T* data;
   130     size_t nitems;
   131     size_t maxsize;
   132 };
   133 
   134 }
   135 
   136 #endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
   137