00001 #ifndef SUPPORT_H
00002 #define SUPPORT_H
00003
00004 #include "platform.H"
00005 #include "error.H"
00006 #include "ref.H"
00007 #include "hash.H"
00008
00009
00010 #include "std/iostream.H"
00011
00012 #define REF_CLASS(FOO) FOO; typedef REFptr<FOO> FOO##ptr; class FOO
00013 #define FD_REF_CLASS(FOO) FOO; typedef REFptr<FOO> FOO##ptr
00014 #define CSTR const STR
00015 #define brcase break; case
00016 #define brdefault break; default
00017
00018
00019 #define PRINT_VAR(v) cerr << # v << " = '" << v << "'" << endl
00020
00021
00022 class STR : public REFcounter {
00023 protected:
00024 char *_s;
00025 static HASH *strpool;
00026 public:
00027 static STR *null;
00028
00029 STR() { _s = 0; }
00030 STR(const char *s) { if (!strpool) strpool = new HASH(1024);
00031 if (!s) s = "";
00032 strpool->add(s, _s); }
00033 STR(char s) { char str[2]; str[0]=s; str[1] = '\0';
00034 if (!strpool) strpool = new HASH(1024);
00035 strpool->add(str, _s); }
00036 STR(const STR &s) { _s = s._s; }
00037 STR(int x) { char buff[1024];sprintf(buff,"%d", x);
00038 if (!strpool) strpool = new HASH(1024);
00039 strpool->add(buff, _s); }
00040 STR(double d) { char buff[1024];sprintf(buff,"%g", d);
00041 if (!strpool) strpool = new HASH(1024);
00042 strpool->add(buff, _s); }
00043 ~STR() { }
00044 size_t len() const { return strlen(_s); }
00045 STR &operator = (CSTR &s) { _s = s._s; return *this;}
00046 char *operator * () const { return _s; }
00047 char operator [](int i) const { return _s[i]; }
00048 bool operator ==(CSTR &s) const { return _s == s._s; }
00049 STR* operator + (CSTR &s) const { char buff[1024];
00050 sprintf(buff,"%s%s",_s,s._s);
00051 return new STR(buff); }
00052 bool contains (CSTR &s) const { return strstr(_s, s._s) != 0; }
00053 static double load_factor() { return strpool?strpool->load_factor():0.0; }
00054 friend inline ostream &operator<<(ostream &os, CSTR *s) { return os<< s->_s;}
00055 };
00056
00057 #define Cstr_ptr const str_ptr
00058 #define Cstr_list const str_list
00059 class str_ptr;
00060 template <class T>
00061 #if defined(sgi) || defined(WIN32) || defined(_AIX) || defined(__GNUC__) || defined(__KCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510)
00062 class LIST;
00063 #else
00064 class LIST<T>;
00065 #endif
00066
00067 typedef LIST<str_ptr> str_list;
00068 class str_ptr : public REFptr<STR> {
00069 public :
00070 static Cstr_ptr null;
00071 static Cstr_ptr &null_str() { if (null.p_ == 0) ((str_ptr &) null) = (STR::null = new STR("")); return null; }
00072
00073 str_ptr() : REFptr<STR>(new STR("")){ }
00074 str_ptr(Cstr_ptr &p) : REFptr<STR>(p) { }
00075 str_ptr(STR *s) : REFptr<STR>(s?s:null.p_){ }
00076 str_ptr(const char *s) : REFptr<STR>(new STR(s)) { }
00077 str_ptr(char c) : REFptr<STR>(new STR(c)) { }
00078 str_ptr(int x) : REFptr<STR>(new STR(x)) { }
00079 str_ptr(double d) : REFptr<STR>(new STR(d)) { }
00080 size_t len () const { return p_->len(); }
00081 char operator [](int i) const { return (*p_)[i]; }
00082 bool operator ==(Cstr_ptr &s) const { return *s.p_ == *p_; }
00083 bool operator !=(Cstr_ptr &s) const { return !(*s.p_ == *p_); }
00084 bool operator ! () const { return (!p_ || !**p_ || !***p_) ; }
00085 operator STR*() const { return (!*this) ? 0 : p_; }
00086 str_ptr operator + (Cstr_ptr &s) const { return str_ptr(*p_ + *s.p_); }
00087 str_ptr to_upper () const;
00088 str_ptr to_lower () const;
00089 bool contains (Cstr_ptr &s) const {return p_->contains(*s.p_);}
00090
00091 bool contains (Cstr_list &s) const;
00092 };
00093
00094 #ifdef JOT_AVOID_STATIC_LOCAL_INLINE_VAR
00095 #define RET_STAT_STR(s) return str_ptr(s)
00096 #else
00097 #define RET_STAT_STR(s) static str_ptr st(s); return st
00098 #endif
00099
00100
00101 #define NULL_STR str_ptr::null_str()
00102
00103 extern "C" {
00104 typedef int (* compare_func_t) (const void *, const void *);
00105 }
00106
00107
00108 #define BAD_IND -1
00109
00110
00111
00112
00113
00114
00115
00116
00117 #define CARRAY const ARRAY
00118 template <class T>
00119 class ARRAY {
00120 protected:
00121 T* _array;
00122 int _num;
00123 int _max;
00124 bool _unique;
00125 bool _do_index;
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 virtual void set_index(const T&, int ) const {}
00137 virtual void clear_index(const T&) const {}
00138
00139
00140
00141
00142
00143 virtual void clear_ele (int ) {}
00144
00145
00146 virtual void clear_range(int i, int j) {
00147 if (_do_index)
00148 for ( ; i < j; i++)
00149 clear_index(_array[i]);
00150 }
00151
00152
00153
00154 virtual void append_ele(const T& el) {
00155
00156 if (_do_index)
00157 set_index(el, _num);
00158 if (_num < _max) {
00159 _array[_num++] = el;
00160 } else {
00161
00162
00163 T tmp = el;
00164 realloc();
00165 _array[_num++] = tmp;
00166 }
00167 }
00168
00169 public:
00170
00171
00172
00173 ARRAY(int m=0) :
00174 _array(0), _num(0), _max(max(m,0)), _unique(0), _do_index(0) {
00175 if (_max) _array = new T[_max];
00176 }
00177 ARRAY(CARRAY<T>& l) :
00178 _array(0), _num(0), _max(0), _unique(0), _do_index(0) { *this = l; }
00179
00180 virtual ~ARRAY() { clear(); delete [] _array;}
00181
00182
00183
00184 int num() const { return _num; }
00185 bool empty() const { return (_num<=0); }
00186 bool valid_index(int k) const { return (k>=0 && k<_num); }
00187 void set_unique() { _unique = 1; }
00188
00189 T* array() { return _array; }
00190 T& operator[](int j) const { assert(_array); return _array[j]; }
00191
00192
00193
00194 T& last() const {
00195 assert(!empty());
00196 return _array[_num-1];
00197 }
00198 T& first() const {
00199 assert(!empty());
00200 return _array[0];
00201 }
00202
00203
00204
00205
00206 void begin_index() {
00207 _do_index = true;
00208 for (int i=0; i<_num; i++)
00209 set_index(_array[i], i);
00210 }
00211
00212
00213 void end_index() {
00214 for (int i=0; i<_num; i++)
00215 clear_index(_array[i]);
00216 _do_index = false;
00217 }
00218
00219 bool is_indexing() const { return _do_index; }
00220
00221
00222
00223
00224 virtual void clear() {
00225
00226 if (_do_index)
00227 end_index();
00228
00229 clear_range(0,_num);
00230 _num=0;
00231 }
00232
00233
00234 virtual void truncate(int n) {
00235 if (valid_index(n)) {
00236 clear_range(n,_num);
00237 _num = n;
00238 } else err_msg("ARRAY::truncate: Error: bad index %d/%d", n, _num);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 virtual void realloc(int new_max=0) {
00253
00254 if (new_max && new_max <= _max)
00255 return;
00256
00257 _max = (new_max == 0) ? (_max ? _max*2 : 1) : new_max;
00258
00259 T *tmp = new T [_max]; assert(tmp);
00260
00261
00262 for (int i=0; i<_num; i++) {
00263 tmp[i] = _array[i];
00264 clear_ele(i);
00265 }
00266
00267 delete [] _array;
00268 _array = tmp;
00269 }
00270
00271
00272
00273
00274
00275 virtual int get_index(const T &el) const {
00276
00277 for (int k = _num-1; k >= 0; k--)
00278 if (_array[k] == el)
00279 return k;
00280 return BAD_IND;
00281 }
00282
00283 bool contains(const T &el) const { return get_index(el) >= 0; }
00284
00285
00286
00287
00288
00289 bool add_uniquely(const T& el) {
00290 if (get_index(el) < 0) {
00291 append_ele(el);
00292 return true;
00293 }
00294 return false;
00295 }
00296
00297
00298 void operator += (const T& el) {
00299 if (_unique)
00300 add_uniquely(el);
00301 else
00302 append_ele(el);
00303 }
00304
00305
00306 void add (const T& p) { *this += p; }
00307
00308
00309 void push(const T& p) {
00310 insert(0,1);
00311 _array[0] = p;
00312 if (_do_index)
00313 set_index(p, 0);
00314 }
00315
00316
00317
00318
00319 void insert(int ind, int num) {
00320 if (_num+num > _max)
00321 realloc(_num+num);
00322 _num += num;
00323 for (int i=_num-1; i>=ind+num; i--) {
00324 _array[i] = _array[i-num];
00325 if (_do_index)
00326 set_index(_array[i], i);
00327 }
00328 }
00329
00330
00331
00332
00333 bool remove(int k) {
00334
00335
00336 if (valid_index(k)) {
00337
00338 if (_do_index) {
00339 set_index(last(), k);
00340 clear_index(_array[k]);
00341 }
00342 _array[k] = _array[--_num];
00343 clear_ele(_num);
00344 return 1;
00345 } else if (k != BAD_IND) {
00346 err_msg("ARRAY::remove: invalid index %d", k);
00347 return 0;
00348 } else return 0;
00349 }
00350
00351
00352 bool operator -= (const T &el) { return remove(get_index(el)); }
00353 bool rem(const T &p) { return (*this -= p); }
00354
00355
00356
00357 T pop() {
00358
00359 T tmp = last();
00360 remove(_num-1);
00361 return tmp;
00362 }
00363
00364
00365
00366 bool pull_index(int k) {
00367 if (valid_index(k)) {
00368 if (_do_index)
00369 clear_index(_array[k]);
00370 for (int i=k; i<_num-1; i++) {
00371 _array[i] = _array[i+1];
00372 if (_do_index)
00373 set_index(_array[i], i);
00374 }
00375 clear_ele(--_num);
00376 return true;
00377 }
00378 if (k != BAD_IND)
00379 err_msg("ARRAY::pull: invalid index %d", k);
00380 return 0;
00381 }
00382
00383 bool pull_element(const T& p) { return pull_index(get_index(p)); }
00384
00385
00386
00387
00388
00389 virtual void shift(int p) {
00390
00391 if (empty())
00392 return;
00393
00394 int n = _num;
00395
00396
00397 if (p >= n) p %= n;
00398 else if (p<0) p = div(p,n).rem + n;
00399
00400 assert(p >=0 && p<n);
00401
00402 if (p == 0)
00403 return;
00404
00405
00406
00407 ARRAY<T> tmp = *this;
00408 for (int k=0; k<n; k++)
00409 _array[(k + p)%n] = tmp[k];
00410
00411
00412 if (_do_index)
00413 begin_index();
00414 }
00415
00416
00417 ARRAY<T> extract(int start, int n) const {
00418 if (!(valid_index(start) && valid_index(start+n-1)))
00419 return ARRAY<T>();
00420 ARRAY<T> ret(n);
00421 for (int i=0; i<n; i++)
00422 ret += _array[i+start];
00423 return ret;
00424 }
00425
00426
00427
00428
00429
00430
00431 ARRAY<T>& operator+=(CARRAY<T>& b) {
00432 if(!b.empty()) {
00433 realloc(num() + b.num());
00434 for (int i=0; i<b.num(); i++)
00435 *this += b[i];
00436 }
00437 return *this;
00438 }
00439
00440
00441 ARRAY<T>& operator=(CARRAY<T>& b) {
00442
00443 if (this == &b)
00444 return *this;
00445
00446 clear();
00447 return *this += b;
00448 }
00449
00450
00451 void operator-=(CARRAY<T> &l) {
00452 for (int i=0; i < l.num(); i++)
00453 *this -= l[i];
00454 }
00455
00456
00457 virtual void reverse() {
00458 for (int i=0, j=_num-1; i<j; ++i, --j) {
00459 swap(_array[i],_array[j]);
00460 if (_do_index) {
00461 set_index(_array[i], i);
00462 set_index(_array[j], j);
00463 }
00464 }
00465 }
00466
00467
00468 virtual void sort(compare_func_t compare) {
00469 qsort(_array, _num, sizeof(T), compare);
00470
00471
00472 if (_do_index)
00473 begin_index();
00474 }
00475 };
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 template <class T, class S>
00488 inline bool
00489 operator ==(CARRAY<T>& a, CARRAY<S> &b)
00490 {
00491 if (a.num() != b.num())
00492 return 0;
00493 for (int i = 0; i < b.num(); i++) {
00494
00495 if (!(a[i] == (T)b[i]))
00496 return 0;
00497 }
00498 return 1;
00499 }
00500
00501
00502 template <class T, class S>
00503 inline ARRAY<T>&
00504 operator +=(ARRAY<T>& a, CARRAY<S>& b)
00505 {
00506 if(!b.empty()) {
00507 a.realloc(a.num() + b.num());
00508 for (int i=0; i<b.num(); i++)
00509 a += (T)b[i];
00510 }
00511 return a;
00512 }
00513
00514
00515 template <class T, class S>
00516 inline ARRAY<T>
00517 operator +(CARRAY<T>& a, CARRAY<S>& b)
00518 {
00519 ARRAY<T> ret = a;
00520 return ret += b;
00521 }
00522
00523
00524
00525 #define ARRAYptrs ARRAY
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 #define CLIST const LIST
00537 template <class T>
00538 class LIST : public ARRAY<T> {
00539 protected:
00540 virtual void clear_ele (int i) { (*this)[i].Clear(); }
00541 virtual void clear_range(int i, int j) {
00542 ARRAY<T>::clear_range(i,j);
00543 for (int k=i; k < j; k++)
00544 clear_ele(k);
00545 }
00546 public:
00547 LIST(int m=0) : ARRAY<T>(m) {}
00548 LIST(CLIST<T>& l) : ARRAY<T>(l) {}
00549 };
00550
00551 template<class T>
00552 ostream &
00553 operator<< (ostream &os, const ARRAY<T> &array)
00554 {
00555 os << array.num() << endl;
00556 for (int i = 0; i < array.num(); i++) {
00557 os << array[i] << endl;
00558 }
00559 os << endl;
00560 return os;
00561 }
00562
00563 template<class T>
00564 istream &
00565 operator>> (istream &is, ARRAY<T> &array)
00566 {
00567 int num; is >> num; array.clear();
00568 for (int i = 0; i < num; i++) {
00569 T x; is >> x; array += x;
00570 }
00571 return is;
00572 }
00573
00574 str_list tokenize(Cstr_ptr &str, char delim=' ');
00575 str_list dir_list(Cstr_ptr &directory);
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 #ifndef WIN32
00586 extern "C" int (*SELECT)(int, fd_set *, fd_set *, fd_set *, timeval *);
00587
00588 extern "C" int Select(int maxfds, fd_set *reads, fd_set *writes,
00589 fd_set *errors, struct timeval *timeout);
00590 #endif
00591
00592 inline void
00593 signalSafeSelect(void)
00594 {
00595 #ifndef WIN32
00596 SELECT = Select;
00597 #endif
00598 }
00599
00600 inline void
00601 fsleep(double dur)
00602 {
00603 #ifdef WIN32
00604 Sleep(int(dur * 1e3));
00605 #else
00606 struct timeval timeout;
00607 double sleep_time = dur * 1e6;
00608 timeout.tv_sec = 0;
00609
00610 #if defined(macosx) || defined(sgi) || defined(__CYGWIN__)
00611 timeout.tv_usec = (long) sleep_time;
00612 #else
00613 # ifdef linux
00614 timeout.tv_usec = (time_t) sleep_time;
00615 #else
00616 timeout.tv_usec = (suseconds_t) sleep_time;
00617 # endif
00618 #endif
00619 SELECT(FD_SETSIZE, 0, 0, 0, &timeout);
00620 #endif
00621 }
00622
00623 #endif // SUPPORT_H
00624
00625