You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.4 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//文件 VectorAccess.h
//主要功能:
// 模板数组基础类
//程序编写: 2011-7-07
/////////////////////////////////////////////////////////////////////////////
#ifndef vectoraccess_h
#define vectoraccess_h
#include <vector>
/*!\brief Simple vector-based container simplifying index-based work.
This class is an implementation detail of the 'vectorSets.h' and 'sortedlist.h'
classes. Thus, this class is not meant to be used anywhere else!
Use TTypeSet, TObjectSet or TSortedList instead. If you need to have the
std::vector to pass to an external C++ object, use the TTypeSet::vec().
NOTE: because this class is based directly upon the STL vector, we have a
problem for the bool type. In STL, they have made the vector<bool> implemented
in terms of the bit_vector. That really sucks because we cannot return a
reference to T! This is why there is a 'TBoolTypeSet'.
*/
namespace NSet
{
template <class T>
class TVectorAccess
{
public:
inline TVectorAccess() {}
inline TVectorAccess( unsigned int n ) : v(n) {}
inline TVectorAccess( unsigned int n, const T& t ): v(n,t) {}
inline TVectorAccess( const TVectorAccess& v2 ): v(v2.v) {}
inline std::vector<T>& vec() { return v; }
inline const std::vector<T>& vec() const { return v; }
inline T& operator[]( int idx ) { return v[idx]; }
inline const T& operator[]( int idx ) const { return (*const_cast<TVectorAccess*>(this))[idx]; }
inline unsigned int size() const { return (unsigned int) v.size(); }
inline bool setCapacity( int sz );
/*!<Allocates mem for sz, does not change size.*/
inline void getCapacity() const { return v.capacity(); }
/*!<\returns max size without reallocation.*/
inline bool setSize( int sz, T val );
inline bool setSize( int sz );
inline TVectorAccess& operator =( const TVectorAccess& v2 ) { v = v2.v; return *this; }
inline bool push_back( const T& t );
inline void insert( int pos, const T& val ) { v.insert(v.begin() + pos,val); }
inline void erase() { v.erase( v.begin(), v.end() ); }
inline void erase( const T& t )
{
for ( int idx=size()-1; idx!=-1; idx-- )
{ if ( v[idx] == t ) { remove(idx); return; } }
}
inline void remove( unsigned int idx )
{
if ( idx>=0 && idx<size() )
v.erase( v.begin() + idx );
}
inline void remove( unsigned int i1, unsigned int i2 )
{
if ( i1 == i2 ) { remove( i1 ); return; }
if ( i1 > i2 ) std::swap( i1, i2 );
const unsigned int sz = size();
if ( i1 >= sz ) return;
if ( i2 >= sz-1 ) i2 = sz-1;
v.erase( v.begin()+i1, v.begin()+i2+1 );
}
inline void swap( unsigned int i, unsigned int j ) { std::swap( v[i], v[j] ); }
inline void fillWith( const T& val )
{
const int sz = size();
T* arr = sz ? &v[0] : 0;
for ( int i=sz-1; i>=0; i--,arr++ )
*arr = val;
}
void moveAfter( const T& t, const T& aft )
{
if ( t == aft || size() < 2 ) return;
int tidx = -1; int aftidx = -1;
for ( int idx=size()-1; idx!=-1; idx-- )
{
if ( v[idx] == t )
{ tidx = idx; if ( aftidx != -1 ) break; }
if ( v[idx] == aft )
{ aftidx = idx; if ( tidx != -1 ) break; }
}
if ( tidx == -1 || aftidx == -1 || tidx == aftidx ) return;
if ( aftidx > tidx )
for ( int idx=tidx; idx<aftidx; idx++ )
swap( idx, idx+1 );
else
for ( int idx=tidx; idx>aftidx+1; idx-- )
swap( idx, idx-1 );
}
void moveToStart( const T& t )
{
if ( size() < 2 ) return;
int tidx = -1;
for ( int idx=size()-1; idx!=-1; idx-- )
if ( v[idx] == t ) { tidx = idx; break; }
for ( int idx=tidx; idx>0; idx-- )
swap( idx, idx-1 );
}
protected:
std::vector<T> v;
};
template<class T> inline
bool TVectorAccess<T>::setCapacity( int sz )
{
try { v.reserve(sz); }
catch ( std::bad_alloc )
{ return false; }
catch ( std::length_error )
{ return false; }
return true;
}
template<class T> inline
bool TVectorAccess<T>::push_back( const T& t )
{
try
{
v.push_back(t);
}
catch ( std::bad_alloc )
{
return false;
}
return true;
}
template<class T> inline
bool TVectorAccess<T>::setSize( int sz, T val )
{
try { v.resize(sz,val); }
catch ( std::bad_alloc )
{ return false; }
return true;
}
template<class T> inline
bool TVectorAccess<T>::setSize( int sz )
{
try { v.resize(sz); }
catch ( std::bad_alloc )
{ return false; }
return true;
}
} //namespace NSet
using namespace NSet;
#endif