home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / tools.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-06-05  |  11.6 KB  |  472 lines

  1. // generic useful stuff for any C++ program
  2.  
  3. #ifndef _TOOLS_H
  4. #define _TOOLS_H
  5.  
  6. #ifdef NULL
  7. #undef NULL
  8. #endif
  9. #define NULL 0
  10.  
  11. typedef unsigned char uchar;
  12. typedef unsigned short ushort;
  13. typedef unsigned int uint;
  14.  
  15. #ifdef _DEBUG
  16. #ifdef __GNUC__
  17. #define ASSERT(c) if(!(c)) { asm("int $3"); }
  18. #else
  19. #define ASSERT(c) if(!(c)) { __asm int 3 }
  20. #endif
  21. #else
  22. #define ASSERT(c) if(c) {}
  23. #endif
  24.  
  25. #define swap(t,a,b) { t m=a; a=b; b=m; }
  26. #ifndef max
  27. #define max(a,b) (((a) > (b)) ? (a) : (b))
  28. #endif
  29. #ifndef min
  30. #define min(a,b) (((a) < (b)) ? (a) : (b))
  31. #endif
  32. #define rnd(max) (rand()%(max))
  33. #define rndreset() (srand(1))
  34. #define rndtime() { loopi(lastmillis&0xF) rnd(i+1); }
  35.  
  36. #define loop(v,m) for(int v = 0; v<int(m); v++)
  37. #define loopi(m) loop(i,m)
  38. #define loopj(m) loop(j,m)
  39. #define loopk(m) loop(k,m)
  40. #define loopl(m) loop(l,m)
  41.  
  42.  
  43. #define DELETEP(p) if(p) { delete   p; p = 0; }
  44. #define DELETEA(p) if(p) { delete[] p; p = 0; }
  45.  
  46. #define PI  (3.1415927f)
  47. #define PI2 (2*PI)
  48. #define SQRT3 (1.7320508f)
  49. #define RAD (PI / 180.0f)
  50.  
  51. #ifdef WIN32
  52. #ifdef M_PI
  53. #undef M_PI
  54. #endif
  55. #define M_PI 3.14159265
  56.  
  57. #ifndef __GNUC__
  58. #pragma warning (3: 4189)       // local variable is initialized but not referenced
  59. #pragma warning (disable: 4244) // conversion from 'int' to 'float', possible loss of data
  60. #pragma warning (disable: 4355) // 'this' : used in base member initializer list
  61. #pragma warning (disable: 4996) // 'strncpy' was declared deprecated
  62. #endif
  63.  
  64. #define PATHDIV '\\'
  65. #else
  66. #define __cdecl
  67. #define _vsnprintf vsnprintf
  68. #define PATHDIV '/'
  69. #endif
  70.  
  71. // easy safe strings
  72.  
  73. #define _MAXDEFSTR 260
  74. typedef char string[_MAXDEFSTR];
  75.  
  76. inline void formatstring(char *d, const char *fmt, va_list v) { _vsnprintf(d, _MAXDEFSTR, fmt, v); d[_MAXDEFSTR-1] = 0; }
  77. inline char *s_strncpy(char *d, const char *s, size_t m) { strncpy(d,s,m); d[m-1] = 0; return d; }
  78. inline char *s_strcpy(char *d, const char *s) { return s_strncpy(d,s,_MAXDEFSTR); }
  79. inline char *s_strcat(char *d, const char *s) { size_t n = strlen(d); return s_strncpy(d+n,s,_MAXDEFSTR-n); }
  80.  
  81.  
  82. struct s_sprintf_f
  83. {
  84.     char *d;
  85.     s_sprintf_f(char *str): d(str) {}
  86.     void operator()(const char* fmt, ...)
  87.     {
  88.         va_list v;
  89.         va_start(v, fmt);
  90.         formatstring(d, fmt, v);
  91.         va_end(v);
  92.     };
  93. };
  94.  
  95. #define s_sprintf(d) s_sprintf_f((char *)d)
  96. #define s_sprintfd(d) string d; s_sprintf(d)
  97. #define s_sprintfdlv(d,last,fmt) string d; { va_list ap; va_start(ap, last); formatstring(d, fmt, ap); va_end(ap); }
  98. #define s_sprintfdv(d,fmt) s_sprintfdlv(d,fmt,fmt)
  99.  
  100.  
  101. template <class T> void _swap(T &a, T &b) { T t = a; a = b; b = t; }
  102.  
  103.  
  104.  
  105. extern char *path(char *s);
  106. extern char *parentdir(char *directory);
  107. extern char *loadfile(char *fn, int *size);
  108. extern bool cmpb(void *b, int n, enet_uint32 c);
  109. extern bool cmpf(char *fn, enet_uint32 c);
  110. extern void endianswap(void *, int, int);
  111. extern void seedMT(uint seed);
  112. extern uint randomMT(void);
  113.  
  114. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  115. #define CMPB(b, c) (true)
  116. #else
  117. #define CMPB(b, c) (cmpb(b, sizeof(b), ENET_HOST_TO_NET_32(c)))
  118. #endif
  119.  
  120. #define loopv(v)    if(false) {} else for(int i = 0; i<(v).length(); i++)
  121. #define loopvj(v)   if(false) {} else for(int j = 0; j<(v).length(); j++)
  122. #define loopvk(v)   if(false) {} else for(int k = 0; k<(v).length(); k++)
  123. #define loopvrev(v) if(false) {} else for(int i = (v).length()-1; i>=0; i--)
  124.  
  125. template <class T>
  126. struct databuf
  127. {
  128.     enum
  129.     {
  130.         OVERREAD  = 1<<0,
  131.         OVERWROTE = 1<<1
  132.     };
  133.  
  134.     T *buf;
  135.     int len, maxlen;
  136.     uchar flags;
  137.  
  138.     template <class U>
  139.     databuf(T *buf, U maxlen) : buf(buf), len(0), maxlen((int)maxlen), flags(0) {}
  140.  
  141.     const T &get()
  142.     {
  143.         static T overreadval;
  144.         if(len<maxlen) return buf[len++];
  145.         flags |= OVERREAD;
  146.         return overreadval;
  147.     }
  148.  
  149.     databuf subbuf(int sz)
  150.     {
  151.         sz = min(sz, maxlen-len);
  152.         len += sz;
  153.         return databuf(&buf[len-sz], sz);
  154.     }
  155.  
  156.     void put(const T &val)
  157.     {
  158.         if(len<maxlen) buf[len++] = val;
  159.         else flags |= OVERWROTE;
  160.     }
  161.  
  162.     void put(const T *vals, int numvals)
  163.     {
  164.         if(maxlen-len<numvals) flags |= OVERWROTE;
  165.         memcpy(&buf[len], vals, min(maxlen-len, numvals)*sizeof(T));
  166.         len += min(maxlen-len, numvals);
  167.     }
  168.  
  169.     int length() const { return len; }
  170.     int remaining() const { return maxlen-len; }
  171.     bool overread() const { return flags&OVERREAD; }
  172.     bool overwrote() const { return flags&OVERWROTE; }
  173.  
  174.     void forceoverread()
  175.     {
  176.         len = maxlen;
  177.         flags |= OVERREAD;
  178.     }
  179. };
  180.  
  181. typedef databuf<char> charbuf;
  182. typedef databuf<uchar> ucharbuf;
  183.  
  184. template <class T> struct vector
  185. {
  186.     T *buf;
  187.     int alen;
  188.     int ulen;
  189.  
  190.     vector()
  191.     {
  192.         alen = 8;
  193.         buf = (T *)new uchar[alen*sizeof(T)];
  194.         ulen = 0;
  195.     }
  196.     vector(const vector<T> &v)
  197.     {
  198.         alen = v.length();
  199.         buf = (T *)new uchar[alen*sizeof(T)];
  200.         ulen = 0;
  201.         *this = v;
  202.     }
  203.  
  204.     ~vector() { setsize(0); delete[] (uchar *)buf; }
  205.  
  206.     vector<T> &operator=(const vector<T> &v)
  207.     {
  208.         setsize(0);
  209.         loopv(v) add(v[i]);
  210.         return *this;
  211.     }
  212.  
  213.     T &add(const T &x)
  214.     {
  215.         if(ulen==alen) vrealloc();
  216.         new (&buf[ulen]) T(x);
  217.         return buf[ulen++];
  218.     }
  219.  
  220.     T &add()
  221.     {
  222.         if(ulen==alen) vrealloc();
  223.         new (&buf[ulen]) T;
  224.         return buf[ulen++];
  225.     }
  226.  
  227.     T &dup()
  228.     {
  229.         if(ulen==alen) vrealloc();
  230.         new (&buf[ulen]) T(buf[ulen-1]);
  231.         return buf[ulen++];
  232.     }
  233.  
  234.     bool inrange(size_t i) const { return i<size_t(ulen); }
  235.     bool inrange(int i) const { return i>=0 && i<ulen; }
  236.  
  237.     T &pop() { return buf[--ulen]; }
  238.     T &last() { return buf[ulen-1]; }
  239.     void drop() { buf[--ulen].~T(); }
  240.     bool empty() const { return ulen==0; }
  241.  
  242.     int length() const { return ulen; }
  243.     T &operator[](int i) { ASSERT(i>=0 && i<ulen); return buf[i]; }
  244.     const T &operator[](int i) const { ASSERT(i >= 0 && i<ulen); return buf[i]; }
  245.     
  246.     void setsize(int i)         { ASSERT(i<=ulen); while(ulen>i) drop(); }
  247.     void setsizenodelete(int i) { ASSERT(i<=ulen); ulen = i; }
  248.     
  249.     void deletecontentsp() { while(!empty()) delete   pop(); }
  250.     void deletecontentsa() { while(!empty()) delete[] pop(); }
  251.     
  252.     T *getbuf() { return buf; }
  253.     const T *getbuf() const { return buf; }
  254.  
  255.     template<class ST>
  256.     void sort(int (__cdecl *cf)(ST *, ST *), int i = 0, int n = -1) { qsort(&buf[i], n<0?ulen:n, sizeof(T), (int (__cdecl *)(const void *,const void *))cf); }
  257.  
  258.     void *_realloc(void *p, int oldsize, int newsize)
  259.     {
  260.         void *np = new uchar[newsize];
  261.         memcpy(np, p, newsize>oldsize ? oldsize : newsize);
  262.         delete[] (uchar *)p;
  263.         return np;
  264.     }
  265.     
  266.     void vrealloc()
  267.     {
  268.         int olen = alen;
  269.         buf = (T *)_realloc(buf, olen*sizeof(T), (alen *= 2)*sizeof(T));
  270.     }
  271.  
  272.     databuf<T> reserve(int sz)
  273.     {
  274.         while(alen-ulen<sz) vrealloc();
  275.         return databuf<T>(&buf[ulen], sz);
  276.     }
  277.  
  278.     void addbuf(const databuf<T> &p)
  279.     {
  280.         ulen += p.length();
  281.     }
  282.  
  283.     void remove(int i, int n)
  284.     {
  285.         for(int p = i+n; p<ulen; p++) buf[p-n] = buf[p];
  286.         ulen -= n;
  287.     }
  288.  
  289.     T remove(int i)
  290.     {
  291.         T e = buf[i];
  292.         for(int p = i+1; p<ulen; p++) buf[p-1] = buf[p];
  293.         ulen--;
  294.         return e;
  295.     }
  296.  
  297.     int find(const T &o)
  298.     {
  299.         loopi(ulen) if(buf[i]==o) return i;
  300.         return -1;
  301.     }
  302.     
  303.     void removeobj(const T &o)
  304.     {
  305.         loopi(ulen) if(buf[i]==o) remove(i--);
  306.     }
  307.  
  308.     void replacewithlast(const T &o)
  309.     {
  310.         if(!ulen) return;
  311.         loopi(ulen-1) if(buf[i]==o)
  312.         {
  313.             buf[i] = buf[ulen-1];
  314.         }
  315.         ulen--;
  316.     }
  317.  
  318.     T &insert(int i, const T &e)
  319.     {
  320.         add(T());
  321.         for(int p = ulen-1; p>i; p--) buf[p] = buf[p-1];
  322.         buf[i] = e;
  323.         return buf[i];
  324.     }
  325. };
  326.  
  327. typedef vector<char *> cvector;
  328. typedef vector<int> ivector;
  329. typedef vector<ushort> usvector;
  330.  
  331. static inline uint hthash(const char *key)
  332. {
  333.     uint h = 5381;
  334.     for(int i = 0, k; (k = key[i]); i++) h = ((h<<5)+h)^k;    // bernstein k=33 xor
  335.     return h;
  336. }
  337.  
  338. static inline bool htcmp(const char *x, const char *y)
  339. {
  340.     return !strcmp(x, y);
  341. }
  342.  
  343. static inline uint hthash(int key)
  344. {   
  345.     return key;
  346. }
  347.  
  348. static inline bool htcmp(int x, int y)
  349. {
  350.     return x==y;
  351. }
  352.  
  353. static inline uint hthash(uint key)
  354. {
  355.     return key;
  356. }
  357.  
  358. static inline bool htcmp(uint x, uint y)
  359. {
  360.     return x==y;
  361. }
  362.  
  363. template <class K, class T> struct hashtable
  364. {
  365.     typedef K key;
  366.     typedef const K const_key;
  367.     typedef T value;
  368.     typedef const T const_value;
  369.  
  370.     enum { CHUNKSIZE = 16 };
  371.  
  372.     struct chain      { T data; K key; chain *next; };
  373.     struct chainchunk { chain chunks[CHUNKSIZE]; chainchunk *next; };
  374.  
  375.     int size;
  376.     int numelems;
  377.     chain **table;
  378.     chain *enumc;
  379.  
  380.     int chunkremain;
  381.     chainchunk *lastchunk;
  382.  
  383.     hashtable(int size = 1<<10)
  384.       : size(size)
  385.     {
  386.         numelems = 0;
  387.         chunkremain = 0;
  388.         lastchunk = NULL;
  389.         table = new chain *[size];
  390.         loopi(size) table[i] = NULL;
  391.     }
  392.  
  393.     ~hashtable()
  394.     {
  395.         DELETEA(table);
  396.     }
  397.  
  398.     chain *insert(const K &key, uint h)
  399.     {
  400.         if(!chunkremain)
  401.         {
  402.             chainchunk *chunk = new chainchunk;
  403.             chunk->next = lastchunk;
  404.             lastchunk = chunk;
  405.             chunkremain = CHUNKSIZE;
  406.         }
  407.         chain *c = &lastchunk->chunks[--chunkremain];
  408.         c->key = key;
  409.         c->next = table[h]; 
  410.         table[h] = c;
  411.         numelems++;
  412.         return c;
  413.     }
  414.  
  415.     chain *find(const K &key, bool doinsert)
  416.     {
  417.         uint h = hthash(key)&(size-1);
  418.         for(chain *c = table[h]; c; c = c->next)
  419.         {
  420.             if(htcmp(key, c->key)) return c;
  421.         }
  422.         if(doinsert) return insert(key, h);
  423.         return NULL;
  424.     }
  425.  
  426.     T *access(const K &key, const T *data = NULL)
  427.     {
  428.         chain *c = find(key, data != NULL);
  429.         if(data) c->data = *data;
  430.         if(c) return &c->data;
  431.         return NULL;
  432.     }
  433.  
  434.     T &operator[](const K &key)
  435.     {
  436.         return find(key, true)->data;
  437.     }
  438.  
  439.     void clear()
  440.     {
  441.         loopi(size)
  442.         {
  443.             /*
  444.             for(chain *c = table[i], *next; c; c = next) 
  445.             { 
  446.                 next = c->next; 
  447.                 delete c; 
  448.             }*/
  449.             table[i] = NULL;
  450.         }
  451.         numelems = 0;
  452.         chunkremain = 0;
  453.         for(chainchunk *chunk; lastchunk; lastchunk = chunk)
  454.         {
  455.             chunk = lastchunk->next;
  456.             delete lastchunk;
  457.         }
  458.     }
  459. };
  460.  
  461. #define enumeratekt(ht,k,e,t,f,b) loopi((ht).size) for(hashtable<k,t>::chain *enumc = (ht).table[i]; enumc; enumc = enumc->next) { hashtable<k,t>::const_key &e = enumc->key; t &f = enumc->data; b; }
  462. #define enumerate(ht,t,e,b)       loopi((ht).size) for((ht).enumc = (ht).table[i]; (ht).enumc; (ht).enumc = (ht).enumc->next) { t &e = (ht).enumc->data; b; }
  463. #define enumerateht(ht)           loopi((ht).size) for((ht).enumc = (ht).table[i]; (ht).enumc; (ht).enumc = (ht).enumc->next)
  464.  
  465. inline char *newstring(size_t l)                { return new char[l+1]; }
  466. inline char *newstring(const char *s, size_t l) { return s_strncpy(newstring(l), s, l+1); }
  467. inline char *newstring(const char *s)           { return newstring(s, strlen(s)); }
  468. inline char *newstringbuf(const char *s)        { return newstring(s, _MAXDEFSTR-1); }
  469.  
  470. #endif
  471.  
  472.