00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef _ARRAYS_H_
00058 #define _ARRAYS_H_
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065
00066 #include "GException.h"
00067 #include "GSmartPointer.h"
00068 #include <string.h>
00069
00070 #ifdef HAVE_NAMESPACES
00071 namespace DJVU {
00072 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00073 }
00074 #endif
00075 #endif
00076
00077
00078
00128
00129
00130 class _ArrayRep
00131 {
00132 friend class _ArrayBase;
00133 public:
00134 _ArrayRep(void) : count(0) {}
00135 _ArrayRep(const _ArrayRep &) {}
00136 virtual ~_ArrayRep(void) {}
00137
00138 _ArrayRep & operator=(const _ArrayRep &) { return *this; }
00139
00140 int get_count(void) const { return count; }
00141 private:
00142 int count;
00143
00144 void ref(void) { count++; }
00145 void unref(void) { if (--count==0) delete this; }
00146 };
00147
00148 class _ArrayBase
00149 {
00150 public:
00151 _ArrayBase(void) : rep(0) {}
00152 _ArrayBase(const _ArrayBase & ab) : rep(0)
00153 {
00154 if (ab.rep) ab.rep->ref();
00155 rep=ab.rep;
00156 }
00157 _ArrayBase(_ArrayRep * ar) : rep(0)
00158 {
00159 if (ar) ar->ref();
00160 rep=ar;
00161 }
00162 virtual ~_ArrayBase(void)
00163 {
00164 if (rep) { rep->unref(); rep=0; }
00165 }
00166
00167 _ArrayRep * get(void) const { return rep; }
00168 _ArrayBase & assign(_ArrayRep * ar)
00169 {
00170 if (ar) ar->ref();
00171 if (rep) rep->unref();
00172 rep=ar;
00173 return *this;
00174 }
00175 _ArrayBase & operator=(const _ArrayBase & ab) { return assign(ab.rep); }
00176 bool operator==(const _ArrayBase & ab) { return rep==ab.rep; }
00177 private:
00178 _ArrayRep * rep;
00179 };
00180
00181
00182
00183
00184
00185 class ArrayRep : public _ArrayRep
00186 {
00187 public:
00188 ArrayRep(int elsize,
00189 void (* xdestroy)(void *, int, int),
00190 void (* xinit1)(void *, int, int),
00191 void (* xinit2)(void *, int, int, const void *, int, int),
00192 void (* xcopy)(void *, int, int, const void *, int, int),
00193 void (* xinsert)(void *, int, int, const void *, int));
00194 ArrayRep(int elsize,
00195 void (* xdestroy)(void *, int, int),
00196 void (* xinit1)(void *, int, int),
00197 void (* xinit2)(void *, int, int, const void *, int, int),
00198 void (* xcopy)(void *, int, int, const void *, int, int),
00199 void (* xinsert)(void *, int, int, const void *, int),
00200 int hibound);
00201 ArrayRep(int elsize,
00202 void (* xdestroy)(void *, int, int),
00203 void (* xinit1)(void *, int, int),
00204 void (* xinit2)(void *, int, int, const void *, int, int),
00205 void (* xcopy)(void *, int, int, const void *, int, int),
00206 void (* xinsert)(void *, int, int, const void *, int),
00207 int lobound, int hibound);
00208 ArrayRep(const ArrayRep & rep);
00209
00210 virtual ~ArrayRep();
00211
00212
00213
00214 int size() const;
00215 int lbound() const;
00216 int hbound() const;
00217
00218 void empty();
00219 void touch(int n);
00220 void resize(int lobound, int hibound);
00221 void shift(int disp);
00222 void del(int n, unsigned int howmany=1);
00223
00224
00225
00226 void ins(int n, const void * what, unsigned int howmany);
00227
00228 ArrayRep & operator=(const ArrayRep & rep);
00229
00230
00231 void *data;
00232 int minlo;
00233 int maxhi;
00234 int lobound;
00235 int hibound;
00236 int elsize;
00237 private:
00238
00239
00240
00241 void (* destroy)(void * data, int lo, int hi);
00242
00243
00244 void (* init1)(void * data, int lo, int hi);
00245
00246
00247 void (* init2)(void * data, int lo, int hi,
00248 const void * src, int src_lo, int src_hi);
00249
00250 void (* copy)(void * dst, int dst_lo, int dst_hi,
00251 const void * src, int src_lo, int src_hi);
00252
00253
00254 void (* insert)(void * data, int els, int where, const void * what,
00255 int howmany);
00256 };
00257
00258 inline int
00259 ArrayRep::size() const
00260 {
00261 return hibound - lobound + 1;
00262 }
00263
00264 inline int
00265 ArrayRep::lbound() const
00266 {
00267 return lobound;
00268 }
00269
00270 inline int
00271 ArrayRep::hbound() const
00272 {
00273 return hibound;
00274 }
00275
00276 inline void
00277 ArrayRep::empty()
00278 {
00279 resize(0, -1);
00280 }
00281
00282 inline void
00283 ArrayRep::touch(int n)
00284 {
00285 if (hibound < lobound)
00286 {
00287 resize(n,n);
00288 } else
00289 {
00290 int nlo = lobound;
00291 int nhi = hibound;
00292 if (n < nlo) nlo = n;
00293 if (n > nhi) nhi = n;
00294 resize(nlo, nhi);
00295 }
00296 }
00297
00305 class ArrayBase : protected _ArrayBase
00306 {
00307 protected:
00308 void check(void);
00309 void detach(void);
00310
00311 ArrayBase(void) {};
00312 public:
00314 int size() const;
00316 int lbound() const;
00318 int hbound() const;
00321 void empty();
00337 void touch(int n);
00343 void resize(int hibound);
00350 void resize(int lobound, int hibound);
00354 void shift(int disp);
00362 void del(int n, unsigned int howmany=1);
00363
00364 virtual ~ArrayBase(void) {};
00365 };
00366
00367 inline void
00368 ArrayBase::detach(void)
00369 {
00370 ArrayRep * new_rep=new ArrayRep(*(ArrayRep *) get());
00371 assign(new_rep);
00372 }
00373
00374 inline void
00375 ArrayBase::check(void)
00376 {
00377 if (get()->get_count()>1) detach();
00378 }
00379
00380 inline int
00381 ArrayBase::size() const
00382 {
00383 return ((const ArrayRep *) get())->size();
00384 }
00385
00386 inline int
00387 ArrayBase::lbound() const
00388 {
00389 return ((const ArrayRep *) get())->lobound;
00390 }
00391
00392 inline int
00393 ArrayBase::hbound() const
00394 {
00395 return ((const ArrayRep *) get())->hibound;
00396 }
00397
00398 inline void
00399 ArrayBase::empty()
00400 {
00401 check();
00402 ((ArrayRep *) get())->empty();
00403 }
00404
00405 inline void
00406 ArrayBase::resize(int lo, int hi)
00407 {
00408 check();
00409 ((ArrayRep *) get())->resize(lo, hi);
00410 }
00411
00412 inline void
00413 ArrayBase::resize(int hi)
00414 {
00415 resize(0, hi);
00416 }
00417
00418 inline void
00419 ArrayBase::touch(int n)
00420 {
00421 check();
00422 ((ArrayRep *) get())->touch(n);
00423 }
00424
00425 inline void
00426 ArrayBase::shift(int disp)
00427 {
00428 check();
00429 ((ArrayRep *) get())->shift(disp);
00430 }
00431
00432 inline void
00433 ArrayBase::del(int n, unsigned int howmany)
00434 {
00435 check();
00436
00437 ((ArrayRep *) get())->del(n, howmany);
00438 }
00439
00448 template <class TYPE>
00449 class ArrayBaseT : public ArrayBase
00450 {
00451 public:
00452 virtual ~ArrayBaseT(void) {};
00453
00459 TYPE& operator[](int n);
00466 const TYPE& operator[](int n) const;
00467
00474 operator TYPE* ();
00481 operator const TYPE* () const;
00482
00483 #ifndef __MWERKS__ //MCW can't compile
00484 operator const TYPE* ();
00485 #endif
00486
00494 void ins(int n, const TYPE &val, unsigned int howmany=1);
00495
00499 void sort();
00508 void sort(int lo, int hi);
00509 protected:
00510 ArrayBaseT(void) {};
00511 private:
00512
00513 static void destroy(void * data, int lo, int hi);
00514 static void init1(void * data, int lo, int hi);
00515 static void init2(void * data, int lo, int hi,
00516 const void * src, int src_lo, int src_hi);
00517 static void copy(void * dst, int dst_lo, int dst_hi,
00518 const void * src, int src_lo, int src_hi);
00519 static void insert(void * data, int els, int where,
00520 const void * what, int howmany);
00521 };
00522
00523 template <class TYPE> inline
00524 ArrayBaseT<TYPE>::operator TYPE* ()
00525 {
00526 check();
00527
00528 ArrayRep * rep=(ArrayRep *) get();
00529 return &((TYPE *) rep->data)[-rep->minlo];
00530 }
00531
00532 #ifndef __MWERKS__ //MCW can't compile
00533 template <class TYPE> inline
00534 ArrayBaseT<TYPE>::operator const TYPE* ()
00535 {
00536 const ArrayRep * rep=(const ArrayRep *) get();
00537 return &((const TYPE *) rep->data)[-rep->minlo];
00538 }
00539 #endif
00540
00541 template <class TYPE> inline
00542 ArrayBaseT<TYPE>::operator const TYPE* () const
00543 {
00544 const ArrayRep * rep=(const ArrayRep *) get();
00545 return &((const TYPE *) rep->data)[-rep->minlo];
00546 }
00547
00548 template <class TYPE> inline TYPE&
00549 ArrayBaseT<TYPE>::operator[](int n)
00550 {
00551 check();
00552
00553 ArrayRep * rep=(ArrayRep *) get();
00554 if (n<rep->lobound || n>rep->hibound)
00555 G_THROW( ERR_MSG("arrays.ill_sub") );
00556 return ((TYPE *) rep->data)[n - rep->minlo];
00557 }
00558
00559 template <class TYPE> inline const TYPE&
00560 ArrayBaseT<TYPE>::operator[](int n) const
00561 {
00562 const ArrayRep * rep=(const ArrayRep *) get();
00563 if (n<rep->lobound || n>rep->hibound)
00564 G_THROW( ERR_MSG("arrays.ill_sub") );
00565 return ((const TYPE *) rep->data)[n - rep->minlo];
00566 }
00567
00568 template <class TYPE> inline void
00569 ArrayBaseT<TYPE>::ins(int n, const TYPE &val, unsigned int howmany)
00570 {
00571 check();
00572
00573 ((ArrayRep *) get())->ins(n, &val, howmany);
00574 }
00575
00576 template <class TYPE> void
00577 ArrayBaseT<TYPE>::sort()
00578 {
00579 sort(lbound(), hbound());
00580 }
00581
00582 template <class TYPE> void
00583 ArrayBaseT<TYPE>::sort(int lo, int hi)
00584 {
00585 if (hi <= lo)
00586 return;
00587
00588 if (hi <= lo + 20)
00589 {
00590 for (int i=lo+1; i<=hi; i++)
00591 {
00592 int j = i;
00593 TYPE tmp = (*this)[i];
00594 while ((--j>=lo) && !((*this)[j]<=tmp))
00595 (*this)[j+1] = (*this)[j];
00596 (*this)[j+1] = tmp;
00597 }
00598 return;
00599 }
00600
00601 TYPE tmp = (*this)[lo];
00602 TYPE pivot = (*this)[(lo+hi)/2];
00603 if (pivot <= tmp)
00604 { tmp = pivot; pivot=(*this)[lo]; }
00605 if ((*this)[hi] <= tmp)
00606 { pivot = tmp; }
00607 else if ((*this)[hi] <= pivot)
00608 { pivot = (*this)[hi]; }
00609
00610 int h = hi;
00611 int l = lo;
00612 while (l < h)
00613 {
00614 while (! (pivot <= (*this)[l])) l++;
00615 while (! ((*this)[h] <= pivot)) h--;
00616 if (l < h)
00617 {
00618 tmp = (*this)[l];
00619 (*this)[l] = (*this)[h];
00620 (*this)[h] = tmp;
00621 l = l+1;
00622 h = h-1;
00623 }
00624 }
00625
00626 sort(lo, h);
00627 sort(l, hi);
00628 }
00629
00643 template <class TYPE>
00644 class TArray : public ArrayBaseT<TYPE> {
00645 public:
00649 TArray();
00654 TArray(int hibound);
00660 TArray(int lobound, int hibound);
00661
00662 virtual ~TArray() {};
00663 private:
00664
00665 static void destroy(void * data, int lo, int hi);
00666 static void init1(void * data, int lo, int hi);
00667 static void init2(void * data, int lo, int hi,
00668 const void * src, int src_lo, int src_hi);
00669 static void insert(void * data, int els, int where,
00670 const void * what, int howmany);
00671 };
00672
00673 template <class TYPE> void
00674 TArray<TYPE>::destroy(void * data, int lo, int hi)
00675 {
00676 }
00677
00678 template <class TYPE> void
00679 TArray<TYPE>::init1(void * data, int lo, int hi)
00680 {
00681 }
00682
00683 template <class TYPE> void
00684 TArray<TYPE>::init2(void * data, int lo, int hi,
00685 const void * src, int src_lo, int src_hi)
00686 {
00687 if (data && src)
00688 {
00689 int els=hi-lo+1;
00690 if (els>src_hi-src_lo+1) els=src_hi-src_lo+1;
00691 if (els>0)
00692 memmove((void *) &((TYPE *) data)[lo],
00693 (void *) &((TYPE *) src)[src_lo], els*sizeof(TYPE));
00694 };
00695 }
00696
00697
00698 template <class TYPE> void
00699 TArray<TYPE>::insert(void * data, int els, int where,
00700 const void * what, int howmany)
00701 {
00702 memmove(((TYPE *) data)+where+howmany,
00703 ((TYPE *) data)+where, sizeof(TYPE)*(els-where));
00704 for(int i=0;i<howmany;i++)
00705 ((TYPE *) data)[where+i]=*(TYPE *) what;
00706 }
00707
00708 template <class TYPE>
00709 TArray<TYPE>::TArray ()
00710 {
00711 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00712 init2, init2, insert));
00713 }
00714
00715 template <class TYPE>
00716 TArray<TYPE>::TArray(int hi)
00717 {
00718 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00719 init2, init2, insert, hi));
00720 }
00721
00722 template <class TYPE>
00723 TArray<TYPE>::TArray(int lo, int hi)
00724 {
00725 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00726 init2, init2, insert, lo, hi));
00727 }
00728
00729
00730
00757 template <class TYPE>
00758 class DArray : public ArrayBaseT<TYPE> {
00759 public:
00763 DArray(void);
00768 DArray(const int hibound);
00774 DArray(const int lobound, const int hibound);
00775
00776 virtual ~DArray() {};
00777 private:
00778
00779 static void destroy(void * data, int lo, int hi);
00780 static void init1(void * data, int lo, int hi);
00781 static void init2(void * data, int lo, int hi,
00782 const void * src, int src_lo, int src_hi);
00783 static void copy(void * dst, int dst_lo, int dst_hi,
00784 const void * src, int src_lo, int src_hi);
00785 static void insert(void * data, int els, int where,
00786 const void * what, int howmany);
00787 };
00788
00789 template <class TYPE> void
00790 DArray<TYPE>::destroy(void * data, int lo, int hi)
00791 {
00792 if (data)
00793 for(int i=lo;i<=hi;i++)
00794 ((TYPE *) data)[i].TYPE::~TYPE();
00795 }
00796
00797 template <class TYPE> void
00798 DArray<TYPE>::init1(void * data, int lo, int hi)
00799 {
00800 if (data)
00801 for(int i=lo;i<=hi;i++)
00802 new ((void *) &((TYPE *) data)[i]) TYPE;
00803 }
00804
00805 template <class TYPE> void
00806 DArray<TYPE>::init2(void * data, int lo, int hi,
00807 const void * src, int src_lo, int src_hi)
00808 {
00809 if (data && src)
00810 {
00811 int i, j;
00812 for(i=lo, j=src_lo;i<=hi && j<=src_hi;i++, j++)
00813 new ((void *) &((TYPE *) data)[i]) TYPE(((TYPE *) src)[j]);
00814 };
00815 }
00816
00817 template <class TYPE> void
00818 DArray<TYPE>::copy(void * dst, int dst_lo, int dst_hi,
00819 const void * src, int src_lo, int src_hi)
00820 {
00821 if (dst && src)
00822 {
00823 int i, j;
00824 for(i=dst_lo, j=src_lo;i<=dst_hi && j<=src_hi;i++, j++)
00825 ((TYPE *) dst)[i]=((TYPE *) src)[j];
00826 };
00827 }
00828
00829 template <class TYPE> inline void
00830 DArray<TYPE>::insert(void * data, int els, int where,
00831 const void * what, int howmany)
00832 {
00833
00834 TYPE * d=(TYPE *) data;
00835
00836 int i;
00837 for (i=els+howmany-1; i>=els; i--)
00838 {
00839 if (i-where >= (int)howmany)
00840 new ((void*) &d[i]) TYPE (d[i-howmany]);
00841 else
00842 new ((void*) &d[i]) TYPE (*(TYPE *) what);
00843 }
00844
00845 for (i=els-1; i>=where; i--)
00846 {
00847 if (i-where >= (int)howmany)
00848 d[i] = d[i-howmany];
00849 else
00850 d[i] = *(TYPE *) what;
00851 }
00852 }
00853
00854 template <class TYPE> inline
00855 DArray<TYPE>::DArray ()
00856 {
00857 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00858 init2, copy, insert));
00859 }
00860
00861 template <class TYPE> inline
00862 DArray<TYPE>::DArray(const int hi)
00863 {
00864 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00865 init2, copy, insert, hi));
00866 }
00867
00868 template <class TYPE> inline
00869 DArray<TYPE>::DArray(const int lo, const int hi)
00870 {
00871 this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
00872 init2, copy, insert, lo, hi));
00873 }
00874
00892 template <class TYPE>
00893 class DPArray : public DArray<GPBase> {
00894 public:
00895
00896 DPArray();
00897 DPArray(int hibound);
00898 DPArray(int lobound, int hibound);
00899 DPArray(const DPArray<TYPE> &gc);
00900
00901 virtual ~DPArray();
00902
00903 GP<TYPE>& operator[](int n);
00904 const GP<TYPE>& operator[](int n) const;
00905
00906 operator GP<TYPE>* ();
00907
00908 #ifndef __MWERKS__ //MCW can't compile
00909 operator const GP<TYPE>* ();
00910 #endif
00911
00912 operator const GP<TYPE>* () const;
00913
00914 void ins(int n, const GP<TYPE> &val, unsigned int howmany=1);
00915 DPArray<TYPE>& operator= (const DPArray &ga);
00916 };
00917
00918 template<class TYPE>
00919 DPArray<TYPE>::DPArray() {}
00920
00921 template<class TYPE>
00922 DPArray<TYPE>::DPArray(int hibound) :
00923 DArray<GPBase>(hibound) {}
00924
00925 template<class TYPE>
00926 DPArray<TYPE>::DPArray(int lobound, int hibound) :
00927 DArray<GPBase>(lobound, hibound) {}
00928
00929 template<class TYPE>
00930 DPArray<TYPE>::DPArray(const DPArray<TYPE> &gc) :
00931 DArray<GPBase>(gc) {}
00932
00933 template<class TYPE>
00934 DPArray<TYPE>::~DPArray() {}
00935
00936 template<class TYPE>
00937 inline GP<TYPE> &
00938 DPArray<TYPE>::operator[](int n)
00939 {
00940 return (GP<TYPE> &) DArray<GPBase>::operator[](n);
00941 }
00942
00943 template<class TYPE>
00944 inline const GP<TYPE> &
00945 DPArray<TYPE>::operator[](int n) const
00946 {
00947 return (const GP<TYPE> &) DArray<GPBase>::operator[](n);
00948 }
00949
00950 template<class TYPE>
00951 inline DPArray<TYPE>::operator GP<TYPE>* ()
00952 {
00953 return (GP<TYPE> *) DArray<GPBase>::operator GPBase*();
00954 }
00955
00956 #ifndef __MWERKS__ //MCW can't compile
00957 template<class TYPE>
00958 inline DPArray<TYPE>::operator const GP<TYPE>* ()
00959 {
00960 return (const GP<TYPE> *) DArray<GPBase>::operator const GPBase*();
00961 }
00962 #endif
00963
00964 template<class TYPE>
00965 inline DPArray<TYPE>::operator const GP<TYPE>* () const
00966 {
00967 return (const GP<TYPE> *) DArray<GPBase>::operator const GPBase*();
00968 }
00969
00970 template<class TYPE>
00971 inline void
00972 DPArray<TYPE>::ins(int n, const GP<TYPE> & val, unsigned int howmany)
00973 {
00974 DArray<GPBase>::ins(n, val, howmany);
00975 }
00976
00977 template<class TYPE>
00978 inline DPArray<TYPE> &
00979 DPArray<TYPE>::operator= (const DPArray &ga)
00980 {
00981 DArray<GPBase>::operator=(ga);
00982 return *this;
00983 }
00984
00985
00986
00988
00989
00990 #ifdef HAVE_NAMESPACES
00991 }
00992 # ifndef NOT_USING_DJVU_NAMESPACE
00993 using namespace DJVU;
00994 # endif
00995 #endif
00996 #endif
00997