#ifndef _VECTOR_H_
#define _VECTOR_H_
#if defined(USE_STL) || defined(USE_STL_VECTOR)
#include <vector>
#define suif_vector vector
#else
#include <assert.h>
template <class T>
class suif_vector {
public:
typedef T VectorType;
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
protected:
T *buff;
protected:
iterator m_start;
iterator m_finish;
iterator m_end_of_storage;
protected:
void allocate_vector(unsigned n) {
if (n == 0) n++;
buff = new T[n];
m_end_of_storage = buff + n;
}
void vector_fill(iterator& start, unsigned n, const T& val) {
iterator tmp = start;
while (tmp < m_finish) {
*(tmp) = val;
tmp++;
}
}
// copy from start up to, but not including, end...to dest
iterator copy(const_iterator start, const_iterator end, iterator dest) {
for (const_iterator tmp = start;
tmp != end; tmp++, dest++) {
*dest = *tmp;
}
return dest;
}
// What is the return value here?
// It seems like it should always end up just before start.
// Shouldn't it return dest2 instead?
const_iterator reverse_copy(const_iterator start, const_iterator end,
iterator dest) {
iterator dest2 = dest + (end - start);
const_iterator tmp = end;
while (tmp >= start) {
*dest2-- = *tmp--;
}
return tmp;
}
void insert_aux(iterator pos, const T& x) {
if (m_finish != m_end_of_storage) {
reverse_copy(pos, end(), pos + 1);
*pos = x;
m_finish = end() + 1;
}
else {
int oldsize = size();
int newsize = 2 * oldsize + 1;
T *pOld = buff;
allocate_vector(newsize);
T *pPos = buff;
pPos = copy(pOld, pos, pPos);
m_finish = copy(pos, end(), pPos+1);
*pPos = x;
delete [] pOld;
m_start = buff;
}
}
public:
suif_vector() : buff(0),m_start(0),m_finish(0),m_end_of_storage(0) {
allocate_vector(1);
m_start = buff;
m_finish = buff;
}
suif_vector(unsigned n, const T& val = T()) :
buff(0),m_start(0),m_finish(0),m_end_of_storage(0) {
iterator tmp;
allocate_vector(n);
m_start = buff;
tmp = m_start;
m_finish = tmp + n;
vector_fill(m_start, n, val);
}
suif_vector(const suif_vector<T>& vec) :
buff(0),m_start(0),m_finish(0),m_end_of_storage(0) {
const_iterator it = vec.begin(), end = vec.end();
unsigned n = vec.size();
delete [] buff;
allocate_vector(n);
copy(it, end, buff);
m_start = buff;
m_finish = buff + n;
}
~suif_vector() {
delete [] buff;
}
suif_vector<T>& operator=(const suif_vector<T>& vec) {
iterator it = vec.begin(), end = vec.end();
unsigned n = vec.size();
delete [] buff;
allocate_vector(n);
copy(it, end, buff);
m_start = buff;
m_finish = buff + n;
return *this;
}
iterator begin() { return m_start; }
iterator end() { return m_finish; }
const_iterator begin() const { return m_start; }
const_iterator end() const { return m_finish; }
inline unsigned length() const { return m_finish - m_start; }
inline unsigned size() const { return m_finish - m_start; }
inline bool empty() const { return size() == 0; }
unsigned capacity() const {
return ((unsigned)(m_end_of_storage - m_start));
}
void insert(iterator pos, const T& x) {
if (m_finish != m_end_of_storage && pos == end()) {
*m_finish = x;
m_finish++;
}
else {
insert_aux(pos, x);
}
}
void insert(int pos,const T& y) {
if (pos < 0)
insert(begin(),y);
else if (pos >= size())
push_back(y);
else
insert(begin() + pos,y);
}
iterator erase(iterator pos) {
iterator tmp;
tmp = pos + 1;
if (tmp != end()) {
copy(tmp, end(), pos);
--m_finish;
}
else {
--m_finish;
}
return(tmp);
}
void erase(int pos) {
if (pos < 0)
pos = 0;
else if (pos >= size())
pos = size() - 1;
if (pos >= 0)
erase(begin() + pos);
}
void push_back(const T& x) {
if (m_finish != m_end_of_storage) {
*m_finish = x;
m_finish++;
}
else {
insert_aux(end(), x);
}
}
void pop_back() { m_finish--; }
T& operator[](unsigned n) {
if ( n >= size()) { assert(0); }
return buff[n];
}
const T& operator[](unsigned n) const {
if ( n >= size()) { assert(0); }
return buff[n];
}
T& at(unsigned n) {
return buff[n];
}
T& front() {
return *begin();
}
T& back() {
return *(end()-1);
}
const T& front() const {
return *begin();
}
const T& back() const {
return *(end()-1);
}
bool is_member(const T& x) const {
for (const_iterator it = begin(); it != end(); it++) {
if ((*it) == x) return true;
}
return false;
}
void clear(void) {
m_finish = buff;
}
private:
}; // class vector
#endif /* USE_STL_VECTOR */
#endif