jitcraft/Vector.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 09 21:40:20 2012 -0700 (2012-07-09)
changeset 66 cbba1997dc71
parent 59 b7d61ddb3c8d
child 69 dfce0539a77d
permissions -rw-r--r--
Add support for passing arrays.
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@59
    27
namespace ke {
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@58
    50
    void pop() {
dvander@58
    51
        assert(nitems);
dvander@58
    52
        data[nitems - 1].~T();
dvander@58
    53
        nitems--;
dvander@58
    54
    }
dvander@55
    55
    size_t length() const {
dvander@55
    56
        return nitems;
dvander@55
    57
    }
dvander@55
    58
    T& at(size_t i) {
dvander@55
    59
        assert(i < length());
dvander@55
    60
        return data[i];
dvander@55
    61
    }
dvander@55
    62
    const T& at(size_t i) const {
dvander@55
    63
        assert(i < length());
dvander@55
    64
        return data[i];
dvander@55
    65
    }
dvander@55
    66
    T& operator [](size_t i) {
dvander@58
    67
        return at(i);
dvander@55
    68
    }
dvander@55
    69
    const T& operator [](size_t i) const {
dvander@58
    70
        return at(i);
dvander@55
    71
    }
dvander@55
    72
    void clear() {
dvander@55
    73
        nitems = 0;
dvander@55
    74
    }
dvander@55
    75
dvander@55
    76
  private:
dvander@55
    77
    bool GrowIfNeeded(size_t needed)
dvander@55
    78
    {
dvander@55
    79
        if (!IsUintPtrAddSafe(nitems, needed)) {
dvander@55
    80
            this->reportAllocationOverflow();
dvander@55
    81
            return false;
dvander@55
    82
        }
dvander@55
    83
        if (maxsize == 0)
dvander@55
    84
            maxsize = 8;
dvander@55
    85
        while (nitems + needed > maxsize)
dvander@55
    86
        {
dvander@55
    87
            if (!IsUintPtrMultiplySafe(maxsize, 2)) {
dvander@55
    88
                this->reportAllocationOverflow();
dvander@55
    89
                return false;
dvander@55
    90
            }
dvander@55
    91
            maxsize *= 2;
dvander@55
    92
        }
dvander@55
    93
        T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
dvander@55
    94
        if (newdata == NULL)
dvander@55
    95
            return false;
dvander@55
    96
        for (size_t i = 0; i < nitems; i++)
dvander@55
    97
        {
dvander@55
    98
            new (&newdata[i]) T(data[i]);
dvander@55
    99
            data[i].~T();
dvander@55
   100
        }
dvander@55
   101
        this->free(data);
dvander@55
   102
        data = newdata;
dvander@55
   103
        return true;
dvander@55
   104
    }
dvander@55
   105
dvander@55
   106
  private:
dvander@55
   107
    T* data;
dvander@55
   108
    size_t nitems;
dvander@55
   109
    size_t maxsize;
dvander@55
   110
};
dvander@55
   111
dvander@55
   112
}
dvander@55
   113
dvander@55
   114
#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
dvander@55
   115