src/Vector.h
author David Anderson <dvander@alliedmods.net>
Sun Aug 05 00:49:31 2012 -0700 (2012-08-05)
changeset 156 0d28dc5af6c7
parent 137 be919b22085b
child 195 c1ba166f3fc4
permissions -rw-r--r--
Re-allow arrays to nest.
     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     T popCopy() {
    51         T t = at(length() - 1);
    52         pop();
    53         return t;
    54     }
    55     void pop() {
    56         assert(nitems);
    57         data[nitems - 1].~T();
    58         nitems--;
    59     }
    60     bool empty() const {
    61         return length() == 0;
    62     }
    63     size_t length() const {
    64         return nitems;
    65     }
    66     T& at(size_t i) {
    67         assert(i < length());
    68         return data[i];
    69     }
    70     const T& at(size_t i) const {
    71         assert(i < length());
    72         return data[i];
    73     }
    74     T& operator [](size_t i) {
    75         return at(i);
    76     }
    77     const T& operator [](size_t i) const {
    78         return at(i);
    79     }
    80     void clear() {
    81         nitems = 0;
    82     }
    83 
    84     T *buffer() const {
    85         return data;
    86     }
    87 
    88   private:
    89     bool GrowIfNeeded(size_t needed)
    90     {
    91         if (!IsUintPtrAddSafe(nitems, needed)) {
    92             this->reportAllocationOverflow();
    93             return false;
    94         }
    95         if (maxsize == 0)
    96             maxsize = 8;
    97         while (nitems + needed > maxsize)
    98         {
    99             if (!IsUintPtrMultiplySafe(maxsize, 2)) {
   100                 this->reportAllocationOverflow();
   101                 return false;
   102             }
   103             maxsize *= 2;
   104         }
   105         T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
   106         if (newdata == NULL)
   107             return false;
   108         for (size_t i = 0; i < nitems; i++)
   109         {
   110             new (&newdata[i]) T(data[i]);
   111             data[i].~T();
   112         }
   113         this->free(data);
   114         data = newdata;
   115         return true;
   116     }
   117 
   118   private:
   119     T* data;
   120     size_t nitems;
   121     size_t maxsize;
   122 };
   123 
   124 }
   125 
   126 #endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
   127