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