00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _TemplateLibrary_Array_H_
00019 #define _TemplateLibrary_Array_H_ 1
00020
00028 #include <lib/sconfig.h>
00029
00030 #include <lib/salloc.h>
00031 #include <lib/tl/binsearch.h>
00032
00033
00065 template<typename T,typename _OP=TLDefaultOperators_CDT<T> >class TLArray
00066 {
00067 protected:
00068
00069 size_t asize;
00070 size_t nelem;
00071 char *_array;
00072
00073 public:
00076 _OP OP;
00077
00078 protected:
00080 inline T &array(size_t idx)
00081 { return(*(T*)(_array+idx*OP.size())); }
00083 inline T *arrayP(size_t idx)
00084 { return((T*)(_array+idx*OP.size())); }
00085
00087 virtual void _realloc(size_t new_asize)
00088 {
00089 char *new_array=(char*)OP.realloc(_array,new_asize*OP.size());
00090 _array=new_array; asize=new_asize;
00091 }
00093 void _free()
00094 {
00095 if(_array)
00096 { OP.free(_array); _array=NULL; }
00097 }
00099 size_t _get_downsize()
00100 {
00101 if(asize>512) return((asize-nelem)>512 ? asize-256 : asize);
00102 if(nelem<=16) return(16);
00103 return(asize-nelem>3*asize/4 ? asize-asize/2 : asize);
00104 }
00106 void _downsize()
00107 {
00108 size_t newsize=_get_downsize();
00109 if(newsize!=asize) _realloc(newsize);
00110 }
00112 inline void _upsize1()
00113 {
00114 if(nelem>=asize) _realloc(asize>512 ?
00115 (asize+512) : (asize ? asize*2 : 16));
00116 }
00118 void _clearall()
00119 {
00120 if(!OP.pdt) for(size_t i=nelem; i--;) OP.clr(arrayP(i));
00121 nelem=0;
00122 }
00123
00124 private:
00126 TLArray(const TLArray &);
00128 void operator=(const TLArray &);
00129 public:
00131 TLArray(const _OP &op=_OP()) : asize(0),nelem(0),_array(NULL),OP(op) {}
00133 virtual ~TLArray()
00134 { _clearall(); _free(); }
00135
00137 inline bool IsEmpty() const
00138 { return(!nelem); }
00139
00141 inline size_t NElem() const
00142 { return(nelem); }
00143
00154 inline T &operator[](size_t idx)
00155 { return(array(idx)); }
00157 inline const T &operator[](size_t idx) const
00158 { return(array(idx)); }
00159
00161 void clear(bool keep_memory=0)
00162 { _clearall(); if(!keep_memory && asize>32) _free(); }
00163
00175 int insert(const T &e,size_t idx)
00176 {
00177 if(idx>nelem) return(-2);
00178 _upsize1();
00179 if(idx==nelem) { OP.ini(arrayP(nelem++),e); return(0); }
00180 size_t i=nelem-1; OP.ini(arrayP(nelem++),array(i));
00181 for(; i>idx; i--) OP.ass(array(i),array(i-1));
00182 OP.ass(array(idx),e); return(0);
00183 }
00184
00195 int remove(size_t idx)
00196 {
00197 if(idx>=nelem) return(-2); --nelem;
00198 for(size_t i=idx; i<nelem; i++) OP.ass(array(i),array(i+1));
00199 OP.clr(arrayP(nelem)); _downsize(); return(0);
00200 }
00201
00212 inline int assign(const T &e,size_t idx)
00213 { if(idx>=nelem) return(-2); OP.ass(array(idx),e); return(0); }
00214
00224 template<typename K>inline ssize_t LinSearch(const K &key,size_t sidx=0)
00225 {
00226 for(size_t i=sidx; i<nelem; i++)
00227 if(OP.eq(array(i),key)) return(i);
00228 return(-1);
00229 }
00230
00240 template<typename K>inline ssize_t BinSearch(const K &key)
00241 { return(TLBinarySearch(_array,nelem,key,OP)); }
00242 };
00243
00244 #endif