You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
7.3 KiB
280 lines
7.3 KiB
#pragma once
|
|
#ifndef _MYVECTOR_H_
|
|
#define _MYVECTOR_H_
|
|
|
|
#include <new>
|
|
|
|
template< class T >
|
|
class TVector
|
|
{
|
|
public:
|
|
typedef T& reference;
|
|
typedef const T& const_reference;
|
|
|
|
// iterators
|
|
typedef T* iterator;
|
|
typedef const T* const_iterator;
|
|
class const_reverse_iterator;
|
|
|
|
class reverse_iterator
|
|
{
|
|
public:
|
|
reverse_iterator() : m_iter(NULL) {}
|
|
explicit reverse_iterator( iterator iter ) : m_iter( iter ) {}
|
|
|
|
reverse_iterator& operator++() { --m_iter; return *this;}
|
|
reverse_iterator operator++(int) { return reverse_iterator(m_iter--); }
|
|
reverse_iterator& operator--() { ++m_iter; return *this;}
|
|
reverse_iterator operator--(int) { return reverse_iterator(m_iter++); }
|
|
reverse_iterator operator+(size_t s) const { return reverse_iterator(m_iter - s); }
|
|
reverse_iterator operator-(size_t s) const { return reverse_iterator(m_iter + s); }
|
|
reverse_iterator& operator+=(size_t s) { m_iter -= s; return *this; }
|
|
reverse_iterator& operator-=(size_t s) { m_iter += s; return *this; }
|
|
bool operator==( iterator iter ) const { return ( m_iter == iter ); }
|
|
bool operator!=( iterator iter ) const { return ( m_iter != iter ); }
|
|
reference operator*() const { return *m_iter; }
|
|
private:
|
|
iterator m_iter;
|
|
friend const_reverse_iterator;
|
|
};
|
|
|
|
class const_reverse_iterator
|
|
{
|
|
public:
|
|
const_reverse_iterator() : m_iter(NULL) {}
|
|
const_reverse_iterator( const reverse_iterator& riter ) : m_iter( riter.m_iter ) {}
|
|
explicit const_reverse_iterator( const_iterator iter ) : m_iter( iter ) {}
|
|
|
|
const_reverse_iterator& operator++() { --m_iter; return *this;}
|
|
const_reverse_iterator operator++(int) { return const_reverse_iterator(m_iter--); }
|
|
const_reverse_iterator& operator--() { ++m_iter; return *this;}
|
|
const_reverse_iterator operator--(int) { return const_reverse_iterator(m_iter++); }
|
|
const_reverse_iterator operator+(size_t s) const { return const_reverse_iterator(m_iter - s); }
|
|
const_reverse_iterator operator-(size_t s) const { return const_reverse_iterator(m_iter + s); }
|
|
const_reverse_iterator& operator+=(size_t s) { m_iter -= s; return *this; }
|
|
const_reverse_iterator& operator-=(size_t s) { m_iter += s; return *this; }
|
|
bool operator==( iterator iter ) const { return ( m_iter == iter ); }
|
|
bool operator!=( iterator iter ) const { return ( m_iter != iter ); }
|
|
const_reference operator*() const { return *m_iter; }
|
|
|
|
private:
|
|
const_iterator m_iter;
|
|
};
|
|
|
|
// constructor / destructor
|
|
TVector();
|
|
~TVector();
|
|
|
|
// iteration
|
|
iterator begin(){ return m_pFirst; }
|
|
const_iterator begin() const { return m_pFirst; }
|
|
iterator end() { return m_pAfterLast; }
|
|
const_iterator end() const { return m_pAfterLast; }
|
|
reverse_iterator rbegin() { return reverse_iterator(m_pAfterLast-1); }
|
|
const_reverse_iterator rbegin() const { return const_reverse_iterator(m_pAfterLast-1); }
|
|
reverse_iterator rend() { return reverse_iterator(m_pFirst-1); }
|
|
const_reverse_iterator rend() const { return const_reverse_iterator(m_pFirst-1); }
|
|
|
|
// insertion / deletion
|
|
void push_back( const T& );
|
|
void pop_back();
|
|
iterator insert( iterator, const T& );
|
|
void insert( iterator, size_t, const T& );
|
|
void insert( iterator, const_iterator, const_iterator );
|
|
iterator erase( iterator );
|
|
iterator erase( iterator, iterator );
|
|
void clear(){ erase( begin(), end() ); }
|
|
|
|
// element access
|
|
reference operator[]( size_t s){ return *(m_pFirst+s); }
|
|
const_reference operator[]( size_t s) const { return *(m_pFirst+s); };
|
|
reference front() { return *m_pFirst; }
|
|
const_reference front() const { return *m_pFirst; }
|
|
reference back() { return *(m_pAfterLast-1); }
|
|
const_reference back() const { return *(m_pAfterLast-1); }
|
|
|
|
// size
|
|
size_t size() const{ return ( m_pAfterLast - m_pFirst ); }
|
|
bool empty() const{ return ( m_pAfterLast == m_pFirst ); }
|
|
|
|
private:
|
|
enum {
|
|
defaultSpace = 64
|
|
};
|
|
|
|
void growSpace(size_t s);
|
|
void growSpace(iterator&,size_t);
|
|
void checkSpace(size_t s=1){if((size()+s)>=m_space) growSpace(s); }
|
|
void checkSpace(iterator& iter, size_t s=1){if((size()+s)>=m_space) growSpace(iter,s); }
|
|
size_t bytes(size_t s) const { return (s * sizeof(T)); }
|
|
|
|
size_t m_space;
|
|
T* m_pFirst;
|
|
T* m_pAfterLast;
|
|
};
|
|
|
|
template< class T >
|
|
inline
|
|
TVector<T>::TVector()
|
|
{
|
|
m_space = 0;
|
|
m_pFirst = m_pAfterLast = NULL;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
TVector<T>::~TVector()
|
|
{
|
|
for( T* p = m_pFirst; p != m_pAfterLast; ++p )
|
|
{
|
|
p->~T();
|
|
}
|
|
operator delete( m_pFirst );
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
void
|
|
TVector<T>::push_back(
|
|
const T& x
|
|
)
|
|
{
|
|
checkSpace();
|
|
new(m_pAfterLast) T(x);
|
|
++m_pAfterLast;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
void
|
|
TVector<T>::pop_back()
|
|
{
|
|
m_pAfterLast -= 1;
|
|
m_pAfterLast->~T();
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
__TYPENAME TVector<T>::iterator
|
|
TVector<T>::insert(
|
|
__TYPENAME TVector<T>::iterator iter,
|
|
const T& x
|
|
)
|
|
{
|
|
checkSpace(iter);
|
|
if ( iter != m_pAfterLast )
|
|
{
|
|
::memmove( iter+1, iter, bytes( m_pAfterLast - iter ) );
|
|
}
|
|
new(iter) T(x);
|
|
++m_pAfterLast;
|
|
return iter;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
void
|
|
TVector<T>::insert(
|
|
__TYPENAME TVector<T>::iterator iter,
|
|
size_t n,
|
|
const T& x
|
|
)
|
|
{
|
|
checkSpace(iter,n);
|
|
if ( iter != m_pAfterLast )
|
|
{
|
|
::memmove( iter+n, iter, bytes( m_pAfterLast - iter ) );
|
|
}
|
|
for ( int i = 0; i < n; i++ )
|
|
{
|
|
new(iter+i) T(x);
|
|
}
|
|
m_pAfterLast += n;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
void
|
|
TVector<T>::insert(
|
|
__TYPENAME TVector<T>::iterator insIter,
|
|
__TYPENAME TVector<T>::const_iterator begIter,
|
|
__TYPENAME TVector<T>::const_iterator endIter
|
|
)
|
|
{
|
|
size_t n = endIter - begIter;
|
|
checkSpace( insIter,n );
|
|
if ( insIter != m_pAfterLast )
|
|
{
|
|
::memmove( insIter+n, insIter, bytes(m_pAfterLast-insIter) );
|
|
}
|
|
for( int i = 0; i < n; i++ )
|
|
{
|
|
new(insIter+i) T(*(begIter+i));
|
|
}
|
|
m_pAfterLast += n;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
__TYPENAME TVector<T>::iterator
|
|
TVector<T>::erase(
|
|
__TYPENAME TVector<T>::iterator iter
|
|
)
|
|
{
|
|
iter->~T();
|
|
::memmove( iter, iter+1, bytes(m_pAfterLast-(iter+1)) );
|
|
m_pAfterLast -= 1;
|
|
return iter;
|
|
}
|
|
|
|
template< class T >
|
|
inline
|
|
__TYPENAME TVector<T>::iterator
|
|
TVector<T>::erase(
|
|
__TYPENAME TVector<T>::iterator begIter,
|
|
__TYPENAME TVector<T>::iterator endIter
|
|
)
|
|
{
|
|
size_t n = endIter - begIter;
|
|
for ( int i = 0; i < n; i++ )
|
|
{
|
|
(begIter+i)->~T();
|
|
}
|
|
::memmove( begIter, endIter, bytes(m_pAfterLast-(endIter)) );
|
|
m_pAfterLast -= n;
|
|
return begIter;
|
|
}
|
|
|
|
template< class T >
|
|
void
|
|
TVector<T>::growSpace(
|
|
size_t n
|
|
)
|
|
{
|
|
size_t s = size();
|
|
size_t newSpace = (m_space == 0)? defaultSpace : m_space * 2;
|
|
while ( newSpace < (n + m_space) )
|
|
newSpace *= 2;
|
|
|
|
T *pBuffer = static_cast<T *>( operator new( bytes( newSpace ) ) );
|
|
::memmove( pBuffer, m_pFirst, bytes(m_pAfterLast-m_pFirst) );
|
|
operator delete( m_pFirst );
|
|
m_space = newSpace;
|
|
m_pFirst = pBuffer;
|
|
m_pAfterLast = m_pFirst + s;
|
|
}
|
|
|
|
// this will grow the space as well as fixup the given iterator (since memory is moving)
|
|
template< class T >
|
|
void
|
|
TVector<T>::growSpace(
|
|
__TYPENAME TVector<T>::iterator& iter, // fix up this iterator
|
|
size_t n
|
|
)
|
|
{
|
|
size_t iterOff = iter - m_pFirst;
|
|
growSpace(n);
|
|
iter = m_pFirst + iterOff;
|
|
}
|
|
|
|
#endif // !_MYVECTOR_H_
|