Go to the documentation of this file.00001
00011
00012
00013
00014
00015 #ifndef ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_
00016 #define ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_
00017
00018
00019
00020
00021
00022 #include <ecl/config/macros.hpp>
00023 #include "push_and_pop_fixed.hpp"
00024
00025
00026
00027
00028
00029 namespace ecl
00030 {
00031
00032
00033
00034
00035
00036 namespace formatters {
00037
00038 template <typename Type, size_t N> class PushAndPopFormatter;
00039
00040 }
00041
00042
00043
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
00106
00113 iterator begin() ecl_assert_throw_decl(StandardException) {
00114 return data.begin();
00115 }
00122 const_iterator begin() const ecl_assert_throw_decl(StandardException) {
00123 return data.begin();
00124 }
00131 iterator end() ecl_assert_throw_decl(StandardException) {
00132 return data.end();
00133 }
00140 const_iterator end() const ecl_assert_throw_decl(StandardException) {
00141 return data.end();
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
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
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
00279 ecl::Array <Type>data;
00280 unsigned int size_fifo;
00281 int leader;
00282 int follower;
00283 };
00284
00285 }
00286
00287 #endif