00001 #pragma once
00002 #ifndef OPENGM_FAST_SEQUENCE_HXX
00003 #define OPENGM_FAST_SEQUENCE_HXX
00004
00005 #include <vector>
00006 #include <algorithm>
00007
00008 #include "opengm/opengm.hxx"
00009
00010 namespace opengm {
00011
00020 template<class T, size_t MAX_STACK=opengm::USUAL_MAX_FACTOR_ORDER>
00021 class FastSequence{
00022 public:
00023 typedef T ValueType;
00024 typedef T value_type;
00025 typedef T const * ConstIteratorType;
00026 typedef T const * const_iterator;
00027 typedef T* IteratorType;
00028 typedef T* iterator;
00029
00030 FastSequence( );
00031 FastSequence(const size_t );
00032 FastSequence(const size_t , const T & );
00033 FastSequence(const FastSequence<T, MAX_STACK> &);
00034 ~FastSequence( );
00035 FastSequence<T, MAX_STACK>& operator=(const FastSequence<T, MAX_STACK> &);
00036 template<class ITERATOR> void assign(ITERATOR , ITERATOR);
00037
00038 size_t size() const ;
00039 T const * begin() const;
00040 T const * end() const;
00041 T* const begin();
00042 T* const end();
00043 T const & operator[](const size_t) const;
00044 T& operator[](const size_t);
00045 void push_back(const T &);
00046 void resize(const size_t );
00047 void reserve(const size_t );
00048 void clear();
00049 bool empty() const;
00050 const T& front() const;
00051 const T& back() const;
00052 T& front();
00053 T& back();
00054
00055 private:
00056 size_t size_;
00057 size_t capacity_;
00058 T stackSequence_[MAX_STACK];
00059 T* pointerToSequence_;
00060 };
00061
00063 template<class T, size_t MAX_STACK>
00064 FastSequence<T, MAX_STACK>::FastSequence( )
00065 : size_(0),
00066 capacity_(MAX_STACK),
00067 pointerToSequence_(stackSequence_) {
00068
00069 }
00070
00073 template<class T, size_t MAX_STACK>
00074 FastSequence<T, MAX_STACK>::FastSequence
00075 (
00076 const size_t size
00077 )
00078 : size_(size),
00079 capacity_(size>MAX_STACK?size:MAX_STACK) {
00080 OPENGM_ASSERT(size_<=capacity_);
00081 OPENGM_ASSERT(capacity_>=MAX_STACK);
00082 if(size_>MAX_STACK) {
00083 pointerToSequence_ = new T[size];
00084 }
00085 else{
00086 pointerToSequence_=stackSequence_;
00087 }
00088 }
00089
00093 template<class T, size_t MAX_STACK>
00094 FastSequence<T, MAX_STACK>::FastSequence
00095 (
00096 const size_t size,
00097 const T & value
00098 )
00099 : size_(size),
00100 capacity_(size>MAX_STACK?size:MAX_STACK) {
00101 OPENGM_ASSERT(size_<=capacity_);
00102 OPENGM_ASSERT(capacity_>=MAX_STACK);
00103 if(size_>MAX_STACK) {
00104 pointerToSequence_ = new T[size_];
00105 }
00106 else{
00107 pointerToSequence_=stackSequence_;
00108 }
00109 std::fill(pointerToSequence_, pointerToSequence_+size_, value);
00110 }
00111
00114 template<class T, size_t MAX_STACK>
00115 FastSequence<T, MAX_STACK>::FastSequence
00116 (
00117 const FastSequence<T, MAX_STACK> & other
00118 )
00119 : size_(other.size_),
00120 capacity_(other.capacity_)
00121 {
00122 OPENGM_ASSERT(size_<=capacity_);
00123 OPENGM_ASSERT(capacity_>=MAX_STACK);
00124 if(size_>MAX_STACK) {
00125 pointerToSequence_ = new T[size_];
00126 }
00127 else{
00128 pointerToSequence_=stackSequence_;
00129 }
00130 std::copy(other.pointerToSequence_, other.pointerToSequence_+size_, pointerToSequence_);
00131 }
00132
00134 template<class T, size_t MAX_STACK>
00135 FastSequence<T, MAX_STACK>::~FastSequence( ) {
00136 if(size_>MAX_STACK) {
00137 OPENGM_ASSERT(pointerToSequence_!=NULL);
00138 delete[] pointerToSequence_;
00139 }
00140 }
00141
00144 template<class T, size_t MAX_STACK>
00145 FastSequence<T, MAX_STACK> & FastSequence<T, MAX_STACK>::operator=
00146 (
00147 const FastSequence<T, MAX_STACK> & other
00148 )
00149 {
00150 if(&other != this) {
00151
00152
00153
00154
00155 if(other.size_>MAX_STACK) {
00156
00157 if(size_>MAX_STACK) {
00158 delete [] pointerToSequence_;
00159 pointerToSequence_ = new T[other.size_];
00160 }
00161
00162 else{
00163 pointerToSequence_ = new T[other.size_];
00164 }
00165 size_=other.size_;
00166 capacity_=size_;
00167 }
00168 else{
00169 pointerToSequence_=stackSequence_;
00170 size_=other.size_;
00171 }
00172 std::copy(other.pointerToSequence_, other.pointerToSequence_+size_, pointerToSequence_);
00173 }
00174 return *this;
00175 }
00176
00178 template<class T, size_t MAX_STACK>
00179 inline size_t
00180 FastSequence<T, MAX_STACK>::size() const {
00181 OPENGM_ASSERT(pointerToSequence_!=NULL ||size_== 0 );
00182 return size_;
00183 }
00184
00186 template<class T, size_t MAX_STACK>
00187 inline T const *
00188 FastSequence<T, MAX_STACK>::begin() const{
00189 OPENGM_ASSERT(pointerToSequence_!=NULL);
00190 return pointerToSequence_;
00191 }
00192
00194 template<class T, size_t MAX_STACK>
00195 inline T const *
00196 FastSequence<T, MAX_STACK>::end() const{
00197 OPENGM_ASSERT(pointerToSequence_!=NULL);
00198 return pointerToSequence_ + size_;
00199 }
00200
00202 template<class T, size_t MAX_STACK>
00203 inline T * const
00204 FastSequence<T, MAX_STACK>::begin() {
00205 OPENGM_ASSERT(pointerToSequence_!=NULL);
00206 return pointerToSequence_;
00207 }
00208
00210 template<class T, size_t MAX_STACK>
00211 inline T * const
00212 FastSequence<T, MAX_STACK>::end() {
00213 OPENGM_ASSERT(pointerToSequence_!=NULL);
00214 return pointerToSequence_ + size_;
00215 }
00216
00218 template<class T, size_t MAX_STACK>
00219 inline T const &
00220 FastSequence<T, MAX_STACK>::operator[]
00221 (
00222 const size_t index
00223 ) const {
00224 OPENGM_ASSERT(pointerToSequence_!=NULL);
00225 OPENGM_ASSERT(index<size_);
00226 return pointerToSequence_[index];
00227 }
00228
00230 template<class T, size_t MAX_STACK>
00231 inline T &
00232 FastSequence<T, MAX_STACK>::operator[]
00233 (
00234 const size_t index
00235 ) {
00236 OPENGM_ASSERT(index<size_);
00237 return pointerToSequence_[index];
00238 }
00239
00242 template<class T, size_t MAX_STACK>
00243 inline void
00244 FastSequence<T, MAX_STACK>::push_back
00245 (
00246 const T & value
00247 ) {
00248 OPENGM_ASSERT(capacity_ >= MAX_STACK);
00249 OPENGM_ASSERT(size_ <= capacity_);
00250 if(capacity_ == size_) {
00251 T * tmp=new T[capacity_ * 2];
00252 std::copy(pointerToSequence_, pointerToSequence_ + size_, tmp);
00253 if(capacity_ > MAX_STACK) {
00254 delete[] pointerToSequence_;
00255 }
00256 capacity_ *= 2;
00257 pointerToSequence_ = tmp;
00258 }
00259 pointerToSequence_[size_]=value;
00260 ++size_;
00261 OPENGM_ASSERT(size_<=capacity_);
00262 OPENGM_ASSERT(capacity_>=MAX_STACK);
00263 }
00264
00267 template<class T, size_t MAX_STACK>
00268 inline void
00269 FastSequence<T, MAX_STACK>::resize
00270 (
00271 const size_t size
00272 ) {
00273 OPENGM_ASSERT(capacity_>=MAX_STACK);
00274 OPENGM_ASSERT(size_<=capacity_);
00275 if(size>capacity_) {
00276 T * tmp=new T[size];
00277 std::copy(pointerToSequence_, pointerToSequence_+size_, tmp);
00278 if(capacity_>MAX_STACK) {
00279 delete[] pointerToSequence_;
00280 }
00281 capacity_=size;
00282 pointerToSequence_=tmp;
00283 }
00284 size_=size;
00285 OPENGM_ASSERT(size_<=capacity_);
00286 OPENGM_ASSERT(capacity_>=MAX_STACK);
00287 }
00288
00291 template<class T, size_t MAX_STACK>
00292 inline void
00293 FastSequence<T, MAX_STACK>::reserve
00294 (
00295 const size_t size
00296 ) {
00297 OPENGM_ASSERT(capacity_>=MAX_STACK);
00298 OPENGM_ASSERT(size_<=capacity_);
00299 if(size>capacity_) {
00300 T * tmp=new T[size];
00301 std::copy(pointerToSequence_, pointerToSequence_+size_, tmp);
00302 if(capacity_>MAX_STACK) {
00303 delete[] pointerToSequence_;
00304 }
00305 capacity_=size;
00306 pointerToSequence_=tmp;
00307 }
00308
00309 OPENGM_ASSERT(size_<=capacity_);
00310 OPENGM_ASSERT(capacity_>=MAX_STACK);
00311 }
00312
00314 template<class T, size_t MAX_STACK>
00315 inline void
00316 FastSequence<T, MAX_STACK>::clear() {
00317 OPENGM_ASSERT(capacity_>=MAX_STACK);
00318 OPENGM_ASSERT(size_<=capacity_);
00319 if(capacity_>MAX_STACK) {
00320 delete[] pointerToSequence_;
00321 }
00322 pointerToSequence_=stackSequence_;
00323 capacity_=MAX_STACK;
00324 size_=0;
00325 OPENGM_ASSERT(size_<=capacity_);
00326 OPENGM_ASSERT(capacity_>=MAX_STACK);
00327 }
00328
00330 template<class T, size_t MAX_STACK>
00331 inline bool
00332 FastSequence<T, MAX_STACK>::empty() const {
00333 return (size_ == 0);
00334 }
00335
00339 template<class T, size_t MAX_STACK>
00340 template<class ITERATOR>
00341 inline void
00342 FastSequence<T, MAX_STACK>::assign(ITERATOR begin, ITERATOR end) {
00343 this->resize(std::distance(begin, end));
00344 std::copy(begin, end, pointerToSequence_);
00345 }
00346
00348 template<class T, size_t MAX_STACK>
00349 inline const T &
00350 FastSequence<T, MAX_STACK>::back()const{
00351 return pointerToSequence_[size_-1];
00352 }
00353
00355 template<class T, size_t MAX_STACK>
00356 inline T &
00357 FastSequence<T, MAX_STACK>::back() {
00358 return pointerToSequence_[size_-1];
00359 }
00360
00362 template<class T, size_t MAX_STACK>
00363 inline const T &
00364 FastSequence<T, MAX_STACK>::front()const{
00365 return pointerToSequence_[0];
00366 }
00367
00369 template<class T, size_t MAX_STACK>
00370 inline T &
00371 FastSequence<T, MAX_STACK>::front() {
00372 return pointerToSequence_[0];
00373 }
00374
00375 }
00376
00377 #endif // OPENGM_FAST_SEQUENCE_HXX