00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef STACKFRAMEVECTOR_H
00037 #define STACKFRAMEVECTOR_H
00038
00039 #include <vector>
00040 #include <ostream>
00041
00042 template <class T>
00043 class StackFrameVector
00044 {
00045 public:
00046
00047
00048 typedef std::vector<T> BufferType;
00049
00050
00051
00052 typedef typename BufferType::reference reference;
00053 typedef typename BufferType::const_reference const_reference;
00054 typedef typename BufferType::iterator iterator;
00055 typedef typename BufferType::const_iterator const_iterator;
00056 typedef typename BufferType::size_type size_type;
00057 typedef typename BufferType::difference_type difference_type;
00058 typedef typename BufferType::value_type value_type;
00059 typedef typename BufferType::allocator_type allocator_type;
00060 typedef typename BufferType::pointer pointer;
00061 typedef typename BufferType::const_pointer const_pointer;
00062 typedef typename BufferType::reverse_iterator reverse_iterator;
00063 typedef typename BufferType::const_reverse_iterator const_reverse_iterator;
00064
00065
00066
00067 StackFrameVector();
00068 StackFrameVector(const StackFrameVector &);
00069 StackFrameVector(size_type n);
00070 StackFrameVector(size_type n, value_type initValue);
00071
00072 ~StackFrameVector();
00073
00074
00075
00076 StackFrameVector *deepCopy() const;
00077
00078
00079 iterator begin();
00080 const_iterator begin() const;
00081 iterator end();
00082 const_iterator end() const;
00083 reverse_iterator rbegin();
00084 const_reverse_iterator rbegin() const;
00085 reverse_iterator rend();
00086 const_reverse_iterator rend() const;
00087
00088
00089
00090
00091
00092
00093 size_type size() const;
00094 size_type max_size() const;
00095 size_type capacity() const;
00096 bool empty() const;
00097
00098
00099 reference operator[](size_type);
00100 const_reference operator[](size_type) const;
00101 reference at(size_type);
00102 const_reference at(size_type) const;
00103 reference front();
00104 const_reference front() const;
00105 reference back();
00106 const_reference back() const;
00107
00108
00109
00110 operator std::vector<T>();
00111
00112
00113
00114 void push(const T &);
00115 void setFrameSize(difference_type);
00116
00117
00118
00119 size_type debugSize() const;
00120
00121
00122
00123
00124
00125
00126 void resetStack();
00127
00128
00129
00130
00131 value_type pop();
00132
00133
00134 void debugDump(std::ostream &s);
00135
00136 protected:
00137
00138 BufferType *buffer;
00139
00140
00141 iterator framePtr, stackPtr;
00142
00143
00144
00145 bool deleteBufferWhenDone;
00146
00147 private:
00148 explicit StackFrameVector(const BufferType &otherBuffer, difference_type framePtrOffset);
00149 };
00150
00151
00152
00153
00154 template <class T>
00155 StackFrameVector<T>::StackFrameVector()
00156 : buffer(new BufferType()),
00157 framePtr(buffer->begin()),
00158 stackPtr(buffer->end()),
00159 deleteBufferWhenDone(true)
00160 {
00161 }
00162
00163 template <class T>
00164 StackFrameVector<T>::StackFrameVector(const StackFrameVector<T> &v)
00165 : buffer(NULL),
00166 framePtr(v.framePtr),
00167 stackPtr(v.stackPtr),
00168 deleteBufferWhenDone(false)
00169 {
00170 }
00171
00172 template <class T>
00173 StackFrameVector<T>::StackFrameVector(
00174 typename StackFrameVector<T>::size_type n)
00175 : buffer(new BufferType(n)),
00176 framePtr(buffer->begin()),
00177 stackPtr(buffer->end()),
00178 deleteBufferWhenDone(true)
00179 {
00180 }
00181
00182 template <class T>
00183 StackFrameVector<T>::StackFrameVector(
00184 typename StackFrameVector<T>::size_type n,
00185 typename StackFrameVector<T>::value_type initValue)
00186 : buffer(new BufferType(n, initValue)),
00187 framePtr(buffer->begin()),
00188 stackPtr(buffer->end()),
00189 deleteBufferWhenDone(true)
00190 {
00191 }
00192
00193 template <class T>
00194 StackFrameVector<T>::StackFrameVector(
00195 const typename StackFrameVector<T>::BufferType &otherBuffer,
00196 typename StackFrameVector<T>::difference_type framePtrOffset)
00197 : buffer(new BufferType(otherBuffer)),
00198 framePtr(buffer->begin() + framePtrOffset),
00199 stackPtr(buffer->end()),
00200 deleteBufferWhenDone(true)
00201 {
00202 }
00203
00204 template <class T>
00205 StackFrameVector<T>::~StackFrameVector()
00206 {
00207 ROSE_ASSERT(deleteBufferWhenDone == (buffer != NULL));
00208 if (deleteBufferWhenDone)
00209 {
00210 delete buffer;
00211 buffer = NULL;
00212 }
00213 }
00214
00215 template <class T>
00216 StackFrameVector<T> *
00217 StackFrameVector<T>::deepCopy() const
00218 {
00219
00220
00221
00222
00223 return new StackFrameVector(BufferType(buffer->begin(), stackPtr), framePtr - buffer->begin());
00224 }
00225
00226 template <class T>
00227 typename StackFrameVector<T>::iterator
00228 StackFrameVector<T>::begin()
00229 {
00230 return framePtr;
00231 }
00232
00233 template <class T>
00234 typename StackFrameVector<T>::const_iterator
00235 StackFrameVector<T>::begin() const
00236 {
00237 return framePtr;
00238 }
00239
00240 template <class T>
00241 typename StackFrameVector<T>::iterator
00242 StackFrameVector<T>::end()
00243 {
00244 return stackPtr;
00245 }
00246
00247 template <class T>
00248 typename StackFrameVector<T>::const_iterator
00249 StackFrameVector<T>::end() const
00250 {
00251 return stackPtr;
00252 }
00253
00254 template <class T>
00255 typename StackFrameVector<T>::reverse_iterator
00256 StackFrameVector<T>::rbegin()
00257 {
00258 return reverse_iterator(end());
00259 }
00260
00261 template <class T>
00262 typename StackFrameVector<T>::const_reverse_iterator
00263 StackFrameVector<T>::rbegin() const
00264 {
00265 return reverse_iterator(end());
00266 }
00267
00268 template <class T>
00269 typename StackFrameVector<T>::reverse_iterator
00270 StackFrameVector<T>::rend()
00271 {
00272 return reverse_iterator(begin());
00273 }
00274
00275 template <class T>
00276 typename StackFrameVector<T>::const_reverse_iterator
00277 StackFrameVector<T>::rend() const
00278 {
00279 return reverse_iterator(begin());
00280 }
00281
00282 template <class T>
00283 typename StackFrameVector<T>::size_type
00284 StackFrameVector<T>::size() const
00285 {
00286 return end() - begin();
00287 }
00288
00289 template <class T>
00290 typename StackFrameVector<T>::size_type
00291 StackFrameVector<T>::max_size() const
00292 {
00293 return size();
00294 }
00295
00296 template <class T>
00297 typename StackFrameVector<T>::size_type
00298 StackFrameVector<T>::capacity() const
00299 {
00300 return size();
00301 }
00302
00303 template <class T>
00304 bool
00305 StackFrameVector<T>::empty() const
00306 {
00307 return size() == 0;
00308 }
00309
00310 template <class T>
00311 typename StackFrameVector<T>::reference
00312 StackFrameVector<T>::operator[](typename StackFrameVector<T>::size_type n)
00313 {
00314 return framePtr[n];
00315 }
00316
00317 template <class T>
00318 typename StackFrameVector<T>::const_reference
00319 StackFrameVector<T>::operator[](typename StackFrameVector<T>::size_type n) const
00320 {
00321 return framePtr[n];
00322 }
00323
00324 #include <stdexcept>
00325
00326 template <class T>
00327 typename StackFrameVector<T>::reference
00328 StackFrameVector<T>::at(typename StackFrameVector<T>::size_type n)
00329 {
00330 if (n >= size())
00331 throw std::out_of_range("StackFrameVector: index out of range");
00332 return (*this)[n];
00333 }
00334
00335 template <class T>
00336 typename StackFrameVector<T>::const_reference
00337 StackFrameVector<T>::at(typename StackFrameVector<T>::size_type n) const
00338 {
00339 if (n >= size())
00340 throw std::out_of_range("StackFrameVector: index out of range");
00341 return (*this)[n];
00342 }
00343
00344 template <class T>
00345 typename StackFrameVector<T>::reference
00346 StackFrameVector<T>::front()
00347 {
00348 return *framePtr;
00349 }
00350
00351 template <class T>
00352 typename StackFrameVector<T>::const_reference
00353 StackFrameVector<T>::front() const
00354 {
00355 return *framePtr;
00356 }
00357
00358 template <class T>
00359 typename StackFrameVector<T>::reference
00360 StackFrameVector<T>::back()
00361 {
00362 return *(stackPtr - 1);
00363 }
00364
00365 template <class T>
00366 typename StackFrameVector<T>::const_reference
00367 StackFrameVector<T>::back() const
00368 {
00369 return *(stackPtr - 1);
00370 }
00371
00372 template <class T>
00373 StackFrameVector<T>::operator std::vector<T>()
00374 {
00375
00376 return BufferType(begin(), end());
00377 }
00378
00379 template <class T>
00380 void
00381 StackFrameVector<T>::push(const T &x)
00382 {
00383 ROSE_ASSERT(buffer != NULL);
00384
00385 if (framePtr == buffer->end())
00386 {
00387 buffer->push_back(x);
00388
00389
00390 framePtr = stackPtr = buffer->end();
00391
00392
00393
00394
00395 }
00396 else
00397 {
00398 *framePtr++ = x;
00399 stackPtr = framePtr;
00400 }
00401 }
00402
00403 template <class T>
00404 void
00405 StackFrameVector<T>::setFrameSize(difference_type frameSize)
00406 {
00407
00408
00409
00410 framePtr = stackPtr - frameSize;
00411 }
00412
00413 template <class T>
00414 typename StackFrameVector<T>::size_type
00415 StackFrameVector<T>::debugSize() const
00416 {
00417 ROSE_ASSERT(buffer != NULL);
00418 return stackPtr - buffer->begin();
00419 }
00420
00421 template <class T>
00422 void
00423 StackFrameVector<T>::resetStack()
00424 {
00425 ROSE_ASSERT(buffer != NULL);
00426 framePtr = stackPtr = buffer->begin();
00427 }
00428
00429 template <class T>
00430 typename StackFrameVector<T>::value_type
00431 StackFrameVector<T>::pop()
00432 {
00433
00434
00435
00436
00437 --framePtr;
00438 return *--stackPtr;
00439 }
00440
00441 template <class T>
00442 void
00443 StackFrameVector<T>::debugDump(std::ostream &s)
00444 {
00445
00446 s << "\n"
00447 << "framePtr offset: " << framePtr - buffer->begin()
00448 << " stackPtr offset: " << stackPtr - buffer->begin()
00449 << " size: " << size()
00450 << " buffer size: " << buffer->size()
00451 << "\n";
00452 s << "buffer:" << "\n";
00453 const_iterator i;
00454 for (i = buffer->begin(); i != buffer->end(); ++i)
00455 s << (void *) *i << ' ';
00456 s << "\n" << "\n";
00457 }
00458
00459 #endif