00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __WVSORTER_H
00010 #define __WVSORTER_H
00011
00012 #include "wvlink.h"
00013
00014 extern WvLink blank_wvlink;
00015
00016
00017
00018
00019
00020
00021
00022
00023 class WvSorterBase
00024 {
00025 public:
00026 typedef int (CompareFunc)(const void *a, const void *b);
00027
00028 void *list;
00029 WvLink **array;
00030 WvLink **lptr;
00031
00032 WvSorterBase(void *_list)
00033 { list = _list; array = lptr = NULL; }
00034 ~WvSorterBase()
00035 { if (array) delete array; }
00036 WvLink *next()
00037 { return lptr ? *(++lptr) : *(lptr = array); }
00038 WvLink *cur()
00039 { return lptr ? *lptr : &blank_wvlink; }
00040
00041 protected:
00042 template <class _list_,class _iter_> void rewind(CompareFunc *cmp);
00043
00044 static int magic_compare(const void *_a, const void *_b);
00045 static CompareFunc *actual_compare;
00046 };
00047
00048
00049
00050
00051
00052
00053
00054
00055 template <class _type_,class _list_,class _iter_>
00056 class WvSorter : public WvSorterBase
00057 {
00058 public:
00059 typedef int (RealCompareFunc)(const _type_ *a, const _type_ *b);
00060 RealCompareFunc *cmp;
00061
00062 WvSorter(_list_ &_list, RealCompareFunc *_cmp)
00063 : WvSorterBase(&_list)
00064 { cmp = _cmp; }
00065 _type_ *ptr() const
00066 { return (_type_ *)(*lptr)->data; }
00067
00068
00069 WvIterStuff(_type_);
00070
00071
00072
00073
00074 void rewind()
00075 { WvSorterBase::rewind<_list_,_iter_>((CompareFunc *)cmp); }
00076 };
00077
00078
00079
00080
00081 template <class _list_,class _iter_>
00082 void WvSorterBase::rewind(CompareFunc *cmp)
00083 {
00084 if (array)
00085 delete array;
00086 array = lptr = NULL;
00087
00088 int n = ((_list_ *)list)->count();
00089 array = new WvLink * [n+1];
00090 WvLink **aptr = array;
00091
00092
00093
00094
00095 _iter_ i(*(_list_ *)list);
00096 aptr = array;
00097 for (i.rewind(); i.next(); )
00098 {
00099 *aptr = i.cur();
00100 aptr++;
00101 }
00102
00103 *aptr = NULL;
00104
00105
00106
00107 CompareFunc *old_compare = actual_compare;
00108 actual_compare = cmp;
00109 qsort(array, n, sizeof(WvLink *), magic_compare);
00110 actual_compare = old_compare;
00111
00112 lptr = NULL;
00113 }
00114
00115
00116 #endif // __WVSORTER_H