src/Vector.h
author Asher Baker <asherkin@gmail.com>
Mon Jun 10 01:04:43 2013 +0100 (2013-06-10)
changeset 263 ba85a47ee414
parent 251 ca99a81745fe
permissions -rw-r--r--
Normalise line endings.
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@195
    50
    void infallibleAppend(const T &item) {
dvander@195
    51
        assert(GrowIfNeeded(1));
dvander@195
    52
        new (&data[nitems]) T(item);
dvander@195
    53
        nitems++;
dvander@195
    54
    }
dvander@137
    55
    T popCopy() {
dvander@137
    56
        T t = at(length() - 1);
dvander@137
    57
        pop();
dvander@137
    58
        return t;
dvander@137
    59
    }
dvander@58
    60
    void pop() {
dvander@58
    61
        assert(nitems);
dvander@58
    62
        data[nitems - 1].~T();
dvander@58
    63
        nitems--;
dvander@58
    64
    }
dvander@137
    65
    bool empty() const {
dvander@137
    66
        return length() == 0;
dvander@137
    67
    }
dvander@55
    68
    size_t length() const {
dvander@55
    69
        return nitems;
dvander@55
    70
    }
dvander@55
    71
    T& at(size_t i) {
dvander@55
    72
        assert(i < length());
dvander@55
    73
        return data[i];
dvander@55
    74
    }
dvander@55
    75
    const T& at(size_t i) const {
dvander@55
    76
        assert(i < length());
dvander@55
    77
        return data[i];
dvander@55
    78
    }
dvander@55
    79
    T& operator [](size_t i) {
dvander@58
    80
        return at(i);
dvander@55
    81
    }
dvander@55
    82
    const T& operator [](size_t i) const {
dvander@58
    83
        return at(i);
dvander@55
    84
    }
dvander@55
    85
    void clear() {
dvander@55
    86
        nitems = 0;
dvander@55
    87
    }
dvander@55
    88
dvander@70
    89
    T *buffer() const {
dvander@70
    90
        return data;
dvander@70
    91
    }
dvander@70
    92
dvander@195
    93
    bool ensure(size_t desired) {
dvander@195
    94
        if (desired <= length())
dvander@195
    95
            return true;
dvander@195
    96
dvander@195
    97
        return GrowIfNeeded(desired - length());
dvander@195
    98
    }
dvander@195
    99
dvander@55
   100
  private:
dvander@55
   101
    bool GrowIfNeeded(size_t needed)
dvander@55
   102
    {
dvander@55
   103
        if (!IsUintPtrAddSafe(nitems, needed)) {
dvander@55
   104
            this->reportAllocationOverflow();
dvander@55
   105
            return false;
dvander@55
   106
        }
dvander@55
   107
        if (maxsize == 0)
dvander@55
   108
            maxsize = 8;
dvander@251
   109
        while (nitems + needed > maxsize) {
dvander@55
   110
            if (!IsUintPtrMultiplySafe(maxsize, 2)) {
dvander@55
   111
                this->reportAllocationOverflow();
dvander@55
   112
                return false;
dvander@55
   113
            }
dvander@55
   114
            maxsize *= 2;
dvander@55
   115
        }
dvander@55
   116
        T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
dvander@55
   117
        if (newdata == NULL)
dvander@55
   118
            return false;
dvander@251
   119
        for (size_t i = 0; i < nitems; i++) {
dvander@55
   120
            new (&newdata[i]) T(data[i]);
dvander@55
   121
            data[i].~T();
dvander@55
   122
        }
dvander@55
   123
        this->free(data);
dvander@55
   124
        data = newdata;
dvander@55
   125
        return true;
dvander@55
   126
    }
dvander@55
   127
dvander@55
   128
  private:
dvander@55
   129
    T* data;
dvander@55
   130
    size_t nitems;
dvander@55
   131
    size_t maxsize;
dvander@55
   132
};
dvander@55
   133
dvander@55
   134
}
dvander@55
   135
dvander@55
   136
#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
dvander@55
   137