blob: 3dc2bf212eed54f817d75553cb21e82c6892cc85 [file] [log] [blame]
/*
* vector.{cc,hh} -- simple array template class
* Eddie Kohler
*
* Copyright (c) 1999-2000 Massachusetts Institute of Technology
* Copyright (c) 2006 Regents of the University of California
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Click LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Click LICENSE file; the license in that file is
* legally binding.
*/
#ifndef CLICK_VECTOR_CC
#define CLICK_VECTOR_CC
#include "vector.h"
template <class T>
Vector<T>::Vector(const Vector<T> &o)
: _l(0), _n(0), _capacity(0)
{
*this = o;
}
template <class T>
Vector<T>::~Vector()
{
for (size_type i = 0; i < _n; i++)
_l[i].~T();
delete[] (unsigned char *)_l;
}
template <class T> Vector<T> &
Vector<T>::operator=(const Vector<T> &o)
{
if (&o != this) {
for (size_type i = 0; i < _n; i++)
_l[i].~T();
_n = 0;
if (reserve(o._n)) {
_n = o._n;
for (size_type i = 0; i < _n; i++)
new(velt(i)) T(o._l[i]);
}
}
return *this;
}
template <class T> Vector<T> &
Vector<T>::assign(size_type n, const T &e)
{
resize(0, e);
resize(n, e);
return *this;
}
template <class T> typename Vector<T>::iterator
Vector<T>::insert(iterator i, const T& e)
{
assert(i >= begin() && i <= end());
size_type pos = i - begin();
if (_n < _capacity || reserve(RESERVE_GROW)) {
for (iterator j = end() - 1; j >= begin() + pos; j--) {
new((void*) (j+1)) T(*j);
j->~T();
}
new(velt(pos)) T(e);
_n++;
}
return begin() + pos;
}
template <class T> typename Vector<T>::iterator
Vector<T>::erase(iterator a, iterator b)
{
if (b > a) {
assert(a >= begin() && b <= end());
iterator i = a, j = b;
for (; j < end(); i++, j++) {
i->~T();
new((void*) i) T(*j);
}
for (; i < end(); i++)
i->~T();
_n -= b - a;
return a;
} else
return b;
}
template <class T> bool
Vector<T>::reserve(size_type want)
{
if (want < 0)
want = (_capacity > 0 ? _capacity * 2 : 4);
if (want <= _capacity)
return true;
T *new_l = (T *)new unsigned char[sizeof(T) * want];
if (!new_l)
return false;
for (size_type i = 0; i < _n; i++) {
new(velt(new_l, i)) T(_l[i]);
_l[i].~T();
}
delete[] (unsigned char *)_l;
_l = new_l;
_capacity = want;
return true;
}
template <class T> void
Vector<T>::resize(size_type nn, const T &e)
{
if (nn <= _capacity || reserve(nn)) {
for (size_type i = nn; i < _n; i++)
_l[i].~T();
for (size_type i = _n; i < nn; i++)
new(velt(i)) T(e);
_n = nn;
}
}
template <class T> void
Vector<T>::swap(Vector<T> &o)
{
T *l = _l;
size_type n = _n;
size_type cap = _capacity;
_l = o._l;
_n = o._n;
_capacity = o._capacity;
o._l = l;
o._n = n;
o._capacity = cap;
}
#endif