dvander@69: /* vim: set ts=4 sw=4 tw=99 et: dvander@69: * dvander@69: * Copyright (C) 2012 David Anderson dvander@69: * dvander@114: * This file is part of SourcePawn. dvander@69: * dvander@114: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@69: * the terms of the GNU General Public License as published by the Free dvander@69: * Software Foundation, either version 3 of the License, or (at your option) dvander@69: * any later version. dvander@69: * dvander@114: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@69: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@69: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@69: * dvander@69: * You should have received a copy of the GNU General Public License along with dvander@114: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@55: */ dvander@55: #ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ dvander@55: #define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ dvander@55: dvander@55: #include dvander@55: #include dvander@55: #include "AllocatorPolicies.h" dvander@55: #include "Utility.h" dvander@55: dvander@59: namespace ke { dvander@55: dvander@85: template dvander@55: class Vector : public AllocPolicy dvander@55: { dvander@55: public: dvander@55: Vector(AllocPolicy = AllocPolicy()) dvander@55: : data(NULL), dvander@55: nitems(0), dvander@55: maxsize(0) dvander@55: { } dvander@55: ~Vector() { dvander@55: for (size_t i = 0; i < nitems; i++) dvander@55: data[i].~T(); dvander@55: this->free(data); dvander@55: } dvander@55: bool append(const T& item) { dvander@55: if (!GrowIfNeeded(1)) dvander@55: return false; dvander@55: new (&data[nitems]) T(item); dvander@55: nitems++; dvander@55: return true; dvander@55: } dvander@58: void pop() { dvander@58: assert(nitems); dvander@58: data[nitems - 1].~T(); dvander@58: nitems--; dvander@58: } dvander@55: size_t length() const { dvander@55: return nitems; dvander@55: } dvander@55: T& at(size_t i) { dvander@55: assert(i < length()); dvander@55: return data[i]; dvander@55: } dvander@55: const T& at(size_t i) const { dvander@55: assert(i < length()); dvander@55: return data[i]; dvander@55: } dvander@55: T& operator [](size_t i) { dvander@58: return at(i); dvander@55: } dvander@55: const T& operator [](size_t i) const { dvander@58: return at(i); dvander@55: } dvander@55: void clear() { dvander@55: nitems = 0; dvander@55: } dvander@55: dvander@70: T *buffer() const { dvander@70: return data; dvander@70: } dvander@70: dvander@55: private: dvander@55: bool GrowIfNeeded(size_t needed) dvander@55: { dvander@55: if (!IsUintPtrAddSafe(nitems, needed)) { dvander@55: this->reportAllocationOverflow(); dvander@55: return false; dvander@55: } dvander@55: if (maxsize == 0) dvander@55: maxsize = 8; dvander@55: while (nitems + needed > maxsize) dvander@55: { dvander@55: if (!IsUintPtrMultiplySafe(maxsize, 2)) { dvander@55: this->reportAllocationOverflow(); dvander@55: return false; dvander@55: } dvander@55: maxsize *= 2; dvander@55: } dvander@55: T* newdata = (T*)this->malloc(sizeof(T) * maxsize); dvander@55: if (newdata == NULL) dvander@55: return false; dvander@55: for (size_t i = 0; i < nitems; i++) dvander@55: { dvander@55: new (&newdata[i]) T(data[i]); dvander@55: data[i].~T(); dvander@55: } dvander@55: this->free(data); dvander@55: data = newdata; dvander@55: return true; dvander@55: } dvander@55: dvander@55: private: dvander@55: T* data; dvander@55: size_t nitems; dvander@55: size_t maxsize; dvander@55: }; dvander@55: dvander@55: } dvander@55: dvander@55: #endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */ dvander@55: