push_and_pop_dynamic.hpp
Go to the documentation of this file.
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_ */


ecl_containers
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:25