#ifndef GIAC_VECTOR_H #define GIAC_VECTOR_H // Simple vector implementation for giac // Incomplete (allocation is handled by new/delete) // compatible with alias_ref_vecteur and without all VISUALC++ checks #include // #include // define IMMEDIATE_VECTOR if you want to use imvector #define immvector_max 1 << 30 namespace std { // inline void swapptr(void * & a,void * & b){ register void * c=a; a=b; b=c; } inline unsigned _abs(int i){ return i>=0?(i==immvector_max?0:i):-i;} inline int nextpow2(int n){ if (n>=16){ return n>=64?n:(n>32?64:32); } else { return n>8?16:(n>4?8:4); } } template class giac_reverse_pointer { _Tp * ptr; public: giac_reverse_pointer(): ptr(0) {} giac_reverse_pointer(_Tp *p): ptr(p) {} giac_reverse_pointer(const giac_reverse_pointer & p): ptr(p.ptr) {} giac_reverse_pointer operator +(int n){ return ptr-n; } giac_reverse_pointer operator -(int n){ return ptr+n; } giac_reverse_pointer & operator ++(){ --ptr; return *this; } giac_reverse_pointer & operator --(){ ++ptr; return *this; } _Tp & operator *() { return *ptr; } const _Tp operator *() const { return *ptr; } bool operator ==(const giac_reverse_pointer & other) const { return ptr==other.ptr; } bool operator !=(const giac_reverse_pointer & other) const { return ptr!=other.ptr; } int operator -(const giac_reverse_pointer & other) const { return int(other.ptr-ptr); } }; // define IMMEDIATE_VECTOR to an integer>=1 for non-dynamical small vectors #if defined(IMMEDIATE_VECTOR) #define _begin_immediate_vect _ptr[0] #define _endalloc_immediate_vect _ptr[1] template class imvector{ // private members int _taille; // <=0 for immediate, >0 for allocated, immvector_max for empty allocated union { _Tp *_ptr[2]; // ptr[0]==begin_immediate_vect, ptr[1]==endalloc_immediate_vect int _tab[IMMEDIATE_VECTOR]; }; // private allocation methods void _zero_tab(){ for (unsigned i=0;i0){ if (_begin_immediate_vect) { // std::cerr << "delete " << _taille << endl; delete [] _begin_immediate_vect; } } else _free_tab(); } void _realloc(unsigned n){ if (n<=(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp)){ if (_taille!=immvector_max){ for (int i=n;i<_taille;i++){ *(_begin_immediate_vect+i)=_Tp(); } } return; } if (_taille<=0){ // dyn alloc the vector _taille=(_taille?-_taille:immvector_max); n=nextpow2(n); _Tp * _newbegin = new _Tp[n]; if (_taille=int(n) ) return; n=nextpow2(n); _Tp * _newbegin = new _Tp[n]; _Tp * _end_immediate_vect = _begin_immediate_vect+(_taille==immvector_max?0:_taille); for (_Tp * ptr=_begin_immediate_vect;ptr!=_end_immediate_vect;++ptr,++_newbegin){ *_newbegin = *ptr; } _newbegin -= (_taille==immvector_max?0:_taille); if (_begin_immediate_vect) delete [] _begin_immediate_vect; _begin_immediate_vect=_newbegin; _endalloc_immediate_vect=_begin_immediate_vect+n; } void _alloc(unsigned n){ _zero_tab(); if (n<=(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp)){ _taille=-int(n); } else { _taille=(n?n:immvector_max); n=nextpow2(n); _begin_immediate_vect = new _Tp[n]; _endalloc_immediate_vect=_begin_immediate_vect+n; } } void _alloc_fill(const _Tp * b,const _Tp * e){ unsigned n=unsigned(e-b); if (n<=(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp)){ _zero_tab(); _taille = -int(n); for (unsigned i=0;i reverse_iterator; typedef giac_reverse_pointer const_reverse_iterator; imvector():_taille(0) { _zero_tab(); } ~imvector() { _destroy(); } imvector(size_t n_,const _Tp & value=_Tp()){ unsigned n=unsigned(n_); _alloc(n); _Tp * _end_immediate_vect=_taille>0?_begin_immediate_vect:(_Tp *)_tab; for (unsigned i=0;i & w){ const _Tp * ptr=w.begin(); _alloc_fill(ptr,ptr+_abs(w._taille)); } imvector<_Tp> & operator = (const imvector<_Tp> & w){ if (this==&w) return *this; _Tp copie[IMMEDIATE_VECTOR]; _Tp * wbeg; unsigned n=_abs(w._taille),i=0; #ifdef NO_WORKAROUND if (w._taille<0){ wbeg=copie; for (unsigned j=0;j for (unsigned j=0;j0?_begin_immediate_vect:((_Tp *) _tab); } iterator end(){ return _taille>0?_begin_immediate_vect+_abs(_taille):((_Tp *) _tab)-_taille;} const_iterator begin() const { return _taille>0?_begin_immediate_vect:((_Tp *) _tab); } const_iterator end() const { return _taille>0?_begin_immediate_vect+_abs(_taille):((_Tp *) _tab)-_taille;} reverse_iterator rbegin(){ return _taille>0?_begin_immediate_vect+_abs(_taille)-1:((_Tp *) _tab)-_taille-1; } reverse_iterator rend(){ return _taille>0?_begin_immediate_vect-1:((_Tp *) _tab)-1;} const_reverse_iterator rbegin() const { return _taille>0?_begin_immediate_vect+_abs(_taille)-1:((_Tp *) _tab)-_taille-1; } const_reverse_iterator rend() const { return _taille>0?_begin_immediate_vect-1:((_Tp *) _tab)-1;} size_t size() const { return _abs(_taille); } size_t capacity() const { return _taille<0?(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp):_endalloc_immediate_vect-_begin_immediate_vect;} _Tp & front() { return *begin(); } _Tp & back() { return *rbegin(); } _Tp & operator [](size_t i) { return *(begin()+i); } const _Tp & front() const { return *begin(); } const _Tp & back() const { return *rbegin(); } const _Tp & operator [](size_t i) const { return *(begin()+i); } void push_back(const _Tp & p0){ if (_taille<=0){ if (unsigned(-_taille)<(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp)){ ((_Tp *) _tab)[-_taille]=p0; --_taille; return; } // create a copy since p0 may be scratched // if p0 is a vector element and the vector is realloced _Tp p(p0); _realloc(_taille?-2*_taille:1); if (_taille==immvector_max){ *(_begin_immediate_vect)=p; _taille=1; } else { *(_begin_immediate_vect+_taille)=p; ++_taille; } return; } if (_taille==immvector_max) _taille=0; if (_endalloc_immediate_vect==_begin_immediate_vect+_taille){ _Tp p(p0); _realloc(_taille?2*_taille:1); *(_begin_immediate_vect+_taille)=p; } else *(_begin_immediate_vect+_taille)=p0; ++_taille; } _Tp pop_back(){ if (_taille<=0){ if (_taille) ++_taille; _Tp res=*( ((_Tp *) _tab) -_taille); *(((_Tp *) _tab)-_taille)=_Tp(); return res; } --_taille; if (_taille){ _Tp res=*(_begin_immediate_vect+_taille); *(_begin_immediate_vect+_taille)=_Tp(); return res; } _Tp res=*_begin_immediate_vect; delete [] _begin_immediate_vect; _zero_tab(); return res; } void clear(){ if (_taille>0 &&_begin_immediate_vect){ if (_taille!=immvector_max){ for (int i=0;i<_taille;++i) *(_begin_immediate_vect+i)=_Tp(); _taille=immvector_max; } } else { if (_taille<0) _free_tab(); _taille=0; } } bool empty() const { return _taille==0 || _taille==immvector_max; } void reserve(size_t n){ if (_abs(_taille)=n) { // clear elements from _begin()+n to _end() _Tp * ptr = begin()+n; for (;ptr!=end();++ptr) *ptr=_Tp(); _taille=_taille>0?(n?n:immvector_max):-int(n); } else { unsigned prev=_taille==immvector_max?0:_abs(_taille); _realloc(n); if (_taille<=0) _taille=-int(n); else _taille=n?n:immvector_max; } } void resize(size_t n_,const _Tp &value){ unsigned n=unsigned(n_); if (_taille!=immvector_max && _abs(_taille)>=n) { // clear elements from _begin()+n to _end() _Tp * ptr = begin()+n; for (;ptr!=end();++ptr) *ptr=value; _taille=_taille>0?(n?n:immvector_max):-int(n); } else { unsigned prev=_taille==immvector_max?0:_abs(_taille); _realloc(n); _Tp * ptr=begin()+prev; for (unsigned i=prev;i=_abs(_taille)){ clear(); return; } _Tp * _end_immediate_vect=end(); for (_Tp * ptr=e;ptr!=_end_immediate_vect;++ptr){ *(ptr-decal)=*ptr; *ptr = _Tp(); } if (_taille<0) { _taille += decal; } else { _taille -= decal; if (!_taille) _taille=immvector_max; } } void erase(_Tp * b){ erase(b,b+1); } _Tp * insert(_Tp * b, const _Tp& x ){ if (_taille==0){ push_back(x); return begin(); } if (_taille<=0){ if (unsigned(-_taille)<(sizeof(int)*IMMEDIATE_VECTOR)/sizeof(_Tp)){ --_taille; for (_Tp * ptr=((_Tp *) _tab)-_taille-1;ptr!=b;--ptr){ *ptr=*(ptr-1); } *b=x; return b; } int pos=int(b-((_Tp *) _tab)); _realloc(_abs(_taille)?2*(-_taille):1); b=_begin_immediate_vect+pos; } if (int(_abs(_taille))==_endalloc_immediate_vect-_begin_immediate_vect){ int pos=int(b-_begin_immediate_vect); _realloc(_abs(_taille)?2*_taille:1); b=_begin_immediate_vect+pos; } if (_taille==immvector_max) _taille=1; else ++_taille; for (_Tp * ptr=_begin_immediate_vect+_abs(_taille)-1;ptr!=b;--ptr){ *ptr=*(ptr-1); } *b=x; return b; } void insert(_Tp * b, unsigned k,const _Tp& x ){ if (_taille<=0){ int pos=int(b-((_Tp *) _tab)); _realloc(k+IMMEDIATE_VECTOR); b=_begin_immediate_vect+pos; } if (_endalloc_immediate_vect-_begin_immediate_vect & w){ char ch[sizeof(imvector<_Tp>)]; memcpy((void *)ch,(void *)&w,sizeof(imvector<_Tp>)); memcpy(&w,this,sizeof(imvector<_Tp>)); memcpy(this,(void *)ch,sizeof(imvector<_Tp>)); } void assign(size_t n_,const _Tp & value=_Tp()){ unsigned n=unsigned(n_); _realloc(n); _taille=_taille>0?(n?n:immvector_max):-n; unsigned i=0; for (_Tp * ptr=_begin_immediate_vect;i0?(n?n:immvector_max):-n; for (_Tp * ptr=_begin_immediate_vect;b!=e;++b,++ptr){ *ptr=*b; } } unsigned max_size() const { return (1 << 30) -1; } static _Tp &OutOfBoundsDefault() { static _Tp value; value = _Tp(); return value; } _Tp & at(size_t n){ if (n>_abs(_taille)) return OutOfBoundsDefault(); return *(begin()+n); } const _Tp at(size_t n) const { if (n>_abs(_taille)) return OutOfBoundsDefault(); return *(begin()+n); } }; template inline bool operator==(const imvector<_Tp>& __x, const imvector<_Tp>& __y){ if (__x.size() != __y.size()) return false; const _Tp * xend=__x.end(); for (const _Tp * xptr=__x.begin(), * yptr=__y.begin();xptr!=xend;++yptr,++xptr){ if (*xptr!=*yptr) return false; } return true; } template inline bool operator < (const imvector<_Tp>& __x, const imvector<_Tp>& __y){ if (__x.size() != __y.size()) return __x.size()<__y.size(); const _Tp * xend=__x.end(); for (const _Tp * xptr=__x.begin(), * yptr=__y.begin();xptr!=xend;++yptr,++xptr){ if (*xptr!=*yptr) return *xptr<*yptr; } return false; } template void swap(imvector<_Tp>& __x,imvector<_Tp>& __y){ __x.swap(__y); } #else // IMMEDIATE_VECTOR #define imvector vector #endif // IMMEDIATE_VECTOR } // namespace std #ifndef GIAC_VECTOR #include #else namespace std { template class vector{ // private members _Tp * _begin,*_end,*_endalloc; // private allocation methods void _realloc(unsigned n){ if (_endalloc-_begin>=int(n)) return; unsigned old=unsigned(_end-_begin); _Tp * _newbegin = new _Tp[n]; for (_Tp * ptr=_begin;ptr!=_end;++ptr,++_newbegin){ *_newbegin = *ptr; } _newbegin -= old; if (_begin) delete [] _begin; _begin=_newbegin; _end=_begin+old; _endalloc=_begin+n; } void _alloc(unsigned n){ _end=_begin = new _Tp[n]; _endalloc=_begin+n; } void _alloc_fill(const _Tp * b,const _Tp * e){ unsigned n=unsigned(e-b); _alloc(n); for (_Tp * ptr=_begin;ptr!=_endalloc;++ptr,++b){ *ptr = *b; } _end = _begin+ n; } public: typedef _Tp value_type; typedef _Tp * pointer; typedef const _Tp * const_iterator; typedef pointer iterator; typedef giac_reverse_pointer<_Tp> reverse_iterator; typedef giac_reverse_pointer const_reverse_iterator; vector():_begin(0),_end(0),_endalloc(0) {} ~vector() { if (_begin) delete [] _begin; } vector(size_t n_,const _Tp & value=_Tp()){ unsigned n=unsigned(n_); _alloc(n); for (;_end!=_endalloc;++_end){ *_end =value; } } vector(const const_iterator & b,const const_iterator & e){ _alloc_fill(b,e); } vector(const vector<_Tp> & w){ _alloc_fill(w._begin,w._end); } vector<_Tp> & operator = (const vector<_Tp> & w){ if (this==&w) return *this; unsigned n=unsigned(w._end-w._begin); _realloc(n); _end=_begin; for (_Tp * ptr=w._begin;ptr!=w._end;++_end,++ptr){ *_end = *ptr; } return *this; } iterator begin(){ return _begin; } iterator end(){ return _end;} const_iterator begin() const { return _begin; } const_iterator end() const { return _end;} reverse_iterator rbegin(){ return _end-1; } reverse_iterator rend(){ return _begin-1;} const_reverse_iterator rbegin() const { return _end-1; } const_reverse_iterator rend() const { return _begin-1;} size_t size() const { return _end-_begin; } size_t capacity() const { return _endalloc-_begin;} _Tp & front() { return *_begin; } _Tp & back() { return *(_end-1); } _Tp & operator [](size_t i) { return *(_begin+i); } const _Tp & front() const { return *_begin; } const _Tp & back() const { return *(_end-1); } const _Tp & operator [](size_t i) const { return *(_begin+i); } void push_back(const _Tp & p){ if (_endalloc==_end){ unsigned n = unsigned(_end-_begin); _realloc(n?2*n:2); } *_end=p; ++_end; } _Tp pop_back(){ --_end; return *_end; } void clear(){ _end=_begin;} bool empty() const { return _end==_begin; } void reserve(size_t n){ if (_endalloc-_begin=n) _end=_begin+n; else { _realloc(n); for (;_end!=_endalloc;++_end){ *_end=value; } } } void erase(_Tp * b,_Tp * e){ unsigned decal=unsigned(e-b); if (!decal) return; for (_Tp * ptr=e;ptr!=_end;++ptr){ *(ptr-decal)=*ptr; } _end -= decal; } void erase(_Tp * b){ erase(b,b+1); } _Tp * insert(_Tp * b, const _Tp& x ){ if (_endalloc==_end){ unsigned pos=unsigned(b-_begin); unsigned n = unsigned(_end-_begin); _realloc(n?2*n:2); b=_begin+pos; } ++_end; for (_Tp * ptr=_end-1;ptr!=b;--ptr){ *ptr=*(ptr-1); } *b=x; return b; } void insert(_Tp * b, unsigned k,const _Tp& x ){ if (_endalloc<_end+k){ unsigned pos=unsigned(b-_begin); unsigned n = unsigned(_end-_begin); _realloc(n>k?2*n:n+k); b=_begin+pos; } _end += k ; for (_Tp * ptr=_end-k;ptr!=b;){ --ptr; *(ptr+k)=*ptr; } for (unsigned j=0;j & w){ _Tp * tmp=_begin; _begin=w._begin; w._begin=tmp; tmp=_end; _end=w._end; w._end=tmp; tmp=_endalloc; _endalloc=w._endalloc; w._endalloc=tmp; } void assign(size_t n_,const _Tp & value=_Tp()){ unsigned n=unsigned(n_); _realloc(n); _end = _begin +n; for (_Tp * ptr=_begin;ptr!=_end;++ptr){ *ptr=value; } } void assign(const _Tp * b,const _Tp * e){ unsigned n=unsigned(e-b); _realloc(n); _end = _begin +n; for (_Tp * ptr=_begin;b!=e;++b,++ptr){ *ptr=*b; } } unsigned max_size() const { return 1 << 30; } _Tp & at(size_t n){ if (n>_end-_begin) return _Tp(); // should be defined somewhere else return *(_begin+n); } const _Tp at(size_t n) const { if (n>_end-_begin) return _Tp(); // should be defined somewhere else return *(_begin+n); } }; template inline bool operator==(const vector<_Tp>& __x, const vector<_Tp>& __y){ if (__x.size() != __y.size()) return false; for (const _Tp * xptr=__x.begin(), * yptr=__y.begin();xptr!=__x.end();++yptr,++xptr){ if (*xptr!=*yptr) return false; } return true; } // template inline bool operator!=(const vector<_Tp>& __x, const vector<_Tp>& __y){ return !(__x==__y); } template inline bool operator < (const vector<_Tp>& __x, const vector<_Tp>& __y){ if (__x.size() != __y.size()) return __x.size()<__y.size(); for (const _Tp * xptr=__x.begin(), * yptr=__y.begin();xptr!=__x.end();++yptr,++xptr){ if (*xptr!=*yptr) return *xptr<*yptr; } return false; } template inline bool operator > (const _Tp & __x, const _Tp & __y){ return __y<__x; } template inline bool operator >= (const _Tp & __x, const _Tp & __y){ return !(__x<__y); } template inline bool operator <= (const _Tp & __x, const _Tp & __y){ return !(__y<__x); } } #endif #endif // GIAC_VECTOR_H