00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef GLUE_LIST_H
00024 #define GLUE_LIST_H
00025
00026 #include <stdlib.h>
00027 #include "std/dllimpexp.H"
00028 #include "std/config.H"
00029 #include "std/error.H"
00030
00031 extern "C" {
00032 typedef int (* compare_func_t) (const void *, const void *);
00033 }
00034
00035 static const int BAD_IND = -999;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #define cARRAY const ARRAY
00046 template <class T>
00047 class ARRAY {
00048 protected:
00049 T *_array;
00050 int _num;
00051 int _max;
00052 int _unique;
00053
00054
00055 virtual void clear_ele (int) {}
00056 virtual void clear_range(int, int) {}
00057 void append_ele(const T& el) {
00058
00059 if (_num == _max) realloc();
00060 _array[_num++] = el;
00061 }
00062
00063 public:
00064
00065 ARRAY(int m=0) : _array(0), _num(0), _max(m > 0 ? m : 0), _unique(0) {
00066 if (_max) _array = new T[_max];
00067 }
00068 ARRAY(cARRAY<T>& l) : _array(0), _num(0), _max(0), _unique(0) { *this = l; }
00069 ARRAY(const T &e) : _array(0), _num(0), _max(0), _unique(0) { ARRAY<T> l;
00070 l += e;
00071 *this = l; }
00072 virtual ~ARRAY() { clear(); delete [] _array;}
00073
00074
00075 int num() const { return _num; }
00076 bool empty() const { return (_num<=0); }
00077 bool valid_index(int k) const { return (k>=0 && k<_num); }
00078 void set_unique() { _unique = 1; }
00079
00080 const T* array() const { return _array; }
00081 T* array() { return _array; }
00082 T& operator [](int j) { return _array[j]; }
00083 T& last() { if (empty())
00084 err_msg("ARRAY::last-list empty");
00085 return _array[_num-1]; }
00086 const T& operator [](int j) const { return _array[j]; }
00087 const T& last() const { if (empty())
00088 err_msg("ARRAY::last-list empty");
00089 return _array[_num-1]; }
00090
00091
00092
00093 void clear() { clear_range(0,_num); _num=0; }
00094 virtual void truncate(int n) {
00095 if (valid_index(n)) {
00096 clear_range(n,_num);
00097 _num = n;
00098 } else err_msg("ARRAY::truncate: bad index %d", n);
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 virtual void realloc(int new_max=0) {
00115 if (new_max && new_max <= _max)
00116 return;
00117 _max = (new_max == 0) ? (_max ? _max*2 : 1) : new_max;
00118 T *tmp = new T [_max];
00119 if (tmp == 0)
00120 err_sys("ARRAY: realloc failed");
00121 for (int i=0; i<_num; i++) {
00122 tmp[i] = _array[i];
00123 clear_ele(i);
00124 }
00125 delete [] _array;
00126 _array = tmp;
00127 }
00128
00129
00130 int get_index(const T &el) const {
00131
00132
00133 for (int k = _num-1; k >= 0; k--)
00134 if (_array[k] == el)
00135 return k;
00136 return BAD_IND;
00137 }
00138 bool contains(const T &el) const { return get_index(el) != BAD_IND; }
00139
00140
00141 void operator += (const T& el) {
00142 if (_unique)
00143 add_uniquely(el);
00144 else
00145 append_ele(el);
00146 }
00147
00148
00149 void add (const T& p) { *this += p; }
00150
00151
00152 void push(const T& p) {
00153 insert(0,1);
00154 _array[0] = p;
00155 }
00156
00157 bool add_uniquely(const T& el) {
00158
00159 int ret=0;
00160 if (get_index(el) == BAD_IND) {
00161 append_ele(el);
00162 ret = 1;
00163 }
00164 return ret;
00165 }
00166
00167
00168 void insert(int ind, int num) {
00169
00170
00171
00172
00173
00174
00175 if (_num+num >= _max)
00176 realloc(_max+num);
00177 _num += num;
00178 for (int i = _num-1; i>=ind+num; i--)
00179 _array[i] = _array[i-num];
00180 }
00181
00182
00183 bool remove(int k) {
00184
00185
00186 if (valid_index(k)) {
00187
00188 _array[k] = _array[--_num];
00189 clear_ele(_num);
00190 return 1;
00191 } else if (k != BAD_IND) {
00192 err_msg("ARRAY::remove: invalid index %d", k);
00193 return 0;
00194 } else return 0;
00195 }
00196
00197
00198
00199 void operator -= (cARRAY<T> &l) { for (int i=0; i < l.num(); i++)
00200 *this -= l[i]; }
00201
00202 bool operator -= (const T &el) { return remove(get_index(el)); }
00203 bool rem(const T &p) { return (*this -= p); }
00204
00205 T pop() {
00206
00207 T tmp = last();
00208 remove(_num-1);
00209 return tmp;
00210 }
00211
00212
00213 ARRAY<T>& operator =(cARRAY<T>& l) {
00214
00215 if (&l == this)
00216 return *this;
00217 clear();
00218 if(!l.empty()) {
00219 realloc(l._num);
00220 for (int i=0; i<l._num; i++)
00221 *this += l[i];
00222 }
00223 return *this;
00224 }
00225 ARRAY<T>& operator +=(cARRAY<T>& l) {
00226
00227 if(!l.empty()) {
00228 realloc(_num + l._num);
00229 for (int i=0; i<l._num; i++)
00230 *this += l[i];
00231 }
00232 return *this;
00233 }
00234 bool operator ==(const ARRAY<T> &c) const {
00235 if (num() != c.num())
00236 return 0;
00237 for (int i = 0; i < num(); i++) {
00238
00239 if (!((*this)[i] == c[i]))
00240 return 0;
00241 }
00242 return 1;
00243 }
00244
00245
00246 void reverse() {
00247 for (int i=0, j=_num-1; i<j; ++i, --j) {
00248
00249 T tmp = _array[i];
00250 _array[i] = _array[j];
00251 _array[j] = tmp;
00252 }
00253 }
00254 virtual void sort(compare_func_t compare) {
00255 qsort(_array, _num, sizeof(T), compare);
00256 }
00257 };
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 #define cLIST const LIST
00271 template <class T>
00272 class LIST : public ARRAY<T> {
00273 protected:
00274 virtual void clear_ele (int i) { _array[i].Clear(); }
00275 virtual void clear_range(int i, int j) { for (int k=i; k < j; k++)
00276 clear_ele(k); }
00277 public:
00278 LIST(int m=0) : ARRAY<T>(m) {}
00279 LIST(cLIST<T>& l) : ARRAY<T>(l) {}
00280 };
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 template <class OBS>
00297 class OBSlist
00298 {
00299 protected:
00300 ARRAY<OBS *> _list;
00301 public:
00302 virtual ~OBSlist() {}
00303 OBSlist() : _list(0) {}
00304 int num() const { return _list.num(); }
00305 void obs(OBS *o) { _list.add_uniquely(o); }
00306 void obs_first(OBS *o) { if (_list.empty()) _list.add(o);
00307 else {
00308 _list.insert(0, 1);
00309 _list[0] = o;
00310 } }
00311 void unobs(OBS *o) { _list.rem(o); }
00312
00313 void notify(const GLUE_TYPENAME OBS::data &d) {
00314 for (int i=0; i < _list.num(); i++)
00315 _list[i]->notify(d); }
00316
00317 };
00318
00319
00320 template<class T>
00321 ostream &
00322 operator<< (ostream &os, const ARRAY<T> &array)
00323 {
00324 for (int i = 0; i < array.num(); i++) {
00325 os << array[i];
00326 if (array.num() > 1) os << endl;
00327 }
00328 return os;
00329 }
00330
00331 template<class T>
00332 istream &
00333 operator>> (istream &is, ARRAY<T> &array)
00334 {
00335 array.clear();
00336 WHITESPACE(is);
00337 while (!is.eof() && is.peek() != '\0' && is.peek() != '}') {
00338 T x; is >> x; array += x;
00339 WHITESPACE(is);
00340 }
00341 return is;
00342 }
00343
00344 #endif // list.H
00345
00346