00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _TemplateLibrary_SortedArray_H_
00018 #define _TemplateLibrary_SortedArray_H_ 1
00019
00027 #include <lib/sconfig.h>
00028
00029 #include <lib/tl/tlarray.h>
00030
00032
00033
00059 template<typename T,typename _OP=TLDefaultOperators_CDT<T> >
00060 class TLSortedArray : private TLArray<T,_OP>
00061 {
00062 public:
00063
00064 using TLArray<T,_OP>::OP;
00065
00066 private:
00067 using TLArray<T,_OP>::nelem;
00068 using TLArray<T,_OP>::asize;
00069 using TLArray<T,_OP>::array;
00070 using TLArray<T,_OP>::arrayP;
00071 using TLArray<T,_OP>::_upsize1;
00072
00074 TLSortedArray(const TLSortedArray &);
00075 void operator=(const TLSortedArray &);
00076 public:
00078 TLSortedArray(const _OP &op=_OP()) : TLArray<T,_OP>(op) {}
00080 ~TLSortedArray() {}
00081
00083 using TLArray<T,_OP>::IsEmpty;
00085 using TLArray<T,_OP>::NElem;
00086
00088 using TLArray<T,_OP>::operator[];
00089
00091 using TLArray<T,_OP>::clear();
00092
00095 inline T *last() { return(nelem ? arrayP(nelem-1) : NULL); }
00096 inline const T *last() const { return(nelem ? arrayP(nelem-1) : NULL); }
00097
00112 template<typename K>ssize_t GetInsertIdx(const K &ent,int allow_dup)
00113 {
00114 if(!nelem || OP.gt(array(0),ent)) return(0);
00115 if(OP.lt(array(nelem-1),ent)) return(nelem);
00116 size_t a=0,b=nelem-1;
00117 if(!allow_dup) {
00118 while(b>a)
00119 { size_t m=(a+b)/2; OP.lt(array(m),ent) ? a=m : b=m; }
00120 return(OP.eq(array(a),ent) ? -1 : a); }
00121 if(allow_dup<0) while(b>a)
00122 { size_t m=(a+b)/2; OP.lt(array(m),ent) ? a=m : b=m; }
00123 else while(b>a)
00124 { size_t m=(a+b)/2; OP.gt(array(m),ent) ? b=m : a=m; }
00125 return(a);
00126 }
00127
00147 int insert(const T &ent,int allow_dup,ssize_t *ret_idx=NULL)
00148 {
00149 ssize_t idx=GetInsertIdx(ent,allow_dup);
00150 if(idx<0) return(1);
00151 TLArray<T,_OP>::insert(ent,idx);
00152 if(ret_idx) *ret_idx=idx; return(0);
00153 }
00154
00171 ssize_t ReOrder(size_t idx,int allow_dup)
00172 {
00173 if(idx>=nelem) return(-2);
00174 ssize_t newidx=GetInsertIdx(array(idx),allow_dup);
00175 if(newidx<0) { Remove(idx); return(-3); }
00176 if((size_t)newidx==idx) return(idx);
00177 T tmp(array(idx));
00178 if((size_t)newidx>idx)
00179 for(ssize_t i=idx; i<newidx; i++) OP.ass(array(i),array(i+1));
00180 else for(ssize_t i=idx; i>newidx; i--) OP.ass(array(i),array(i-1));
00181 OP.ass(array(newidx),tmp); return(newidx);
00182 }
00183
00197 void ReOrder()
00198 {
00199 if(nelem<1) return;
00200 T tmp;
00201 for(size_t i=1; i<nelem; i++)
00202 {
00203 size_t j1=i-1;
00204 if(OP.le(array(j1),array(i))) continue;
00205 OP.ass(tmp,array(i));
00206 size_t j=i;
00210 do
00211 { OP.ass(array(j),array(j1)); if(!j) break; j=j1--; }
00212 while(OP.lt(tmp,array(j1)));
00213 OP.ass(array(j),tmp);
00214 }
00215 }
00216
00224 template<typename K>ssize_t search(const K &key)
00225 { return(TLBinarySearch(_array,nelem,key,OP)); }
00226
00228 using TLArray<T,_OP>::remove;
00229
00240 template<typename K>ssize_t remove(const K &key)
00241 {
00242 if(!nelem || OP.gt(array(0),key) ||
00243 OP.lt(array(nelem-1),key)) return(0);
00244 size_t a=0,b=nelem-1;
00245 while(b>a)
00246 { size_t m=(a+b)/2; OP.lt(array(m),key) ? a=m : b=m; }
00247 if(a+1<nelem && OP.eq(array(a+1),key)) {
00248 size_t a1=a; b=nelem-1;
00249 while(b>a1)
00250 { size_t m=(a1+b)/2; OP.gt(array(m),key) ? b=m : a1=m; }
00251 }
00252
00253 size_t delta=b-a+1;
00254 nelem-=delta;
00255 for(size_t i=a; i<nelem; i++) OP.ass(array(i),array(i+delta));
00256 if(!OP.pdt) for(size_t i=nelem+delta; i-->nelem;) OP.clr(arrayP(i));
00257 _downsize(); return(delta);
00258 }
00259
00264 size_t CheckOrder()
00265 {
00266 size_t nerr=0;
00267 for(size_t i=1; i<nelem; i++)
00268 { if(OP.gt(array(i),array(i+1))) ++nerr; }
00269 return(nerr);
00270 }
00271 };
00272
00273 #endif