Use the new import feature of Ragel for bringing in defines from the parser
[ragel.git] / aapl / resize.h
blob24edc16ed8a33f12896b0a7130edea80ba644728
1 /*
2 * Copyright 2002 Adrian Thurston <thurston@cs.queensu.ca>
3 */
5 /* This file is part of Aapl.
7 * Aapl is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 2.1 of the License, or (at your option)
10 * any later version.
12 * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 * more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Aapl; if not, write to the Free Software Foundation, Inc., 59
19 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef _AAPL_RESIZE_H
23 #define _AAPL_RESIZE_H
25 #include <assert.h>
27 #ifdef AAPL_NAMESPACE
28 namespace Aapl {
29 #endif
31 /* This step is expressed in units of T. Changing this requires changes to
32 * docs in ResizeLin constructor. */
33 #define LIN_DEFAULT_STEP 256
36 * Resizing macros giving different resize methods.
39 /* If needed is greater than existing, give twice needed. */
40 #define EXPN_UP( existing, needed ) \
41 needed > existing ? (needed<<1) : existing
43 /* If needed is less than 1 quarter existing, give twice needed. */
44 #define EXPN_DOWN( existing, needed ) \
45 needed < (existing>>2) ? (needed<<1) : existing
47 /* If needed is greater than existing, give needed plus step. */
48 #define LIN_UP( existing, needed ) \
49 needed > existing ? (needed+step) : existing
51 /* If needed is less than existing - 2 * step then give needed plus step. */
52 #define LIN_DOWN( existing, needed ) \
53 needed < (existing-(step<<1)) ? (needed+step) : existing
55 /* Return existing. */
56 #define CONST_UP( existing, needed ) existing
58 /* Return existing. */
59 #define CONST_DOWN( existing, needed ) existing
61 /**
62 * \addtogroup vector
63 * @{
66 /** \class ResizeLin
67 * \brief Linear table resizer.
69 * When an up resize or a down resize is needed, ResizeLin allocates the space
70 * needed plus some user defined step. The result is that when growing the
71 * vector in a linear fashion, the number of resizes is also linear.
73 * If only up resizing is done, then there will never be more than step unused
74 * spaces in the vector. If down resizing is done as well, there will never be
75 * more than 2*step unused spaces in the vector. The up resizing and down
76 * resizing policies are offset to improve performance when repeatedly
77 * inserting and removing a small number of elements relative to the step.
78 * This scheme guarantees that repetitive inserting and removing of a small
79 * number of elements will never result in repetative reallocation.
81 * The vectors pass sizes to the resizer in units of T, so the step gets
82 * interpreted as units of T.
85 /*@}*/
87 /* Linear resizing. */
88 class ResizeLin
90 protected:
91 /**
92 * \brief Default constructor.
94 * Intializes resize step to 256 units of the table type T.
96 ResizeLin() : step(LIN_DEFAULT_STEP) { }
98 /**
99 * \brief Determine the new table size when up resizing.
101 * If the existing size is insufficient for the space needed, then allocate
102 * the space needed plus the step. The step is in units of T.
104 inline long upResize( long existing, long needed )
105 { return LIN_UP(existing, needed); }
108 * \brief Determine the new table size when down resizing.
110 * If space needed is less than the existing - 2*step, then allocate the
111 * space needed space plus the step. The step is in units of T.
113 inline long downResize( long existing, long needed )
114 { return LIN_DOWN(existing, needed); }
116 public:
118 * \brief Step for linear resize.
120 * Amount of extra space in units of T added each time a resize must take
121 * place. This may be changed at any time. The step should be >= 0.
123 long step;
127 * \addtogroup vector
128 * @{
131 /** \class ResizeCtLin
132 * \brief Linear table resizer with compile time step.
134 * When an up resize or a down resize is needed, ResizeCtLin allocates the
135 * space needed plus some compile time defined step. The result is that when
136 * growing the vector in a linear fashion, the number of resizes is also
137 * linear.
139 * If only up resizing is done, then there will never be more than step unused
140 * spaces in the vector. If down resizing is done as well, there will never be
141 * more than 2*step unused spaces in the vector. The up resizing and down
142 * resizing policies are offset to improve performance when repeatedly
143 * inserting and removing a small number of elements relative to the step.
144 * This scheme guarantees that repetitive inserting and removing of a small
145 * number of elements will never result in repetative reallocation.
147 * The vectors pass sizes to the resizer in units of T, so the step gets
148 * interpreted as units of T.
151 /*@}*/
153 /* Linear resizing. */
154 template <long step> class ResizeCtLin
156 protected:
158 * \brief Determine the new table size when up resizing.
160 * If the existing size is insufficient for the space needed, then allocate
161 * the space needed plus the step. The step is in units of T.
163 inline long upResize( long existing, long needed )
164 { return LIN_UP(existing, needed); }
167 * \brief Determine the new table size when down resizing.
169 * If space needed is less than the existing - 2*step, then allocate the
170 * space needed space plus the step. The step is in units of T.
172 inline long downResize( long existing, long needed )
173 { return LIN_DOWN(existing, needed); }
177 * \addtogroup vector
178 * @{
181 /** \class ResizeConst
182 * \brief Constant table resizer.
184 * When an up resize is needed the existing size is always used. ResizeConst
185 * does not allow dynamic resizing. To use ResizeConst, the vector needs to be
186 * constructed with and initial allocation amount otherwise it will be
187 * unusable.
190 /*@}*/
192 /* Constant table resizing. */
193 class ResizeConst
195 protected:
196 /* Assert don't need more than exists. Return existing. */
197 static inline long upResize( long existing, long needed );
200 * \brief Determine the new table size when down resizing.
202 * Always returns the existing table size.
204 static inline long downResize( long existing, long needed )
205 { return CONST_DOWN(existing, needed); }
209 * \brief Determine the new table size when up resizing.
211 * If the existing size is insufficient for the space needed, then an assertion
212 * will fail. Otherwise returns the existing size.
214 inline long ResizeConst::upResize( long existing, long needed )
216 assert( needed <= existing );
217 return CONST_UP(existing, needed);
221 * \addtogroup vector
222 * @{
225 /** \class ResizeRunTime
226 * \brief Run time settable table resizer.
228 * ResizeRunTime can have it's up and down resizing policies set at run time.
229 * Both up and down policies can be set independently to one of Exponential,
230 * Linear, or Constant. See the documentation for ResizeExpn, ResizeLin, and
231 * ResizeConst for the details of the resizing policies.
233 * The policies may be changed at any time. The default policies are
234 * both Exponential.
237 /*@}*/
239 /* Run time resizing. */
240 class ResizeRunTime
242 protected:
244 * \brief Default constuctor.
246 * The up and down resizing it initialized to Exponetial. The step
247 * defaults to 256 units of T.
249 inline ResizeRunTime();
252 * \brief Resizing policies.
254 enum ResizeType {
255 Exponential, /*!< Exponential resizing. */
256 Linear, /*!< Linear resizing. */
257 Constant /*!< Constant table size. */
260 inline long upResize( long existing, long needed );
261 inline long downResize( long existing, long needed );
263 public:
265 * \brief Step for linear resize.
267 * Amount of extra space in units of T added each time a resize must take
268 * place. This may be changed at any time. The step should be >= 0.
270 long step;
273 * \brief Up resizing policy.
275 ResizeType upResizeType;
278 * \brief Down resizing policy.
280 ResizeType downResizeType;
283 inline ResizeRunTime::ResizeRunTime()
285 step( LIN_DEFAULT_STEP ),
286 upResizeType( Exponential ),
287 downResizeType( Exponential )
292 * \brief Determine the new table size when up resizing.
294 * Type of up resizing is determined by upResizeType. Exponential, Linear and
295 * Constant resizing is the same as that of ResizeExpn, ResizeLin and
296 * ResizeConst.
298 inline long ResizeRunTime::upResize( long existing, long needed )
300 switch ( upResizeType ) {
301 case Exponential:
302 return EXPN_UP(existing, needed);
303 case Linear:
304 return LIN_UP(existing, needed);
305 case Constant:
306 assert( needed <= existing );
307 return CONST_UP(existing, needed);
309 return 0;
313 * \brief Determine the new table size when down resizing.
315 * Type of down resizing is determined by downResiizeType. Exponential, Linear
316 * and Constant resizing is the same as that of ResizeExpn, ResizeLin and
317 * ResizeConst.
319 inline long ResizeRunTime::downResize( long existing, long needed )
321 switch ( downResizeType ) {
322 case Exponential:
323 return EXPN_DOWN(existing, needed);
324 case Linear:
325 return LIN_DOWN(existing, needed);
326 case Constant:
327 return CONST_DOWN(existing, needed);
329 return 0;
332 /* Don't need these anymore. */
333 #undef EXPN_UP
334 #undef EXPN_DOWN
335 #undef LIN_UP
336 #undef LIN_DOWN
337 #undef CONST_UP
338 #undef CONST_DOWN
340 #ifdef AAPL_NAMESPACE
342 #endif
344 #endif /* _AAPL_RESIZE_H */