xref: /386bsd/usr/include/nonstd/gnu/g++/Obstack.h (revision a2142627)
1 // This may look like C code, but it is really -*- C++ -*-
2 /*
3 Copyright (C) 1988 Free Software Foundation
4     written by Doug Lea (dl@rocky.oswego.edu)
5 
6 This file is part of GNU CC.
7 
8 GNU CC is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY.  No author or distributor
10 accepts responsibility to anyone for the consequences of using it
11 or for whether it serves any particular purpose or works at all,
12 unless he says so in writing.  Refer to the GNU CC General Public
13 License for full details.
14 
15 Everyone is granted permission to copy, modify and redistribute
16 GNU CC, but only under the conditions described in the
17 GNU CC General Public License.   A copy of this license is
18 supposed to have been given to you along with GNU CC so you
19 can know your rights and responsibilities.  It should be in a
20 file named COPYING.  Among other things, the copyright notice
21 and this notice must be preserved on all copies.
22 */
23 
24 
25 #ifndef _Obstack_h
26 #ifdef __GNUG__
27 #pragma once
28 #pragma interface
29 #endif
30 #define _Obstack_h 1
31 
32 #include <std.h>
33 
34 class Obstack
35 {
36   struct _obstack_chunk
37   {
38     char*           limit;
39     _obstack_chunk* prev;
40     char            contents[4];
41   };
42 
43 protected:
44   long	          chunksize;
45   _obstack_chunk* chunk;
46   char*	          objectbase;
47   char*	          nextfree;
48   char*	          chunklimit;
49   int             alignmentmask;
50 
51   void  _free(void* obj);
52   void  newchunk(int size);
53 
54 public:
55         Obstack(int size = 4080, int alignment = 4); // 4080=4096-mallocslop
56 
57         ~Obstack();
58 
59   void* base();
60   void* next_free();
61   int   alignment_mask();
62   int   chunk_size();
63   int   size();
64   int   room();
65   int   contains(void* p);      // does Obstack hold pointer p?
66 
67   void  grow(const void* data, int size);
68   void  grow(const void* data, int size, char terminator);
69   void  grow(const char* s);
70   void  grow(char c);
71   void  grow_fast(char c);
72   void  blank(int size);
73   void  blank_fast(int size);
74 
75   void* finish();
76   void* finish(char terminator);
77 
78   void* copy(const void* data, int size);
79   void* copy(const void* data, int size, char terminator);
80   void* copy(const char* s);
81   void* copy(char c);
82   void* alloc(int size);
83 
84   void  free(void* obj);
85   void  shrink(int size = 1); // suggested by ken@cs.rochester.edu
86 
87   int   OK();                   // rep invariant
88 };
89 
90 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
91 
92 
~Obstack()93 inline Obstack::~Obstack()
94 {
95   _free(0);
96 }
97 
base()98 inline void* Obstack::base()
99 {
100   return objectbase;
101 }
102 
next_free()103 inline void* Obstack::next_free()
104 {
105   return nextfree;
106 }
107 
alignment_mask()108 inline int Obstack::alignment_mask()
109 {
110   return alignmentmask;
111 }
112 
chunk_size()113 inline int Obstack::chunk_size()
114 {
115   return chunksize;
116 }
117 
size()118 inline int Obstack::size()
119 {
120   return nextfree - objectbase;
121 }
122 
room()123 inline int Obstack::room()
124 {
125   return chunklimit - nextfree;
126 }
127 
grow(const void * data,int size)128 inline void Obstack:: grow(const void* data, int size)
129 {
130   if (nextfree+size > chunklimit)
131     newchunk(size);
132   bcopy(data, nextfree, size);
133   nextfree += size;
134 }
135 
grow(const void * data,int size,char terminator)136 inline void Obstack:: grow(const void* data, int size, char terminator)
137 {
138   if (nextfree+size+1 > chunklimit)
139     newchunk(size+1);
140   bcopy(data, nextfree, size);
141   nextfree += size;
142   *(nextfree)++ = terminator;
143 }
144 
grow(const char * s)145 inline void Obstack:: grow(const char* s)
146 {
147   grow((void*)s, strlen(s), 0);
148 }
149 
grow(char c)150 inline void Obstack:: grow(char c)
151 {
152   if (nextfree+1 > chunklimit)
153     newchunk(1);
154   *(nextfree)++ = c;
155 }
156 
blank(int size)157 inline void Obstack:: blank(int size)
158 {
159   if (nextfree+size > chunklimit)
160     newchunk(size);
161   nextfree += size;
162 }
163 
finish(char terminator)164 inline void* Obstack::finish(char terminator)
165 {
166   grow(terminator);
167   return finish();
168 }
169 
copy(const void * data,int size)170 inline void* Obstack::copy(const void* data, int size)
171 {
172   grow (data, size);
173   return finish();
174 }
175 
copy(const void * data,int size,char terminator)176 inline void* Obstack::copy(const void* data, int size, char terminator)
177 {
178   grow(data, size, terminator);
179   return finish();
180 }
181 
copy(const char * s)182 inline void* Obstack::copy(const char* s)
183 {
184   grow((void*)s, strlen(s), 0);
185   return finish();
186 }
187 
copy(char c)188 inline void* Obstack::copy(char c)
189 {
190   grow(c);
191   return finish();
192 }
193 
alloc(int size)194 inline void* Obstack::alloc(int size)
195 {
196   blank(size);
197   return finish();
198 }
199 
free(void * obj)200 inline void Obstack:: free(void* obj)
201 {
202   if (obj >= (void*)chunk && obj<(void*)chunklimit)
203     nextfree = objectbase = (char *) obj;
204   else
205     _free(obj);
206 }
207 
grow_fast(char c)208 inline void Obstack:: grow_fast(char c)
209 {
210   *(nextfree)++ = c;
211 }
212 
blank_fast(int size)213 inline void Obstack:: blank_fast(int size)
214 {
215   nextfree += size;
216 }
217 
shrink(int size)218 inline void Obstack:: shrink(int size) // from ken@cs.rochester.edu
219 {
220   if (nextfree >= objectbase + size)
221     nextfree -= size;
222 }
223 
224 #endif
225 
226 #endif
227