00001 #ifndef __LOUT_MISC_HH__
00002 #define __LOUT_MISC_HH__
00003
00004 #include <stdio.h>
00005 #include <stdarg.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <assert.h>
00009
00015 namespace lout {
00016
00017 namespace misc {
00018
00019 template <class T> inline T min (T a, T b) { return a < b ? a : b; }
00020 template <class T> inline T max (T a, T b) { return a > b ? a : b; }
00021
00022 template <class T> inline T min (T a, T b, T c)
00023 {
00024 return (min (a, min (b, c)));
00025 }
00026 template <class T> inline T max (T a, T b, T c)
00027 {
00028 return (max (a, max (b, c)));
00029 }
00030
00031 extern const char *prgName;
00032
00033 void init (int argc, char *argv[]);
00034
00035 inline void assertNotReached ()
00036 {
00037 fprintf (stderr, "*** [%s] This should not happen! ***\n", prgName);
00038 abort ();
00039 }
00040
00041 inline int roundInt(double d)
00042 {
00043 return (int) ((d > 0) ? (d + 0.5) : (d - 0.5));
00044 }
00045
00052 class Comparable
00053 {
00054 public:
00055 virtual ~Comparable();
00056
00070 virtual int compareTo(Comparable *other) = 0;
00071
00072 static int compareFun(const void *p1, const void *p2);
00073 };
00074
00079 template <class T> class SimpleVector
00080 {
00081 private:
00082 T *array;
00083 int num, numAlloc;
00084
00085 inline void resize ()
00086 {
00087
00088
00089
00090 if (array == NULL) {
00091 this->numAlloc = 1;
00092 this->array = (T*) malloc (sizeof (T));
00093 }
00094 if (this->numAlloc < this->num) {
00095 this->numAlloc = (this->num < 100) ?
00096 this->num : this->num + this->num/10;
00097 this->array =
00098 (T*) realloc(this->array, (this->numAlloc * sizeof (T)));
00099 }
00100 }
00101
00102 public:
00103 inline SimpleVector (int initAlloc)
00104 {
00105 this->num = 0;
00106 this->numAlloc = initAlloc;
00107 this->array = NULL;
00108 }
00109
00110 inline SimpleVector (const SimpleVector &o) {
00111 this->array = NULL;
00112 this->num = o.num;
00113 this->numAlloc = o.numAlloc;
00114 resize ();
00115 memcpy (this->array, o.array, sizeof (T) * num);
00116 }
00117
00118 inline ~SimpleVector ()
00119 {
00120 if (this->array)
00121 free (this->array);
00122 }
00123
00127 inline int size() { return this->num; }
00128
00129 inline T* getArray() { return array; }
00130
00136 inline void increase() { setSize(this->num + 1); }
00137
00143 inline void setSize(int newSize) {
00144 assert (newSize >= 0);
00145 this->num = newSize;
00146 this->resize ();
00147 }
00148
00154 inline void setSize (int newSize, T t) {
00155 int oldSize = this->num;
00156 setSize (newSize);
00157 for (int i = oldSize; i < newSize; i++)
00158 set (i, t);
00159 }
00160
00166 inline T* getRef (int i) {
00167 assert (i >= 0 && this->num - i > 0);
00168 return array + i;
00169 }
00170
00177 inline T get (int i) {
00178 assert (i >= 0 && this->num - i > 0);
00179 return this->array[i];
00180 }
00181
00190 inline void set (int i, T t) {
00191 assert (i >= 0 && this->num - i > 0);
00192 this->array[i] = t;
00193 }
00194 };
00195
00196
00200 class StringBuffer
00201 {
00202 private:
00203 struct Node
00204 {
00205 char *data;
00206 Node *next;
00207 };
00208
00209 Node *firstNode, *lastNode;
00210 int numChars;
00211 char *str;
00212 bool strValid;
00213
00214 public:
00215 StringBuffer();
00216 ~StringBuffer();
00217
00224 inline void append(const char *str) { appendNoCopy(strdup(str)); }
00225 void appendNoCopy(char *str);
00226 const char *getChars();
00227 void clear ();
00228 };
00229
00230
00234 class BitSet
00235 {
00236 private:
00237 unsigned char *bits;
00238 int numBytes;
00239
00240 inline int bytesForBits(int bits) { return bits == 0 ? 1 : (bits + 7) / 8; }
00241
00242 public:
00243 BitSet(int initBits);
00244 ~BitSet();
00245 void intoStringBuffer(misc::StringBuffer *sb);
00246 bool get(int i);
00247 void set(int i, bool val);
00248 void clear();
00249 };
00250
00256 class ZoneAllocator
00257 {
00258 private:
00259 size_t poolSize, poolLimit, freeIdx;
00260 SimpleVector <char*> *pools;
00261 SimpleVector <char*> *bulk;
00262
00263 public:
00264 ZoneAllocator (size_t poolSize) {
00265 this->poolSize = poolSize;
00266 this->poolLimit = poolSize / 4;
00267 this->freeIdx = poolSize;
00268 this->pools = new SimpleVector <char*> (1);
00269 this->bulk = new SimpleVector <char*> (1);
00270 };
00271
00272 ~ZoneAllocator () {
00273 zoneFree ();
00274 delete pools;
00275 delete bulk;
00276 }
00277
00278 inline void * zoneAlloc (size_t t) {
00279 void *ret;
00280
00281 if (t > poolLimit) {
00282 bulk->increase ();
00283 bulk->set (bulk->size () - 1, (char*) malloc (t));
00284 return bulk->get (bulk->size () - 1);
00285 }
00286
00287 if (t > poolSize - freeIdx) {
00288 pools->increase ();
00289 pools->set (pools->size () - 1, (char*) malloc (poolSize));
00290 freeIdx = 0;
00291 }
00292
00293 ret = pools->get (pools->size () - 1) + freeIdx;
00294 freeIdx += t;
00295 return ret;
00296 }
00297
00298 inline void zoneFree () {
00299 for (int i = 0; i < pools->size (); i++)
00300 free (pools->get (i));
00301 pools->setSize (0);
00302 for (int i = 0; i < bulk->size (); i++)
00303 free (bulk->get (i));
00304 bulk->setSize (0);
00305 freeIdx = poolSize;
00306 }
00307
00308 inline const char *strndup (const char *str, size_t t) {
00309 char *new_str = (char *) zoneAlloc (t + 1);
00310 memcpy (new_str, str, t);
00311 new_str[t] = '\0';
00312 return new_str;
00313 }
00314
00315 inline const char *strdup (const char *str) {
00316 return strndup (str, strlen (str));
00317 }
00318 };
00319
00320 }
00321
00322 }
00323
00324 #endif // __LOUT_MISC_HH__