Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/tl/tlsortedarray.h

Go to the documentation of this file.
00001 /*
00002  * lib/tl/tlsortedarray.h 
00003  * 
00004  * Implementation of a sorted array template. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #ifndef _TemplateLibrary_SortedArray_H_
00018 #define _TemplateLibrary_SortedArray_H_ 1
00019 
00027 #include <lib/sconfig.h>    /* MUST be first */
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         // Access to operator template: 
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;  // 1 element is always sorted :)
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             // Remove entries a..b. 
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  /* _TemplateLibrary_SortedArray_H_ */

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5