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  *****************************************************************************/
00070 template<typename Type>
00071 class ECL_PUBLIC PushAndPop<Type,DynamicStorage>
00072 {
00073 public:
00074   typedef Type           value_type; 
00075   typedef Type*          iterator;   
00076   typedef const Type*    const_iterator;  
00077   typedef Type&          reference;  
00078   typedef const Type&    const_reference; 
00079   typedef std::size_t    size_type;  
00080   typedef std::ptrdiff_t difference_type;
00081   typedef std::reverse_iterator<iterator> reverse_iterator; 
00082   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;  
00083   typedef formatters::PushAndPopFormatter<Type,DynamicStorage> Formatter; 
00090   PushAndPop() : size_fifo(0), leader(0), follower(0) {}
00091 
00092   PushAndPop( const unsigned int length ) ecl_assert_throw_decl(StandardException)
00093   : size_fifo(length+1), leader(0), follower(0)
00094   {
00095     ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer"));
00096     data.resize( size_fifo );
00097   }
00098 
00099   PushAndPop( const unsigned int length, const Type & d ) ecl_assert_throw_decl(StandardException) :
00100   size_fifo(length+1),
00101   leader(0),
00102   follower(0)
00103   {
00104     ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer"));
00105     data.resize( size_fifo );
00106     fill( d );
00107   }
00108   virtual ~PushAndPop()
00109   {}
00110 
00111   /*********************
00112   ** Iterators
00113   **********************/
00114   /* ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! ACHTUNG! */
00115   /*
00116    * These have not been updated to take care with the push/pop, they just point to the
00117    * start and end of the underlying array!
00118    */
00125   iterator begin() ecl_assert_throw_decl(StandardException) {
00126     return data.begin(); // underlying array will throw if no storage has been allocated
00127   }
00134   const_iterator begin() const ecl_assert_throw_decl(StandardException) {
00135     return data.begin(); // underlying array will throw if no storage has been allocated
00136   }
00143   iterator end() ecl_assert_throw_decl(StandardException) {
00144     return data.end(); // underlying array will throw if no storage has been allocated
00145   }
00152   const_iterator end() const ecl_assert_throw_decl(StandardException) {
00153     return data.end(); // underlying array will throw if no storage has been allocated
00154   }
00161   reverse_iterator rbegin() ecl_assert_throw_decl(StandardException) {
00162     return reverse_iterator(end());
00163   }
00170   const_reverse_iterator rbegin() const ecl_assert_throw_decl(StandardException) {
00171     return const_reverse_iterator(end());
00172   }
00179   reverse_iterator rend() ecl_assert_throw_decl(StandardException) {
00180     return reverse_iterator(begin());
00181   }
00188   const_reverse_iterator rend() const ecl_assert_throw_decl(StandardException) {
00189     return const_reverse_iterator(begin());
00190   }
00191 
00192 
00193   /*********************
00194   ** Accessors
00195   **********************/
00196   // Cannot do stencils easily as push and pop roll over - not guaranteed of being contiguous
00197 
00198   Type & operator[] (int idx)
00199   {
00200     return data[ ((follower+idx)%size_fifo) ];
00201   }
00202 
00203   const Type & operator[] (int idx) const
00204   {
00205     return data[ ((follower+idx)%size_fifo) ];
00206   }
00207 
00208   void operator() (const PushAndPop<Type,0> & otherOne )
00209   {
00210     leader = otherOne.leader;
00211     follower = otherOne.follower;
00212     for( int i=0; i<size_fifo; i++ )
00213     {
00214       data[i] = otherOne.data[i];
00215     }
00216   }
00217 
00224   void push_back( const Type & datum )
00225   {
00226     data[ leader++ ] = datum;
00227     leader %= size_fifo;
00228     if( leader == follower )
00229     {
00230       follower++;
00231       follower %= size_fifo;
00232       // it just rolls over
00233     }
00234   }
00235 
00236   Type pop_front()
00237   {
00238     ecl_assert_throw( (follower != leader), StandardException(LOC, OutOfRangeError, "PushAndPop follower==leader"));
00239     Type value = data[follower++];
00240     follower %= size_fifo;
00241     return value;
00242   }
00243 
00244   void fill( const Type & d )
00245   {
00246     for( unsigned int i=0; i<size_fifo; i++ ) data[i] = d;
00247   }
00248 
00249   void resize( unsigned int length )
00250   {
00251     size_fifo = length+1;
00252     ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer"));
00253     data.resize( size_fifo );
00254   }
00255 
00263   unsigned int asize()
00264   {
00265     return size_fifo;
00266   }
00267 
00268   unsigned int size() const
00269   {
00270     if( leader > follower ) return leader - follower;
00271     else if( leader < follower ) return size_fifo-follower+leader;
00272     return 0;
00273   }
00274 
00275   void clear()
00276   {
00277     follower = 0;
00278     leader = 0;
00279   }
00280 
00281 //protected:
00282   ecl::Array <Type>data;
00283   unsigned int size_fifo;
00284   int leader;
00285   int follower;
00286 };
00287 
00288 } // namespace ecl
00289 
00290 #endif /* ECL_CONTAINERS_PUSH_AND_POP_DYNAMIC_HPP_ */


ecl_containers
Author(s): Daniel Stonier
autogenerated on Mon Jul 3 2017 02:21:42