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

📄 wy_array.h

📁 一个不错
💻 H
📖 第 1 页 / 共 4 页
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2006  This file is header only.  Note: Members are cancellation point iff the refered element members are        cancellation points.  Conversion of some functions in consideration might need an array (poll,  scattered i/o,getaddrinfo,..might not).   Wy_Array reduces dependency of this library on std::vector (and different rule)  ,probably applications. Just go on and see. .Function members basically throw Reply to report error to avoid both testing  returned and thrown object. .Element type as enum is limited in use .2D/3D dimension use are not particularly supported .Problem with static member class_name .function members for argument type WySeg<const T> are not documented*/#ifndef WY_ARRAY_H__#define WY_ARRAY_H__#define WY_ARRAY_VERSION 31#include "wyret.h"#include <new>#include "wyseg.h"#ifdef WY_DEBUG // Precondition check #define WY__CHK_VALIDOBJ(x) \     if( ((x)._b_bgn==NULL)||\         ((x)._b_eob<(x)._b_end)||\         ((x)._b_end<(x)._b_bgn) ) {\         WY_TERMINATE("");\       }#else #define WY__CHK_VALIDOBJ(x) (void)0#endifconst size_t Wy_Array_MaxSizeRawMemory=(INT_MAX/2)-1;  // max array byte sizeconst size_t Wy_Array_MinimumCapacity=4;  // default capacityconst size_t Wy_Array_DefaultSize=0;      // must be 0template<typename T>class Wy_Array {    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    // [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] Destruct elements pointed in range [p1,p2).    //       Destruction order is from the last element to the first.    //    // [Throw] from ~T()    //    //  Note: If destructing an element throws, the destruction process goes on    //        for the rest and then rethrow, or double throws encountered.    //    inline static void _destruct(ElemType* p1, ElemType* p2)           {             for(; p1!=p2;) try {               --p2;               p2->~ElemType();             }             catch(...) {               while(p2!=p1) {                 --p2;                 p2->~ElemType();               }               throw;             };           };    // [Syn] Destruct one element pointed by p    //    // [Throw] from ~T()    //    inline static void _destruct(ElemType* p)           { p->~ElemType(); };    // [Syn] Allocate an array of capacity cap, and copy construct the front    //       part of the array from [buf, buf+n_elem)    //    //  Note: assert(cap>=n_elem) to call    //    // [Throw] from T(T)    //    // Note: ~T() throw leads to std::terminate() (double throw)    //    // [Ret] ElemType pointer to an allocated array whit elements copy    //         constructed from buf    //       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);         }         // copy construct element in the new array         ElemType *des_ptr(narr);         try {           for( ; n_elem; ++buf,++des_ptr,--n_elem) {             new(des_ptr) ElemType(*buf);           };         }         catch(...) {           _destruct(narr,des_ptr);           _free_raw(narr);           throw;         };         return(narr);       };     // [Syn] Move n objects pointed by src to raw memory pointed     //       by dest     //     static void _objmove(ElemType* dest, ElemType* src, SizeType n) WY__NOTHROW__       {        if(dest<src) {          for( ; n; ++src,++dest,--n) {            new(dest) ElemType(*src,Wy::ByMove);          }        } else {          if(n==0) {            return;          }          --n;          src+=n;          dest+=n;          for(;;) {            new(dest) ElemType(*src,Wy::ByMove);            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_Array() WY__TSPC(Reply)      : _b_bgn(_alloc_raw(MinimumCapacity*sizeof(ElemType))),        _b_end(_b_bgn),        _b_eob(_b_bgn+MinimumCapacity)    {      if(_b_bgn==NULL) {        WY_THROW( Reply(Wym_ENOMEM) );      }      WY__CHK_VALIDOBJ(*this);    };    // Note: ctor(size_t) is still considered questionable in concept     //       (conversion ctor), so use this version instead. e.g reset(size_t)    //       may be confusing. Alternatively, that ctor(size_t n) means to    //       reserve n capacity is also meaningful (== new T[n])    //    Wy_Array(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( Reply(Wym_EFBIG) );      }      _b_end=_b_bgn=_alloc_raw(cap*sizeof(ElemType));      if(_b_bgn==NULL) {        WY_THROW( Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+n_elem;      try {        for(; _b_end!=_b_eob; ++_b_end) {          new(_b_end) ElemType(elem);        }      }      catch(...) {        _destruct(_b_bgn,_b_end);        _free_raw(_b_bgn);        _b_bgn=_b_end=NULL; _b_eob=NULL;        throw;      };      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    Wy_Array(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( Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+src_size;      try {        ElemType *ep( src.begin() );        for(; _b_end!=_b_eob; ++_b_end, ++ep) {          new(_b_end) ElemType(*ep);        }      }      catch(...) {        _destruct(_b_bgn,_b_end);        _free_raw(_b_bgn);        _b_bgn=_b_end=NULL; _b_eob=NULL;        throw;      };      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    // note: This member might be considered an invisible overload. Manual does    //       not list the versions of const element type, for looked inconsistent    //    Wy_Array(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( Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+src_size;      try {        const ElemType *ep( src.begin() );        for(; _b_end!=_b_eob; ++_b_end, ++ep) {          new(_b_end) ElemType(*ep);        }      }      catch(...) {        _destruct(_b_bgn,_b_end);        _free_raw(_b_bgn);        _b_bgn=_b_end=NULL; _b_eob=NULL;        throw;      };      _b_eob=_b_bgn+cap;      WY__CHK_VALIDOBJ(*this);    };    Wy_Array(const Wy_Array& src)      : _b_bgn(NULL),  _b_end(NULL), _b_eob(NULL)    {      WY__CHK_VALIDOBJ(src);      const SizeType cap( src.size()> Wy_Array::min_capacity()?                          src.size(): Wy_Array::min_capacity() );      _b_bgn=_dup_array(src._b_bgn,src.size(),cap);      if(_b_bgn==NULL) {        WY_THROW( Reply(Wym_ENOMEM) );      }      _b_eob=_b_bgn+cap;      _b_end=_b_bgn+src.size();      WY__CHK_VALIDOBJ(*this);    };    Wy_Array(Wy_Array& 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__CHK_VALIDOBJ(*this);       };    ~Wy_Array()     {      WY__CHK_VALIDOBJ(*this);      try {        _destruct(_b_bgn,_b_end);      }      catch(...) {        _free_raw(_b_bgn);        throw;      };      _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__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( Reply(Wym_ENOENT) );        }        return *_b_bgn;       };    const ElemType& front(void) const WY__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( Reply(Wym_ENOENT) );        }        return *_b_bgn;       };    ElemType& back(void) WY__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( Reply(Wym_ENOENT) );        }        return *(_b_end-1);       };    const ElemType& back(void) const WY__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        if(_b_end==_b_bgn) {          WY_THROW( 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__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        const SizeType csize(_b_end-_b_bgn);        if(idx>csize) {          WY_THROW( Reply(Wym_EINVAL) );        }        return WySeg<ElemType>(_b_bgn+idx,csize-idx);      };    WySeg<ElemType> subseg(SizeType idx, SizeType num) const WY__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        SizeType rs(_b_end-_b_bgn);        if(idx>rs) {          WY_THROW( Reply(Wym_EINVAL) );        }        rs-=idx;        if(rs>num) {          rs=num;        }        return WySeg<ElemType>(_b_bgn+idx,rs);      };    const ElemType& operator[](SizeType n) const WY__TSPC(Reply)      {        WY__CHK_VALIDOBJ(*this);        if(n>=SizeType(_b_end-_b_bgn)) {          WY_THROW( Reply(Wym_EINVAL) );        }        return _b_bgn[n];      };    ElemType& operator[](SizeType n) WY__TSPC(Reply)

⌨️ 快捷键说明

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