⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exparr.hpp

📁 The library provides supports for run-time loaded plugin classes in C++
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    T     *ta;    INT   cur_size;    INT   max_size;};template <class T, class INT=int>class EaIter {public:    EaIter( const ExpArr<T,INT> &ea ) : m_pea(&ea), m_ix(0) { }    void Init( INT ix=0 ) { m_ix=ix; }    T Get() {        if( m_ix<0 || m_ix>=m_pea->Size() ) EA_THROW_RV( "EaIter::Get, Index out of range", m_pea->GetNullElem() );        return m_pea->Elem(m_ix);    }T operator () () { return Get(); }    int Index( ) { return m_ix; }    void operator ++ () { m_ix++; }    void operator ++ (int) { m_ix++; } // postfix    void operator -- () { m_ix--; }    void operator -- (int) { m_ix--; } // postfix    bool AtEnd() { return m_ix>=m_pea->Size(); }protected:    const ExpArr<T> *m_pea;    INT m_ix;};// ----- ExpArrP -----// The pointer versiontemplate<class T, class INT=int >class ExpArrP : public ExpArr<T,INT> {public:    ExpArrP( const T *pt, INT n ) : ExpArr<T,INT>(pt,n) {  }    ExpArrP( const ExpArrP<T,INT> &ea ) : ExpArr<T,INT>(ea) { }    ExpArrP( const ExpArrP<T,INT> &ea, bool is_move ) : ExpArr<T,INT>(ea,is_move) { }    ExpArrP( ) : ExpArr<T,INT>() { }    //~ExpArrP();    // # ExpArrP specific    void DeleteAll( ) {        for( int ix=0; ix<this->cur_size; ix++ )            delete this->ta[ix];        this->Empty();    }    // # ExpArrP specific, for efficiency    T ElemSafe( INT ix ) const {        if( ix<0 || ix>=this->cur_size ) return NULL;        else return this->ta[ix];    }    // Use operator==: T t; U u; t==u    template<class U>    int FindIndexOf( const U &u, int ix=0, int dir=1 ) {        for( ; ix>=0 && ix<this->cur_size; ix+=dir )            if( this->ta[ix] && (*(this->ta[ix]))==u )                return ix;        return -1;    }    // Use operator==: T t; U u; u==t    template<class U>    int FindIndexOfR( const U &u, int ix=0, int dir=0 ) {        for( ; ix>=0 && ix<this->cur_size; ix+=dir )            if( this->ta[ix] && u==(*(this->ta[ix])) )                return ix;        return -1;    }    // Use operator==: T t; U u; t==u    template<class U>    T Find( const U &u ) {        INT ix = FindIndexOf(u);        return ElemSafe(ix);    }    // Use operator==: T t; U u; u==t    template<class U>    T FindR( const U &u ) {        INT ix = FindIndexOfR(u);        return ElemSafe(ix);    }};template <class T, class INT=int>class EapIter : public EaIter<T,INT> {public:    EapIter( const ExpArrP<T,INT> &ea ) : EaIter<T,INT>(ea) { }    T Get() {        if( this->m_ix<0 || this->m_ix >= this->m_pea->Size() )            m_t = NULL;        else            m_t = this->m_pea->Elem(this->m_ix);        return m_t;    }    T operator () () { return Get(); }    T m_t;};/*template <class T,class INT=int>class EapIter {public:   EapIter( const ExpArrP<T,INT> &ea ) : m_pea(&ea), m_ix(0) {} //{ EA_ASSERT(m_pea); }   void Init( int ix=0 ) { m_ix=ix; }   T Get() { return m_pea->ElemSafe(m_ix); }   T operator () () { return m_pea->ElemSafe(m_ix); }   int Index( ) { return m_ix; }   void operator ++ () { m_ix++; }   void operator ++ (int) { m_ix++; } // postfix   void operator -- () { m_ix--; }   void operator -- (int) { m_ix--; } // postfix   bool AtEnd() { return m_ix>=m_pea->Size(); } protected:   const ExpArrP<T,INT> *m_pea;   int m_ix;};*/#include "ExpArr.hpp"// We would want placement new below. However, together with debug new operators// this becomes tricky. Instead choose to init each element with values from// GetNullElem. (we could use placement new in release version, but then we get// slightly different meanings to the operations)./*#ifdef new	// Define way of replacing placement new#else	#include <new>#endif*/// This version holds objects with constructors and/or destructors being applied to them// When an object goes out of the array scope, its destructor is applied.// When an object comes into the scope, its constructor is applied.// Otherwise, we interpret things at 'object scope', not at raw memory level.template <class T, class INT=int>class ExpArrObj : public ExpArr<T,INT> {public:    ExpArrObj( const T *pt, INT n ) : ExpArr<T,INT>() { Push(pt,n); }    ExpArrObj( const ExpArrObj<T> &ea ) : ExpArr<T,INT>() { Push(ea); }    // Special constructor to move contents from other ExpArrr, breaking const,     // but that has to be due to C++ restriction in this case.    ExpArrObj( const ExpArr<T> &ea, bool is_move ) : ExpArr<T,INT>(ea,is_move) { }    ExpArrObj( ) : ExpArr<T,INT>() { }    ~ExpArrObj( ) { DestroyAll(); }    void Empty() { DestroyAll(); }    ExpArrObj& DestroyAll( ) {        // Reduce size first, then delete elems        int sz = this->cur_size;        this->cur_size = 0;        for( int ix=0; ix<sz; ix++ )            this->ta[ix].~T();        return *this;    }    void MinCurrentSize( INT size ) {        this->MinTotalSize(size);        for( int ix=this->cur_size; ix<size; ix++ )        	memcpy( this->ta+ix, &this->GetNullElem(), sizeof(T) );            //new ((void*)(this->ta+ix)) T();        this->cur_size = size;    }    // It is probably good for ExpArrObj to return a reference by default (?)    T& Elem( INT ix ) const {        if( ix<0 || ix>=this->cur_size )            EA_THROW_RV("ExpArrObj::Elem - Index out of range",this->GetNullElem());        return this->ta[ix];    }    ExpArrObj& Push( const T& elem ) {        this->MinFreeElem(1);        // Placement new to run constructor    	memcpy( this->ta+this->cur_size, &this->GetNullElem(), sizeof(T) );        //new ((void*)(this->ta+this->cur_size))T();    	        this->ta[this->cur_size++] = elem;        return *this;    }    // Push an elemnt but don't set it to anything (meaning run constructor on it)    ExpArrObj& Push( ) {        this->MinFreeElem(1);        // Placement new to run constructor    	memcpy( this->ta+this->cur_size++, &this->GetNullElem(), sizeof(T) );        //new ((void*)(this->ta+this->cur_size++))T();        return *this;    }    ExpArrObj& PushVol( T& elem ) {  // Allows for operator = to modify elem        this->MinFreeElem(1);        // Placement new to run constructor    	memcpy( this->ta+this->cur_size, &this->GetNullElem(), sizeof(T) );        //new ((void*)(this->ta+this->cur_size))T();        this->ta[this->cur_size++] = elem;  // Here!        return *this;    }    ExpArrObj& PushElem( T elem ) {  // Copy element here (needed?)        this->MinFreeElem(1);        // Placement new to run constructor    	memcpy( this->ta+this->cur_size, &this->GetNullElem(), sizeof(T) );        //new ((void*)(this->ta+this->cur_size))T();        this->ta[this->cur_size++] = elem;        return *this;    }    void Pop( ) {        if( !this->cur_size )            EA_THROW_RV( "ExpArrObj::Pop, Empty stack", (ExpArr<T,INT>::GetNullElem()) );        this->ta[this->cur_size].~T();        // No return element    }    INT IndexOf( const T& elem, INT ix=0, INT dir=1 ) const {        for(; ix>=0 && ix<this->cur_size; ix+=dir)            if(this->ta[ix]==elem)                 return ix;        return (INT)-1;    }        bool Has( const T& elem ) const { return IndexOf(elem)!=-1; }    void RemoveIndexUnordered( INT ix ) {        this->RangeCheck(ix);        this->ta[ix].~T();        ExpArr<T,INT>::RemoveIndex(ix);    }    void RemoveIndexOrdered( INT ix ) {        this->RangeCheck(ix);        this->ta[ix].~T();        ExpArr<T,INT>::RemoveIndexOrdered(ix);    }    bool Remove( const T &elem ) {        INT ix = this->IndexOf(elem);        if( ix==(INT)-1 ) return false;        RemoveIndex(ix);        return true;    }    bool RemoveUnordered( const T &elem ) {        INT ix = this->IndexOf(elem);        if( ix==(INT)-1 ) return false;        RemoveIndexUnordered(ix);        return true;    }    bool RemoveOrdered( const T &elem ) {        INT ix = this->IndexOf(elem);        if( ix==-1 ) return false;        RemoveIndexOrdered(ix);        return true;    }    ExpArrObj& InsertOrdered( const T &elem, INT ix ) {        this->MakeSpaceAt( ix );    	memcpy( this->ta+ix, &this->GetNullElem(), sizeof(T) );        //new ((void*)(this->ta+ix)) T(); // If we have custom allocator, this might not have happened        this->ta[ix] = elem;        return *this;    }    int Replace( const T& find, const T& repl ) {        int n_found = 0;        for(INT ix=0; ix<this->cur_size; ix++)            if( this->ta[this->ix]==find ) {                this->ta[this->ix]=repl;                n_found++;            }        return n_found;    }    ExpArrObj& Push( const ExpArrObj<T,INT>& other ) {  // At top of stack        return Insert( other.ExpArr<T,INT>::ta, other.ExpArr<T,INT>::cur_size, this->cur_size );    }    ExpArrObj& Push( const T *elems, INT number ) {  // At top of stack        if( !number ) return *this;        return Insert( elems, number, this->cur_size );    }    ExpArrObj& Insert( const T *elems, INT number, INT at_ix=0 ) {  // At arbitrary position        if( !number ) return *this;        if( !elems ) EA_THROW_RV( "ExpArrObj::Insert, NULL pointer received", *this );        if( at_ix<0 ) at_ix+=this->cur_size;        if( number<0 ) EA_THROW_RV( "ExpArrObj::Insert, Negative number", *this );        if( at_ix<0 || at_ix>this->cur_size ) EA_THROW_RV( "ExpArrObj::Push, Index out of reange", *this );        //MinFreeElem(number);        MakeSpaceAt( at_ix, number );        for( int ix=0; ix<number; ix++ ) {        	memcpy( this->ta+at_ix+ix, &this->GetNullElem(), sizeof(T) );            //new ((void*)(this->ta+at_ix+ix)) T();            this->ta[at_ix+ix] = elems[ix];        }        return *this;    }    ExpArrObj& Remove( INT number, INT at_ix ) {  // At arbitrary position        if( number<0 || at_ix<0 || at_ix+number>this->cur_size ) EA_THROW_RV( "ExpArr::Remove, Invalid number and/or index", *this );        INT to_ix = at_ix+number;        // Destructors on elements to be removed        for( INT ix=at_ix; ix<to_ix; ix++ )            this->ta[this->ix].~T();        ExpArr<T,INT>::Remove(number,at_ix);        return *this;    }    ExpArrObj& operator = ( const ExpArrObj<T,INT>& other ) {        // Same code as base case, but Push calls local func        this->Empty();        Push( other.ta, other.cur_size );        return *this;    }    bool operator == ( const ExpArrObj<T,INT>& other ) const {        if( this->cur_size!=other.cur_size ) return false;        for( INT ix=0;ix<this->cur_size;ix++ )            if ( !(this->ta[ix]==other.ta[ix]) )                return false;        return true;    }};// ExpArrPOwn is the owner of its elements and will delete all elems in destructortemplate<class T, class INT=int >class ExpArrPOwn : public ExpArrP<T,INT> {public:    // Forwarding ctors    ExpArrPOwn( const T *pt, INT n ) : ExpArrP<T,INT>(pt,n) {  }    ExpArrPOwn( const ExpArr<T,INT> &ea ) : ExpArrP<T,INT>(ea) { }    ExpArrPOwn( const ExpArr<T,INT> &ea, bool is_move ) : ExpArrP<T,INT>(ea,is_move) { }    ExpArrPOwn( ) : ExpArrP<T,INT>() { }    ~ExpArrPOwn(){        this->DeleteAll();    }};// Type registration, if typeof.h included before us#ifdef TYPEOF_H    #undef TYPE_REG_FILE    #define TYPE_REG_FILE 100    TYPE_REG_T2(ArrBase)    TYPE_REG_T2(ExpArr)     // We need to redo the InnerType stuff    TYPE_REG_T2(ExpArrObj)      TYPE_REG_T2(ExpArrP)       TYPE_REG_T2(ExpArrPOwn)           template<class T, class INT>    struct IterTypes<ExpArrObj<T,INT> > {        // integer default index        typedef int ix_type;        // For ExpArrObj, use reference by default        typedef T& e_type;        static T& GetEInit(){ return ExpArrObj<T,INT>::GetNullElem(); }    };#endif/*// An ExpArr that has a custome allocatortemplate <class T, class INT=int,           AllocFunc AF=&NewArrAlloc<T>, FreeFunc FF=&DelArrFree<T> >class ExpArrAlloc {public:};*/#endif // EXPARR_HPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -