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.

338 lines
7.1 KiB
C

1 month ago
//////////////////////////////////////////////////////////////////////////////
//<2F>ļ<EFBFBD> ObjectSeg.h
//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>:
// ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д: 2011-7-07
/////////////////////////////////////////////////////////////////////////////
#ifndef objectset_h
#define objectset_h
#include "VectorSet.h"
#include "vectorAccess.h"
/*!\brief Set of pointers to objects
The TObjectSet does not manage the objects.
*/
namespace NSet
{
template <class T>
class TObjectSet : public CVectorSet
{
public:
inline TObjectSet();
inline TObjectSet(const TObjectSet<T>&);
inline virtual ~TObjectSet() { deepErase(); }
virtual bool isManaged() const { return false; }
inline bool nullAllowed() const { return allow0_; }
inline void allowNull(bool yn=true);
inline virtual int size() const { return vec_.size(); }
inline virtual bool IsValidIndex(int) const;
inline virtual int indexOf(const T*) const;
inline virtual T* operator[](int idx) const { /*if ( !IsValidIndex(idx) )*/ return (T*)vec_[idx]; }
//inline virtual const T* operator[](int idx) const { /*if ( !IsValidIndex(idx) )*/ return (const T*)vec_[idx]; }
inline virtual T* GetAt(int idx) const { return (T*)vec_[idx]; }
inline virtual T* operator[](const T*) const; //!< check & unconst
inline TObjectSet<T>& operator =(const TObjectSet<T>&);
inline virtual TObjectSet<T>& operator +=(T*);
inline virtual TObjectSet<T>& operator -=(T*);
inline virtual T* replace(int idx,T*);
inline virtual void insertAt(T* newptr, int);
inline virtual void insertAfter(T* newptr, int);
inline virtual void copy(const TObjectSet<T>&);
inline virtual void append(const TObjectSet<T>&);
inline virtual void swap( int idx0, int idx1 );
inline virtual void Add(T* ptr) { push(ptr); }
inline virtual void push(T* ptr);
inline virtual T* pop();
inline void deepErase(); //<2F><><EFBFBD>ȿռ<C8BF><D5BC>ͷţ<CDB7><C5A3><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ָ<EFBFBD><D6B8><EFBFBD>Ŀռ<C4BF>
inline virtual void erase() { plainErase(); } //<2F>򵥿ռ<F2B5A5BF><D5BC>ͷţ<CDB7><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ָ<EFBFBD><D6B8>ָ<EFBFBD><D6B8><EFBFBD>Ŀռ<C4BF>
virtual inline T* remove(int,bool preserve_order=true); /*!<\returns the removed pointer. */
inline virtual void remove(int from,int to);
protected:
TVectorAccess<void*> vec_;
bool allow0_;
public:
inline void plainErase() { vec_.erase(); } /*!< Not virtual. Don't use casually. */
};
//! empty the TObjectSet deleting all objects pointed to.
template <class T>
inline void deepErase( TObjectSet<T>& os )
{
for ( int sz=os.size(), idx=0; idx<sz; idx++ )
delete os[idx];
os.plainErase();
}
//! empty the TObjectSet deleting all objects pointed to.
template <class T>
inline void deepEraseArr( TObjectSet<T>& os )
{
for ( int sz=os.size(), idx=0; idx<sz; idx++ )
delete [] os[idx];
os.plainErase();
}
//! append copies of one set's objects to another TObjectSet.
template <class T,class S>
inline void deepAppend( TObjectSet<T>& to, const TObjectSet<S>& from )
{
const int sz = from.size();
for ( int idx=0; idx<sz; idx++ )
to += from[idx] ? new T( *from[idx] ) : 0;
}
//! fill an TObjectSet with copies of the objects in the other set.
template <class T,class S>
inline void deepCopy( TObjectSet<T>& to, const TObjectSet<S>& from )
{
if ( &to == &from ) return;
deepErase( to );
to.allowNull( from.nullAllowed() );
deepAppend( to, from );
}
//! Locate object in set
template <class T,class S>
inline int indexOf( const TObjectSet<T>& os, const S& val )
{
for ( int idx=0; idx<os.size(); idx++ )
{
if ( *os[idx] == val )
return idx;
}
return -1;
}
//! Get const object in set
template <class T,class S>
inline const T* find( const TObjectSet<T>& os, const S& val )
{
const int idx = indexOf( os, val );
return idx == -1 ? 0 : os[idx];
}
//! Get object in set
template <class T,class S>
inline T* find( TObjectSet<T>& os, const S& val )
{
const int idx = indexOf( os, val );
return idx == -1 ? 0 : os[idx];
}
//! Sort TObjectSet. Must have operator > defined for elements
template <class T>
inline void sort( TObjectSet<T>& os )
{
T* tmp; const int sz = os.size();
for ( int d=sz/2; d>0; d=d/2 )
for ( int i=d; i<sz; i++ )
for ( int j=i-d; j>=0 && *os[j]>*os[j+d]; j-=d )
os.swap( j, j+d );
}
// Member function implementations
template <class T> inline
TObjectSet<T>::TObjectSet() : allow0_(false)
{
}
template <class T> inline
TObjectSet<T>::TObjectSet( const TObjectSet<T>& t )
{
*this = t;
}
template <class T> inline
TObjectSet<T>& TObjectSet<T>::operator =( const TObjectSet<T>& os )
{
allow0_ = os.allow0_;
copy(os);
return *this;
}
template <class T> inline
void TObjectSet<T>::deepErase()
{
::deepErase( *this );
}
template <class T> inline
void TObjectSet<T>::allowNull( bool yn )
{
allow0_ = yn;
}
template <class T> inline
bool TObjectSet<T>::IsValidIndex( int idx ) const
{
return idx>=0 && idx<size();
}
template <class T> inline
T* TObjectSet<T>::operator[]( const T* t ) const
{
const int idx = indexOf(t);
return idx < 0 ? 0 : const_cast<T*>(t);
}
template <class T> inline
int TObjectSet<T>::indexOf( const T* ptr ) const
{
for ( int idx=0; idx<size(); idx++ )
if ( (const T*)vec_[idx] == ptr ) return idx;
return -1;
}
template <class T> inline
TObjectSet<T>& TObjectSet<T>::operator +=( T* ptr )
{
if ( ptr || allow0_ )
vec_.push_back( (void*)ptr );
return *this;
}
template <class T> inline
TObjectSet<T>& TObjectSet<T>::operator -=( T* ptr )
{
if ( ptr || allow0_ )
vec_.erase( (void*)ptr );
return *this;
}
template <class T> inline
void TObjectSet<T>::swap( int idx0, int idx1 )
{
if ( idx0<0 || idx0>=size() || idx1<0 || idx1>=size() )
return;
void* tmp = vec_[idx0];
vec_[idx0] = vec_[idx1];
vec_[idx1] = tmp;
}
template <class T> inline
T* TObjectSet<T>::replace( int idx, T* newptr )
{
if ( idx<0 || idx>=size() ) return 0;
T* ptr = (T*)vec_[idx];
vec_[idx] = (void*)newptr; return ptr;
}
template <class T> inline
void TObjectSet<T>::insertAt( T* newptr, int idx )
{
vec_.insert( idx, (void*)newptr );
}
template <class T> inline
void TObjectSet<T>::insertAfter( T* newptr, int idx )
{
*this += newptr;
if ( idx < 0 )
vec_.moveToStart( (void*)newptr );
else
vec_.moveAfter( (void*)newptr, vec_[idx] );
}
template <class T> inline
void TObjectSet<T>::copy( const TObjectSet<T>& os )
{
if ( &os != this )
{
erase();
allow0_ = os.allow0_;
append( os );
}
}
template <class T> inline
void TObjectSet<T>::append( const TObjectSet<T>& os )
{
const int sz = os.size();
vec_.setCapacity( size()+sz );
for ( int idx=0; idx<sz; idx++ )
*this += const_cast<T*>( os[idx] );
}
template <class T> inline
void TObjectSet<T>::push( T* ptr )
{ *this +=ptr; }
template <class T> inline
T* TObjectSet<T>::pop()
{
int sz = size();
if ( !sz ) return 0;
return remove( sz-1 );
}
template <class T> inline
T* TObjectSet<T>::remove( int idx, bool kporder )
{
T* res = (T*)vec_[idx];
if ( kporder )
vec_.remove( idx );
else
{
const int lastidx = size()-1;
if ( idx!=lastidx )
vec_[idx] = vec_[lastidx];
vec_.remove( lastidx );
}
return res;
}
template <class T> inline
void TObjectSet<T>::remove( int i1, int i2 )
{ vec_.remove( i1, i2 ); }
}//namesapce
#endif