src/Vector.h
author David Anderson <danderson@mozilla.com>
Thu Jul 26 00:16:53 2012 -0700 (2012-07-26)
changeset 100 3278e19f064d
parent 86 32ad0523b309
child 114 d142e352b60a
permissions -rw-r--r--
Push build.
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@69
     5
 * This file is part of JITCraft.
dvander@69
     6
 *
dvander@69
     7
 * JITCraft 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@69
    12
 * Foobar 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@69
    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@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@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@70
    76
    T *buffer() const {
dvander@70
    77
        return data;
dvander@70
    78
    }
dvander@70
    79
dvander@55
    80
  private:
dvander@55
    81
    bool GrowIfNeeded(size_t needed)
dvander@55
    82
    {
dvander@55
    83
        if (!IsUintPtrAddSafe(nitems, needed)) {
dvander@55
    84
            this->reportAllocationOverflow();
dvander@55
    85
            return false;
dvander@55
    86
        }
dvander@55
    87
        if (maxsize == 0)
dvander@55
    88
            maxsize = 8;
dvander@55
    89
        while (nitems + needed > maxsize)
dvander@55
    90
        {
dvander@55
    91
            if (!IsUintPtrMultiplySafe(maxsize, 2)) {
dvander@55
    92
                this->reportAllocationOverflow();
dvander@55
    93
                return false;
dvander@55
    94
            }
dvander@55
    95
            maxsize *= 2;
dvander@55
    96
        }
dvander@55
    97
        T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
dvander@55
    98
        if (newdata == NULL)
dvander@55
    99
            return false;
dvander@55
   100
        for (size_t i = 0; i < nitems; i++)
dvander@55
   101
        {
dvander@55
   102
            new (&newdata[i]) T(data[i]);
dvander@55
   103
            data[i].~T();
dvander@55
   104
        }
dvander@55
   105
        this->free(data);
dvander@55
   106
        data = newdata;
dvander@55
   107
        return true;
dvander@55
   108
    }
dvander@55
   109
dvander@55
   110
  private:
dvander@55
   111
    T* data;
dvander@55
   112
    size_t nitems;
dvander@55
   113
    size_t maxsize;
dvander@55
   114
};
dvander@55
   115
dvander@55
   116
}
dvander@55
   117
dvander@55
   118
#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
dvander@55
   119