2 #ifndef ACOMMON_OBJSTACK__HPP
3 #define ACOMMON_OBJSTACK__HPP
5 #include "parm_string.hpp"
13 typedef unsigned char byte;
17 byte data[1]; // hack for data[]
30 ObjStack(const ObjStack &);
31 void operator=(const ObjStack &);
33 void align_bottom(size_t align) {
34 size_t a = (size_t)bottom % align;
35 if (a != 0) bottom += align - a;
37 void align_top(size_t align) {
38 top -= (size_t)top % align;
41 // The alignment here is the guaranteed alignment that memory in
42 // new chunks will be aligned to. It does NOT guarantee that
43 // every object is aligned as such unless all objects inserted
44 // are a multiple of align.
45 ObjStack(size_t chunk_s = 1024, size_t align = sizeof(void *));
53 // This alloc_bottom does NOT check alignment. However, if you always
54 // insert objects with a multiple of min_align than it will always
55 // me aligned as such.
56 void * alloc_bottom(size_t size) {
59 if (bottom > top) {new_chunk(); tmp = bottom; bottom += size;}
62 // This alloc_bottom will insure that the object is aligned based on the
64 void * alloc_bottom(size_t size, size_t align)
69 if (bottom > top) {new_chunk(); goto loop;}
72 char * dup_bottom(ParmString str) {
73 return (char *)memcpy(alloc_bottom(str.size() + 1),
74 str.str(), str.size() + 1);
77 // This alloc_bottom does NOT check alignment. However, if you
78 // always insert objects with a multiple of min_align than it will
79 // always be aligned as such.
80 void * alloc_top(size_t size) {
82 if (top < bottom) {new_chunk(); top -= size;}
85 // This alloc_top will insure that the object is aligned based on
86 // the alignment given.
87 void * alloc_top(size_t size, size_t align)
91 if (top < bottom) {new_chunk(); goto loop;}
94 char * dup_top(ParmString str) {
95 return (char *)memcpy(alloc_top(str.size() + 1),
96 str.str(), str.size() + 1);
99 // By default objects are allocated from the top since that is sligtly
101 void * alloc(size_t size) {return alloc_top(size);}
102 void * alloc(size_t size, size_t align) {return alloc_top(size,align);}
103 char * dup(ParmString str) {return dup_top(str);}
105 // alloc_temp allocates an object from the bottom which can be
106 // resized untill it is commited. If the resizing will involve
107 // moving the object than the data will be copied in the same way
108 // realloc does. Any previously allocated objects are aborted when
109 // alloc_temp is called.
111 if (temp_end) return bottom;
114 unsigned temp_size() {
115 return temp_end - bottom;
117 void * alloc_temp(size_t size) {
118 temp_end = bottom + size;
119 if (temp_end > top) {
121 temp_end = bottom + size;
125 // returns a pointer the the new beginning of the temp memory
126 void * resize_temp(size_t size) {
128 return alloc_temp(size);
129 if (bottom + size <= top) {
130 temp_end = bottom + size;
132 size_t s = temp_end - bottom;
135 memcpy(bottom, p, s);
136 temp_end = bottom + size;
140 // returns a pointer to the beginning of the new memory (in
141 // otherwords the END of the temp memory BEFORE the call to grow
142 // temp) NOT the beginning if the temp memory
143 void * grow_temp(size_t s) {
145 return alloc_temp(s);
146 unsigned old_size = temp_end - bottom;
147 unsigned size = old_size + s;
148 if (bottom + size <= top) {
149 temp_end = bottom + size;
151 size_t s = temp_end - bottom;
154 memcpy(bottom, p, s);
155 temp_end = bottom + size;
157 return bottom + old_size;
167 typedef ObjStack StringBuffer;