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

📄 wy__arrayvalue.h

📁 一个不错
💻 H
📖 第 1 页 / 共 3 页
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2006  This file is part of wy_array.h*/#include <cstring>    // for memcpy,memmove// Element type T is for POD (memcpy and operator= work) such as arithmetic types,// pointer types,.. for those built-in types do not have the move constructor.//template<typename T>class Wy__ArrayValue {    typedef T ElemType;    typedef size_t SizeType;    static const SizeType MaxSizeRawMemory;    static const SizeType MinimumCapacity;    static const SizeType DefaultSize;    ElemType* _b_bgn;           // array begin pointer    ElemType* _b_end;           // end pointer of constructed objects    const ElemType* _b_eob;     // array end storage ptr    //    static SizeType _byte_dist(const ElemType* p2, const ElemType* p1)          { return static_cast<const char*>(p2)-static_cast<const char*>(p1); };    // [Syn] Allocate n bytes of raw memory block    //    // [Ret] ElemType pointer to n bytes of raw memory block    //       NULL= Not enough memory    //    inline static ElemType* _alloc_raw(size_t n) WY__TSPC() {             return reinterpret_cast<ElemType*>(::operator new(n,std::nothrow));           };     // [Syn] Free the memory block allocated by _alloc_raw(size_t)    //    inline static void _free_raw(ElemType* v) WY__TSPC() {             ::operator delete(v);           };    // [Syn] Allocate an array of capacity cap, and copy the front    //       part of the array from [buf, buf+n_elem)    //    //  Note: assert(cap>=n_elem) to call    //    // [Ret] ElemType pointer to such array    //       NULL= Not enough memory    //    // [Depend] T(T), ~T()    //    static ElemType* _dup_array(const ElemType* buf, SizeType n_elem, SizeType cap)       {         // allocate another array of cap capacity         ElemType *narr=_alloc_raw(cap*sizeof(ElemType));         if(narr==NULL) {           return(NULL);         }         std::memcpy(narr,buf,n_elem*sizeof(ElemType));         return(narr);       };     static void _objmove(ElemType* dest, ElemType* src, SizeType n) WY__NOTHROW__       {        if(dest<src) {          for( ; n; ++src,++dest,--n) {            *dest=*src;          }        } else {          if(n==0) {            return;          }          --n;          src+=n;          dest+=n;          for(;;) {            *dest=*src;            if(n==0) {              break;            }            --src;            --dest;            --n;          };        }       };  public:    //WY_THROW_REPLY;    typedef ElemType value_type;    typedef SizeType size_type;    static  SizeType max_capacity(void) WY__TSPC()       { return MaxSizeRawMemory/sizeof(ElemType); };    static SizeType min_capacity(void) WY__TSPC()       { return(MinimumCapacity); };    Wy__ArrayValue()      : _b_bgn(_alloc_raw(MinimumCapacity*sizeof(ElemType))),        _b_end(_b_bgn),        _b_eob(_b_bgn+MinimumCapacity)    {      if(_b_bgn==NULL) {        WY_THROW(typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );      }      WY__CHK_VALIDOBJ(*this);    };    Wy__ArrayValue(size_t n_elem, const ElemType& elem)      : _b_bgn(NULL), _b_end(NULL), _b_eob(NULL)    {      const SizeType cap( n_elem<MinimumCapacity? MinimumCapacity : n_elem );      if(cap>this->max_capacity()) {        WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EFBIG) );      }      _b_end=_b_bgn=_alloc_raw(cap*sizeof(ElemType));      if(_b_bgn==NULL) {        WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+n_elem;      for(; _b_end!=_b_eob; ++_b_end) {        *_b_end= elem;      }      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    Wy__ArrayValue(const WySeg<ElemType>& src)      : _b_bgn(NULL), _b_end(NULL), _b_eob(NULL)    {      const SizeType src_size( src.size() );      const SizeType cap( src_size<MinimumCapacity? MinimumCapacity : src_size );      _b_end=_b_bgn=_alloc_raw(cap*sizeof(ElemType));      if(_b_bgn==NULL) {        WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+src_size;      for(ElemType *ep(src.begin()); _b_end!=_b_eob; ++_b_end,++ep) {        *_b_end= ElemType(*ep);      }      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    Wy__ArrayValue(const WySeg<const ElemType>& src)      : _b_bgn(NULL), _b_end(NULL), _b_eob(NULL)    {      const SizeType src_size( src.size() );      const SizeType cap( src_size<MinimumCapacity? MinimumCapacity : src_size );      _b_end=_b_bgn=_alloc_raw(cap*sizeof(ElemType));      if(_b_bgn==NULL) {        WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+src_size;      for(const ElemType *ep(src.begin()); _b_end!=_b_eob; ++_b_end,++ep) {        *_b_end= ElemType(*ep);      }      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    Wy__ArrayValue(const Wy__ArrayValue& src)      : _b_bgn(NULL),  _b_end(NULL), _b_eob(NULL)    {      WY__CHK_VALIDOBJ(src);      const SizeType cap( src.size()> Wy_Array<ElemType>::min_capacity()?                          src.size(): Wy_Array<ElemType>::min_capacity() );      _b_bgn=_dup_array(src._b_bgn,src.size(),cap);      if(_b_bgn==NULL) {        WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+cap;      _b_end=_b_bgn+src.size();      WY__CHK_VALIDOBJ(*this);    };    Wy__ArrayValue(Wy__ArrayValue& p, Wy::ByMove_t) WY__TSPC()      {         // move semantics of p to this         _b_bgn= p._b_bgn;         _b_end= p._b_end;         _b_eob= p._b_eob;         #ifdef WY_DEBUG         // cleanup semantics of p         p._b_bgn=p._b_end=NULL; p._b_eob=NULL;         #endif      };    ~Wy__ArrayValue()     {      WY__CHK_VALIDOBJ(*this);      _free_raw(_b_bgn);      _b_bgn=_b_end=NULL; _b_eob=NULL;    };    bool is_default(void) const WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_end==_b_bgn;       };    SizeType size(void) const WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_end-_b_bgn;       };    // ** Note **    // These members expose the address of the internal dynamic buffer    ElemType* begin(void) WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_bgn; };    const ElemType* begin(void) const WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_bgn; };    const ElemType* end(void) const WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_end; };    ElemType* end(void) WY__TSPC()      { WY__CHK_VALIDOBJ(*this);        return _b_end; };    ElemType& front(void)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOENT) );        }        return *_b_bgn;       };    const ElemType& front(void) const      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOENT) );        }        return *_b_bgn;       };    ElemType& back(void)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOENT) );        }        return *(_b_end-1);       };    const ElemType& back(void) const      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOENT) );        }        return *(_b_end-1);       };    WySeg<ElemType> subseg(void) const      {        WY__CHK_VALIDOBJ(*this);        return WySeg<ElemType>(_b_bgn,SizeType(_b_end-_b_bgn));      };    WySeg<ElemType> subseg(SizeType idx) const      {        WY__CHK_VALIDOBJ(*this);        const SizeType csize(_b_end-_b_bgn);        if(idx>csize) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EINVAL) );        }        return WySeg<ElemType>(_b_bgn+idx,csize-idx);      };    WySeg<ElemType> subseg(SizeType idx, SizeType num) const      {      WY__CHK_VALIDOBJ(*this);        SizeType rs(_b_end-_b_bgn);        if(idx>rs) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EINVAL) );        }        rs-=idx;        if(rs>num) {          rs=num;        }        return WySeg<ElemType>(_b_bgn+idx,rs);      };    // Note: operator[] checks for valid position n    //       App. has to make sure n<size(), this could be difficult    //       with expr like: a[i][j][k]     //    const ElemType& operator[](SizeType n) const      {        WY__CHK_VALIDOBJ(*this);        if(n>=SizeType(_b_end-_b_bgn)) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EINVAL) );        }        return _b_bgn[n];      };    ElemType& operator[](SizeType n)      {        WY__CHK_VALIDOBJ(*this);        if(n>=SizeType(_b_end-_b_bgn)) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EINVAL) );        }        return _b_bgn[n];      };    // Note: capacity is intact    void reset(void)      {        WY__CHK_VALIDOBJ(*this);        _b_end=_b_bgn;      };    void reset(const WySeg<const ElemType>& src)      {        WY__CHK_VALIDOBJ(*this);        const SizeType src_size(src.size());        if(src_size<=this->_capacity()) {          if(src.is_overlap( WySeg<const ElemType>(_b_bgn,_b_eob-_b_bgn) )) {            WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ELOOP) );          }          ::memcpy(_b_bgn,src.begin(),src_size*sizeof(ElemType));          _b_end=_b_bgn+src_size;        } else {          // This algorithm duplicate src first          //          const SizeType cap( src_size>=Wy_Array<ElemType>::min_capacity()?                              src_size : Wy_Array<ElemType>::min_capacity() );          ElemType *ptmp=_dup_array(src.begin(),src_size,cap);          if(ptmp==NULL) {            WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );          }            _free_raw(_b_bgn);          _b_bgn=ptmp;          _b_end=ptmp+src_size;          _b_eob=ptmp+cap;        }        WY__CHK_VALIDOBJ(*this);      };    void reset(const WySeg<ElemType>& src)      {        WY__CHK_VALIDOBJ(*this);        const SizeType src_size(src.size());        if(src_size<=this->_capacity()) {          if(src.is_overlap( WySeg<ElemType>(_b_bgn,_b_eob-_b_bgn) )) {            WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ELOOP) );          }          ::memcpy(_b_bgn,src.begin(),src_size*sizeof(ElemType));          _b_end=_b_bgn+src_size;        } else {          // This algorithm duplicate src first          //          const SizeType cap( src_size>=Wy_Array<ElemType>::min_capacity()?                              src_size : Wy_Array<ElemType>::min_capacity() );          ElemType *ptmp=_dup_array(src.begin(),src_size,cap);          if(ptmp==NULL) {            WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );          }            _free_raw(_b_bgn);          _b_bgn=ptmp;          _b_end=ptmp+src_size;          _b_eob=ptmp+cap;        }        WY__CHK_VALIDOBJ(*this);      };    // Note: capacity is set to needed minimum if reallocation occurred,    //       otherwise capacity is intact    void reset(const Wy__ArrayValue& src)      {        WY__CHK_VALIDOBJ(*this);        const SizeType src_size(src.size());        if(src_size<=this->_capacity()) {          if(_b_bgn==src._b_bgn) {            return;        // v.reset(v)          }          ::memcpy(_b_bgn,src._b_bgn,src_size*sizeof(ElemType));          _b_end=_b_bgn+src_size;        } else {          // This algorithm duplicate src first          //          const SizeType cap( src_size>=Wy_Array<ElemType>::min_capacity()?                              src_size : Wy_Array<ElemType>::min_capacity() );          ElemType *ptmp=_dup_array(src._b_bgn,src_size,cap);          if(ptmp==NULL) {            WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_ENOMEM) );          }            _free_raw(_b_bgn);          _b_bgn=ptmp;          _b_end=ptmp+src_size;          _b_eob=ptmp+cap;        }        WY__CHK_VALIDOBJ(*this);      };    void reset(size_t n_elem, const ElemType& elem)      {        WY__CHK_VALIDOBJ(*this);        const SizeType cap( n_elem<MinimumCapacity? MinimumCapacity : n_elem );        if(cap>this->max_capacity()) {          WY_THROW( typename Wy_Array<ElemType>::Reply(Wym_EFBIG) );        }        if(cap<=this->_capacity()) {          _b_end=_b_bgn;          for(SizeType i=0; i<n_elem; ++i,++_b_end) {            *_b_end= elem;          }

⌨️ 快捷键说明

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