#ifndef VECTOR_ #define VECTOR_ #include <assert.h> #include <stdlib.h> #include "new" #include "helpers/iterator.h" namespace std { /* * Minimal and incomplete version of STL vector class * Note that the current implementation never shrinks the memory allocation */ template<typename T> class vector { public: typedef size_t size_type; typedef private_stuff::iterator_base<T> iterator; typedef private_stuff::iterator_base<const T> const_iterator; typedef private_stuff::reverse_iterator_base<T> reverse_iterator; typedef private_stuff::reverse_iterator_base<const T> const_reverse_iterator; vector() { begin_ptr = NULL, end_ptr = NULL; end_of_storage_ptr = NULL; } vector(const vector& other) { begin_ptr = NULL; end_ptr = NULL; end_of_storage_ptr = NULL; // crude... for(const_iterator i = other.begin(); i != other.end(); ++i) push_back(*i); } ~vector() { clear(); free(begin_ptr); } void push_back(const T& val) { if(end_ptr == end_of_storage_ptr) { size_t current_size = size(); size_t new_storage_size = current_size > 0 ? current_size * 2 + 1 : 4; begin_ptr = reinterpret_cast<T*> (realloc(begin_ptr, new_storage_size * sizeof(T))); end_ptr = begin_ptr + current_size; end_of_storage_ptr = begin_ptr + new_storage_size; } // placement new to construct object new(end_ptr) T(val); end_ptr++; } iterator erase(iterator pos) { assert(!empty()); // destruct object pos.p->~T(); size_t move_count = end() - pos; assert(move_count <= size()); memmove(pos.p, pos.p + 1, (move_count - 1) * sizeof(T)); end_ptr--; // TODO shrink allocation return pos; } void pop_back() { assert(size() > 0); --end_ptr; // destruct object end_ptr->~T(); } void clear() { for(T* p = begin_ptr; p != end_ptr; ++p) { p->~T(); } end_ptr = begin_ptr; } void resize(size_type newsize, const T& val = T()) { if(newsize < size()) { for(T* i = begin_ptr + newsize; i < end_ptr; ++i) { i->~T(); } end_ptr = begin_ptr + newsize; } else if(newsize > size()) { for(size_t t = newsize - size(); t > 0; --t) { push_back(val); } } } T& back() { return *(end_ptr - 1); } const T& back() const { return *(end_ptr - 1); } T& front() { return *begin_ptr; } const T& front() const { return *begin_ptr; } size_type size() const { return size_type(end_ptr - begin_ptr); } size_type capacity() const { return end_of_storage_ptr - begin_ptr; } bool empty() const { return begin_ptr == end_ptr; } T& operator[] (size_type idx) { T* p = begin_ptr + idx; assert(p < end_ptr); return *p; } const T& operator[] (size_type idx) const { T* p = begin_ptr + idx; assert(p < end_ptr); return *p; } iterator begin() { return iterator(begin_ptr); } const_iterator begin() const { return const_iterator(begin_ptr); } iterator end() { return iterator(end_ptr); } const_iterator end() const { return const_iterator(end_ptr); } reverse_iterator rbegin() { return reverse_iterator(end_ptr-1); } reverse_iterator rend() { return reverse_iterator(begin_ptr-1); } const reverse_iterator rbegin() const { return const_reverse_iterator(end_ptr-1); } const_reverse_iterator rend() const { return const_reverse_iterator(begin_ptr-1); } private: // copy constructor not supported yet void operator=(const vector& other); T* begin_ptr; T* end_ptr; T* end_of_storage_ptr; }; } #endif