$search
00001 00011 /***************************************************************************** 00012 ** Ifdefs 00013 *****************************************************************************/ 00014 00015 #ifndef ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_ 00016 #define ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_ 00017 00018 /***************************************************************************** 00019 ** Includes 00020 *****************************************************************************/ 00021 00022 #include <ecl/config/macros.hpp> 00023 #include "push_and_pop_fixed.hpp" 00024 00025 /***************************************************************************** 00026 ** Namespaces 00027 *****************************************************************************/ 00028 00029 namespace ecl 00030 { 00031 00032 /***************************************************************************** 00033 ** Forward Declarations 00034 *****************************************************************************/ 00035 00036 namespace formatters { 00037 00038 template <typename Type, size_t N> class PushAndPopFormatter; 00039 00040 } // namespace formatters 00041 00042 /***************************************************************************** 00043 ** Interface 00044 *****************************************************************************/ 00063 template<typename Type> 00064 class ECL_PUBLIC PushAndPop<Type,DynamicStorage> 00065 { 00066 public: 00067 typedef Type value_type; 00068 typedef Type* iterator; 00069 typedef const Type* const_iterator; 00070 typedef Type& reference; 00071 typedef const Type& const_reference; 00072 typedef std::size_t size_type; 00073 typedef std::ptrdiff_t difference_type; 00074 typedef std::reverse_iterator<iterator> reverse_iterator; 00075 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00076 typedef formatters::PushAndPopFormatter<Type,DynamicStorage> Formatter; 00083 PushAndPop() : size_fifo(0), leader(0), follower(0) {} 00084 00085 PushAndPop( const unsigned int length ) ecl_assert_throw_decl(StandardException) 00086 : size_fifo(length+1), leader(0), follower(0) 00087 { 00088 ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer")); 00089 data.resize( size_fifo ); 00090 } 00091 00092 PushAndPop( const unsigned int length, const Type & d ) ecl_assert_throw_decl(StandardException) : 00093 size_fifo(length+1), 00094 leader(0), 00095 follower(0) 00096 { 00097 ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer")); 00098 data.resize( size_fifo ); 00099 fill( d ); 00100 } 00101 virtual ~PushAndPop() 00102 {} 00103 00104 /********************* 00105 ** Iterators 00106 **********************/ 00113 iterator begin() ecl_assert_throw_decl(StandardException) { 00114 return data.begin(); // underlying array will throw if no storage has been allocated 00115 } 00122 const_iterator begin() const ecl_assert_throw_decl(StandardException) { 00123 return data.begin(); // underlying array will throw if no storage has been allocated 00124 } 00131 iterator end() ecl_assert_throw_decl(StandardException) { 00132 return data.end(); // underlying array will throw if no storage has been allocated 00133 } 00140 const_iterator end() const ecl_assert_throw_decl(StandardException) { 00141 return data.end(); // underlying array will throw if no storage has been allocated 00142 } 00149 reverse_iterator rbegin() ecl_assert_throw_decl(StandardException) { 00150 return reverse_iterator(end()); 00151 } 00158 const_reverse_iterator rbegin() const ecl_assert_throw_decl(StandardException) { 00159 return const_reverse_iterator(end()); 00160 } 00167 reverse_iterator rend() ecl_assert_throw_decl(StandardException) { 00168 return reverse_iterator(begin()); 00169 } 00176 const_reverse_iterator rend() const ecl_assert_throw_decl(StandardException) { 00177 return const_reverse_iterator(begin()); 00178 } 00179 00180 00181 /********************* 00182 ** Accessors 00183 **********************/ 00195 Stencil< PushAndPop<Type,DynamicStorage> > stencil(const unsigned int& start_index, const unsigned int& n) ecl_assert_throw_decl(StandardException) { 00196 ecl_assert_throw(start_index < size(), StandardException(LOC, OutOfRangeError, "Start index provided is larger than the underlying array size.")); 00197 ecl_assert_throw(start_index+n <= size(), StandardException(LOC, OutOfRangeError, "Finish index provided is larger than the underlying array size.")); 00198 return Stencil< PushAndPop<Type,DynamicStorage> >(*this, begin()+start_index, begin()+start_index+n); 00199 } 00200 00201 Type & operator[] (int idx) 00202 { 00203 return data[ ((follower+idx)%size_fifo) ]; 00204 } 00205 00206 const Type & operator[] (int idx) const 00207 { 00208 return data[ ((follower+idx)%size_fifo) ]; 00209 } 00210 00211 void operator() (const PushAndPop<Type,0> & otherOne ) 00212 { 00213 leader = otherOne.leader; 00214 follower = otherOne.follower; 00215 for( int i=0; i<size_fifo; i++ ) 00216 { 00217 data[i] = otherOne.data[i]; 00218 } 00219 } 00220 00221 void push_back( const Type & datum ) 00222 { 00223 data[ leader++ ] = datum; 00224 leader %= size_fifo; 00225 if( leader == follower ) 00226 { 00227 follower++; 00228 follower %= size_fifo; 00229 // it just rolls over 00230 } 00231 } 00232 00233 Type pop_front() 00234 { 00235 ecl_assert_throw( (follower != leader), StandardException(LOC, OutOfRangeError, "PushAndPop follower==leader")); 00236 Type value = data[follower++]; 00237 follower %= size_fifo; 00238 return value; 00239 } 00240 00241 void fill( const Type & d ) 00242 { 00243 for( unsigned int i=0; i<size_fifo; i++ ) data[i] = d; 00244 } 00245 00246 void resize( unsigned int length ) 00247 { 00248 size_fifo = length; 00249 ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer")); 00250 data.resize( size_fifo ); 00251 } 00252 00260 unsigned int asize() 00261 { 00262 return size_fifo; 00263 } 00264 00265 unsigned int size() const 00266 { 00267 if( leader > follower ) return leader - follower; 00268 else if( leader < follower ) return size_fifo-follower+leader; 00269 return 0; 00270 } 00271 00272 void clear() 00273 { 00274 follower = 0; 00275 leader = 0; 00276 } 00277 00278 //protected: 00279 ecl::Array <Type>data; 00280 unsigned int size_fifo; 00281 int leader; 00282 int follower; 00283 }; 00284 00285 } // namespace ecl 00286 00287 #endif /* ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_ */