| /* |
| * 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 |