/* * * Copyright (c) 1994 * Hewlett-Packard Company * */ #ifndef VECTOR_H #define VECTOR_H #include #include #include "assert.H" #include "memory_handler.H" #include "utilities.H" #include "system_size.H" #define PTRDIFF_T_MAX INT_MAX #define PTRDIFF_T_MIN INT_MIN template class BaseVector { protected: T* first; T* last; BaseVector() : first(0), last(0) {} BaseVector(BaseVector&) {} public: size_t size() const { return last - first; } int isEmpty() const { return size() == 0; } int isNotEmpty() const { return size() != 0; } T* begin() const { return first; } T* end() const { return last; } int operator==(const BaseVector& x) const { return size() == x.size() && equal(begin(), end(), x.begin()); } int operator!=(const BaseVector& x) const { return !(*this == x); } T& operator[](ptrdiff_t n) { // assert(0 <= n && n < size()); return begin()[n]; } }; template class SimpleVector : public BaseVector { protected: void allocate(size_t n) { first = Allocator()(n); last = first + n; } public: SimpleVector() {} SimpleVector(size_t n) { allocate(n); } SimpleVector(const SimpleVector& x) { allocate(x.size()); move(x.begin(), x.end(), begin()); } SimpleVector& operator=(const SimpleVector& x) { if (this != &x) { if (size() != x.size()) { delete [] first; allocate(x.size()); } move(x.begin(), x.end(), begin()); } return *this; } ~SimpleVector() { delete [] first; } }; template class Vector : public BaseVector { protected: T* endOfStorage; void rawAllocate(size_t n, size_t m) { first = (T*)memalloc(sizeof(T) * m); last = first + n; endOfStorage = first + m; } size_t storageSize() { return endOfStorage - first; } int isFull() { return last == endOfStorage; } void reallocate() { T* oldFirst = begin(); T* oldLast = end(); rawAllocate(size(), storageSize() ? 2 * storageSize() : INITIAL_VECTOR_SIZE); move(oldFirst, oldLast, PointerToRawStorage(begin())); forEach(oldFirst, oldLast, ExplicitDestructor()); ::delete(oldFirst); } public: Vector() : endOfStorage(0) {} Vector(const Vector& x) { rawAllocate(x.size(), x.size()); move(x.begin(), x.end(), PointerToRawStorage(begin())); } Vector(const BaseVector& x) { rawAllocate(x.size(), x.size()); move(x.begin(), x.end(), PointerToRawStorage(begin())); } Vector& operator=(const Vector& x) { if (this != &x) { forEach(begin(), end(), ExplicitDestructor()); if (size() < x.size()) { ::delete(begin()); rawAllocate(x.size(), x.size()); } move(x.begin(), x.end(), PointerToRawStorage(begin())); } return *this; } Vector& operator=(const BaseVector& x) { if (this != &x) { forEach(begin(), end(), ExplicitDestructor()); if (size() < x.size()) { ::delete(begin()); rawAllocate(x.size(), x.size()); } move(x.begin(), x.end(), PointerToRawStorage(begin())); } return *this; } ~Vector() { forEach(begin(), end(), ExplicitDestructor()); ::delete(begin()); } void insertAtEnd(T& x) { if (isFull()) reallocate(); PointerToRawStorage(last++) = x; } void deleteFromEnd() { if(isNotEmpty()) ExplicitDestructor()(*--last); } void insert(T* position, T& x) { if (isFull()) reallocate(); if (position != last) { PointerToRawStorage(last) = *(last - 1); moveBackward(position, last - 1, last); } *position = x; last++; } void erase(T* position) { if (position != end()) { move(position + 1, end(), position); ExplicitDestructor()(*--last); } } }; #endif