3a4a5b9ecce306a7b65aab164cc9c402329d355c
[charm.git] / src / libs / ck-libs / collide / collide_buffers.h
1 /*
2 Ancient, hideous custom memory management classes.
3 FIXME: replace these with something well-tested,
4 standard, and modern, like std::vector.
5
6 Orion Sky Lawlor, olawlor@acm.org, 2001/2/5
7 */
8 #ifndef __UIUC_CHARM_COLLIDE_BUFFERS_H
9 #define __UIUC_CHARM_COLLIDE_BUFFERS_H
10
11 #include <stdlib.h> /* for size_t */
12
13 //A simple extensible untyped chunk of memory.
14 //  Lengths are in bytes
15 class memoryBuffer {
16  public:
17   typedef unsigned int size_t;
18  private:
19   void *data;
20   size_t len;//Length of data array above
21   void setData(const void *toData,size_t toLen);//Reallocate and copy
22  public:
23   memoryBuffer();//Empty initial buffer
24   memoryBuffer(size_t initLen);//Initial capacity specified
25   ~memoryBuffer();//Deletes heap-allocated buffer
26   memoryBuffer(const memoryBuffer &in) {data=NULL;setData(in.data,in.len);}
27   memoryBuffer &operator=(const memoryBuffer &in) {setData(in.data,in.len); return *this;}
28   
29   size_t length(void) const {return len;}
30   void *getData(void) {return data;}
31   const void *getData(void) const {return data;}
32   void detachBuffer(void) {data=NULL;len=0;}
33   
34   void resize(size_t newlen);//Reallocate, preserving old data
35   void reallocate(size_t newlen);//Free old data, allocate new
36 };
37
38 //Superclass for simple flat memory containers
39 template <class T> class bufferT {
40   T *data; //Data items in container
41   int len; //Index of last valid member + 1
42  protected:
43   bufferT() :data(NULL),len(0) {}
44   bufferT(T *data_,int len_) :data(data_),len(len_) {}
45   void set(T *data_,int len_) {data=data_;len=len_;}
46   void setData(T *data_) {data=data_;}
47   void setLength(int len_) {len=len_;}
48   int &getLength(void) {return len;}
49  public:
50   int length(void) const {return len;}
51   
52   T &operator[](int t) {return data[t];}
53   const T &operator[](int t) const {return data[t];}
54   T &at(int t) {return data[t];}
55   const T &at(int t) const {return data[t];}
56   
57   T *getData(void) {return (T *)data;}
58   const T *getData(void) const {return (T *)data;}
59 };
60
61 //For preallocated data
62 template <class T> class fixedBufferT : public bufferT<T> {
63  public:
64   fixedBufferT(T *data_,int len_) :bufferT<T>(data_,len_) {}
65 };
66
67 //Variable size buffer
68 //T's constructors/destructors are not called by this (use std::vector)
69 //Copying the memory of a T must be equivalent to copying a T.
70 template <class T> class growableBufferT : public bufferT<T> {
71   typedef bufferT<T> super;
72   enum { sT=sizeof(T) };
73   memoryBuffer buf;//Data storage
74   int max;//Length of storage buffer
75   //Don't use these:
76   growableBufferT<T>(const growableBufferT<T> &in);
77   growableBufferT<T> &operator=(const growableBufferT<T> &in);
78  public:
79   growableBufferT<T>() :buf() {max=0;}
80   growableBufferT<T>(size_t Len) :buf(Len*sT) {set((T*)buf.getData(),Len);max=Len;}
81     
82   inline int length(void) const {return super::length();}
83   inline int size(void) const {return super::length();}
84   inline int &length(void) {return this->getLength();}
85   inline int capacity(void) const {return max;}
86   
87   T *detachBuffer(void) {
88     T *ret=(T *)buf.getData();
89     buf.detachBuffer();
90     this->set(NULL,0);
91     max=0;
92     return ret;
93   }
94   void empty(void) {reallocate(0);}
95   void push_back(const T& v) {
96     grow(length()+1);
97     at(this->getLength()++)=v;
98   }
99   //Push without checking bounds
100   void push_fast(const T& v) {
101     grow(length()+1);
102     at(this->getLength()++)=v;
103   }
104   void grow(int min) {
105     if (min>max) {
106       if (min > 1000000) {
107         //printf("COLLIDE: Buffer size %d is getting out of hand, switching to conservative mechanism!\n", min);
108         atLeast(min+(min/4));
109       }
110       else {
111         resize(min+max+8);
112       }
113     }
114   }
115   void atLeast(int min) {//More conservative version of grow
116     if (min>max) resize(min);
117   }
118   void resize(int Len) {
119     buf.resize(Len*sT);
120     setData((T*)buf.getData());
121     max=Len;
122   }
123   void reallocate(int Len) {
124     buf.reallocate(Len*sT);
125     setData((T*)buf.getData());
126     this->setLength(0);
127     max=Len;
128   }
129 };
130
131 #endif