jitcraft/Vector.h
author David Anderson <dvander@alliedmods.net>
Sat Jul 07 20:53:10 2012 -0700 (2012-07-07)
changeset 55 e073a9fe8e57
child 58 4d6265f95ff1
permissions -rw-r--r--
Move ExpressionList to a jc::Vector.
dvander@55
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@55
     2
 *
dvander@55
     3
 * Copyright (C) 2012 David Anderson
dvander@55
     4
 *
dvander@55
     5
 * This file is part of JITCraft.
dvander@55
     6
 *
dvander@55
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@55
     8
 * the terms of the GNU General Public License as published by the Free
dvander@55
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@55
    10
 * any later version.
dvander@55
    11
 * 
dvander@55
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@55
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@55
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@55
    15
 *
dvander@55
    16
 * You should have received a copy of the GNU General Public License along with
dvander@55
    17
 * JITCraft. 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@55
    27
namespace jc {
dvander@55
    28
dvander@55
    29
template <typename T, typename AllocPolicy = NormalAllocPolicy>
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@55
    50
    size_t length() const {
dvander@55
    51
        return nitems;
dvander@55
    52
    }
dvander@55
    53
    T& at(size_t i) {
dvander@55
    54
        assert(i < length());
dvander@55
    55
        return data[i];
dvander@55
    56
    }
dvander@55
    57
    const T& at(size_t i) const {
dvander@55
    58
        assert(i < length());
dvander@55
    59
        return data[i];
dvander@55
    60
    }
dvander@55
    61
    T& operator [](size_t i) {
dvander@55
    62
        return get(i);
dvander@55
    63
    }
dvander@55
    64
    const T& operator [](size_t i) const {
dvander@55
    65
        return get(i);
dvander@55
    66
    }
dvander@55
    67
    void clear() {
dvander@55
    68
        nitems = 0;
dvander@55
    69
    }
dvander@55
    70
dvander@55
    71
  private:
dvander@55
    72
    bool GrowIfNeeded(size_t needed)
dvander@55
    73
    {
dvander@55
    74
        if (!IsUintPtrAddSafe(nitems, needed)) {
dvander@55
    75
            this->reportAllocationOverflow();
dvander@55
    76
            return false;
dvander@55
    77
        }
dvander@55
    78
        if (maxsize == 0)
dvander@55
    79
            maxsize = 8;
dvander@55
    80
        while (nitems + needed > maxsize)
dvander@55
    81
        {
dvander@55
    82
            if (!IsUintPtrMultiplySafe(maxsize, 2)) {
dvander@55
    83
                this->reportAllocationOverflow();
dvander@55
    84
                return false;
dvander@55
    85
            }
dvander@55
    86
            maxsize *= 2;
dvander@55
    87
        }
dvander@55
    88
        T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
dvander@55
    89
        if (newdata == NULL)
dvander@55
    90
            return false;
dvander@55
    91
        for (size_t i = 0; i < nitems; i++)
dvander@55
    92
        {
dvander@55
    93
            new (&newdata[i]) T(data[i]);
dvander@55
    94
            data[i].~T();
dvander@55
    95
        }
dvander@55
    96
        this->free(data);
dvander@55
    97
        data = newdata;
dvander@55
    98
        return true;
dvander@55
    99
    }
dvander@55
   100
dvander@55
   101
  private:
dvander@55
   102
    T* data;
dvander@55
   103
    size_t nitems;
dvander@55
   104
    size_t maxsize;
dvander@55
   105
};
dvander@55
   106
dvander@55
   107
}
dvander@55
   108
dvander@55
   109
#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
dvander@55
   110