📄 wy_array.h
字号:
} // This algorithm reset *this first and reuse current array, // i.e. whatever copy constructor of ElemType throws will // be rethrown, *this is default. // try { _destruct(_b_bgn,_b_end); } catch(...) { // postcondion, for stack unwind from ~T() _b_end=_b_bgn; // is default for this member throw; }; _b_end=_b_bgn; // copy construct elements try { const ElemType *src_ptr(src.begin()); for( ; src_ptr!=src.end(); ++src_ptr,++_b_end) { new(_b_end) ElemType(*src_ptr); }; } catch(...) { _destruct(_b_bgn,_b_end); _b_end=_b_bgn; throw; }; } else { // This algorithm duplicate src first // const SizeType cap( src_size>=Wy_Array::min_capacity()? src_size : Wy_Array::min_capacity() ); ElemType *ptmp=_dup_array(src.begin(),src_size,cap); if(ptmp==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } // reset() *this try { _destruct(_b_bgn,_b_end); } catch(...) { // postcondion, for stack unwind from ~T() _b_end=_b_bgn; // is default for this member _destruct(ptmp,ptmp+src_size); _free_raw(ptmp); throw; }; _free_raw(_b_bgn); _b_bgn=ptmp; _b_end=ptmp+src_size; _b_eob=ptmp+cap; } WY__CHK_VALIDOBJ(*this); return(*this); }; // std: no swap() function invalidates any references,pointers,.. ??? // void swap(Wy_Array& v2) WY__TSPC() { WY__CHK_VALIDOBJ(*this); // v.swap(v) ok { ElemType* tmp(_b_bgn); _b_bgn=v2._b_bgn; v2._b_bgn=tmp; tmp=_b_end; _b_end=v2._b_end; v2._b_end=tmp; } { const ElemType* tmp(_b_eob); _b_eob=v2._b_eob; v2._b_eob=tmp; } WY__CHK_VALIDOBJ(*this); /* This definition may be better char buf[sizeof(Wy_Array)]; // might have alignment problem! new(buf) Wy_Array(v2,ByMove); new(v2) Wy_Array(*this,ByMove); new(this) Wy_Array(*((Wy_Array*)buf),ByMove); */ }; void push_back(const ElemType& elem) { WY__CHK_VALIDOBJ(*this); if(_b_end<_b_eob) { // elem in *this ok new(_b_end) ElemType(elem); ++_b_end; } else { // allocate another array twice as large const SizeType cap( (_b_eob-_b_bgn)<<1 ); if(cap>this->max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } ElemType *ptmp=_alloc_raw(cap*sizeof(ElemType)); if(ptmp==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } ElemType *des_ptr(ptmp+this->size()); // copy construct the argument object // (ok, if elem refers to the object inside *this) try { new(des_ptr) ElemType(elem); } catch(...) { _free_raw(ptmp); throw; }; // move all elements of *this to ptmp ElemType *src_ptr(_b_end-1); // _b_bgn!=_b_end --des_ptr; for(;;) { new(des_ptr) T(*src_ptr,Wy::ByMove); if(des_ptr==ptmp) { break; } --des_ptr; --src_ptr; } #ifdef WY_DEBUG if((des_ptr!=ptmp)||(src_ptr!=_b_bgn)) { WY_TERMINATE(""); } #endif // update _b_bgn,_b_end,_b_eob to the new array(ptmp) des_ptr=_b_end; _b_end=ptmp+(this->size()+1); _b_bgn=ptmp; _b_eob=ptmp+cap; _free_raw(src_ptr); } WY__CHK_VALIDOBJ(*this); }; void pop_back(void) { WY__CHK_VALIDOBJ(*this); if(_b_end==_b_bgn) { return; } --_b_end; _destruct(_b_end); WY__CHK_VALIDOBJ(*this); }; // considering: return _b_bgn // void erase(SizeType idx, SizeType n) { WY__CHK_VALIDOBJ(*this); ElemType *p1(_b_bgn+idx); if(p1>=_b_end) { if(p1==_b_end) { WY__CHK_VALIDOBJ(*this); return; } WY_THROW( Reply(Wym_EINVAL) ); } // assert( p1<_b_end ); ElemType *p2=_b_end; if(SizeType(p2-p1)>=n) { if(n<=0) { WY__CHK_VALIDOBJ(*this); return; } p2=p1+n; } // destruct elements [p1,p2) try { _destruct(p1,p2); } catch(...) { for( ; p2!=_b_end; ++p1,++p2) { new(p1) T(*p2,Wy::ByMove); } _b_end=p1; throw; }; for( ; p2!=_b_end; ++p1,++p2) { new(p1) T(*p2,Wy::ByMove); } _b_end=p1; WY__CHK_VALIDOBJ(*this); };/* This member may be redundent from resize(len) void erase(SizeType idx) { WY__CHK_VALIDOBJ(*this); ElemType *p1(_b_bgn+idx); if(p1>=_b_end) { if(p1==_b_end) { WY__CHK_VALIDOBJ(*this); return; } WY_THROW( Reply(Wym_EINVAL) ); } // assert( p1<_b_end ); // destruct elements [p1,_b_end) try { _destruct(p1,_b_end); } catch(...) { _b_end=p1; throw; }; _b_end=p1; WY__CHK_VALIDOBJ(*this); }; */ // considering: return _b_bgn, consider to remove // void insert(SizeType idx, const ElemType& elem) { WY__CHK_VALIDOBJ(*this); const SizeType OrgSize( this->size() ); if(idx>OrgSize) { WY_THROW( Reply(Wym_EINVAL) ); } if(OrgSize<this->_capacity()) { const ElemType InsElem(elem); // in case elem is in *this ElemType *p1(_b_bgn+idx); // insert point ElemType *p2(_b_end); for(; p2>p1; --p2) { new(p2) ElemType(*(p2-1),Wy::ByMove); } // if(WySeg<const ElemType>(_b_bgn,_b_eob).is_overlap( // WySeg<const ElemType>(&elem,SizeType(1)))) { // new(p2) ElemType(InsElem); } else { } try { new(p2) ElemType(InsElem); } catch(...) { for(; p2<_b_end; ++p2) { new(p2) ElemType(*(p2-1),Wy::ByMove); } throw; }; ++_b_end; } else { // allocate another array twice as large const SizeType cap( (_b_eob-_b_bgn)<<1 ); if(cap>this->max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } ElemType *ptmp=_alloc_raw(cap*sizeof(ElemType)); if(ptmp==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } ElemType *p1(ptmp+idx); // insert point try { new(p1) ElemType(elem); } catch(...) { _free_raw(ptmp); throw; }; ElemType *des_ptr(ptmp); ElemType *p2(_b_bgn); // move all elements in _b_bgn to ptmp for(; des_ptr!=p1; ++p2,++des_ptr) { new(des_ptr) ElemType(*p2,Wy::ByMove); } ++des_ptr; for(; p2!=_b_end; ++p2,++des_ptr) { new(des_ptr) ElemType(*p2,Wy::ByMove); } // update _b_bgn,_b_end,_b_eob to the new array(ptmp) p2=_b_bgn; _b_bgn=ptmp; _b_end=des_ptr; _b_eob=ptmp+cap; _free_raw(p2); } WY__CHK_VALIDOBJ(*this); }; void insert(SizeType idx, SizeType n_elem, const ElemType& elem) { WY__CHK_VALIDOBJ(*this); if(idx>this->size()) { WY_THROW( Reply(Wym_EINVAL) ); } if(this->size()+n_elem<=this->_capacity()) { if(n_elem==0) { return; } ElemType * const p0(_b_bgn+idx); // insert point ElemType *p1(_b_end); // point to the last+1 ElemType *p2(p1+n_elem); // move dest.+1 for(; p1>p0; ) { --p1; --p2; new(p2) ElemType(*(p1),Wy::ByMove); } try { p2=p0; for(SizeType i=0; i<n_elem; ++i,++p2) { new(p2) ElemType(elem); } } catch(...) { p1=p0; _destruct(p1,p2); for(p2=p1+n_elem; p1<_b_end; ++p1) { new(p1) ElemType(*(p2),Wy::ByMove); } throw; }; _b_end+=n_elem; } else { // allocate another array twice as large if(n_elem>this->max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const SizeType cap( (n_elem+this->size())<<1 ); if(cap>this->max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } ElemType *ptmp=_alloc_raw(cap*sizeof(ElemType)); if(ptmp==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } ElemType *p1(ptmp+idx); // insert point (in ptmp) ElemType *p2(p1); try { for(SizeType i=0; i<n_elem; ++i,++p2) { new(p2) ElemType(elem); } } catch(...) { _destruct(p1,p2); _free_raw(ptmp); throw; }; ElemType *des_ptr(ptmp); p2=_b_bgn; // move all elements in _b_bgn to ptmp for(; des_ptr!=p1; ++p2,++des_ptr) { new(des_ptr) ElemType(*p2,Wy::ByMove); } des_ptr+=n_elem; for(; p2!=_b_end; ++p2,++des_ptr) { new(des_ptr) ElemType(*p2,Wy::ByMove); } // update _b_bgn,_b_end,_b_eob to the new array(ptmp) p2=_b_bgn; _b_bgn=ptmp; _b_end=des_ptr; _b_eob=ptmp+cap; _free_raw(p2); } WY__CHK_VALIDOBJ(*this); }; void insert(SizeType idx, const WySeg<const ElemType>& src) { WY__CHK_VALIDOBJ(*this); if(idx>this->size()) { WY_THROW( Reply(Wym_EINVAL) ); } if(src.is_overlap( WySeg<const ElemType>(_b_bgn,(ElemType*)_b_eob) )) { WY_THROW( Reply(Wym_ELOOP) ); } const SizeType src_size( src.size() ); if(this->size()+src_size<=this->_capacity()) { if(src_size==0) { return; } ElemType * const p0(_b_bgn+idx); // insert point ElemType *p1(_b_end); // point to the last+1 ElemType *p2(p1+src_size); // move dest.+1 for(; p1>p0; ) { --p1; --p2; new(p2) ElemType(*(p1),Wy::ByMove); } try { p2=p0; for(SizeType i=0; i<src_size; ++i,++p2) { new(p2) ElemType(src[i]); } } catch(...) { p1=p0; _destruct(p1,p2); for(p2=p1+src_size; p1<_b_end; ++p1) { new(p1) ElemType(*(p2),Wy::ByMove); } throw;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -