$search
00001 00011 /***************************************************************************** 00012 ** Ifdefs 00013 *****************************************************************************/ 00014 00015 #ifndef ECL_CONTAINERS_PUSH_AND_POP_FIXED_HPP_ 00016 #define ECL_CONTAINERS_PUSH_AND_POP_FIXED_HPP_ 00017 00018 /***************************************************************************** 00019 ** Includes 00020 *****************************************************************************/ 00021 00022 #include <iostream> //showMe 00023 #include <algorithm> // std::copy 00024 #include <ecl/config/macros.hpp> 00025 #include <ecl/errors/compile_time_assert.hpp> 00026 #include <ecl/exceptions/standard_exception.hpp> 00027 #include "../array.hpp" 00028 00029 /***************************************************************************** 00030 ** Namespaces 00031 *****************************************************************************/ 00032 00033 namespace ecl { 00034 00035 /***************************************************************************** 00036 ** Interface 00037 *****************************************************************************/ 00059 template<typename T, std::size_t Size=DynamicStorage> 00060 class ECL_PUBLIC PushAndPop 00061 { 00062 public: 00063 PushAndPop() 00064 : 00065 size_fifo(Size+1), 00066 leader(0), 00067 follower(0) 00068 { 00069 } 00070 00071 PushAndPop( const T & d ) ecl_assert_throw_decl(StandardException) 00072 : 00073 size_fifo(Size+1), 00074 leader(0), 00075 follower(0) 00076 { 00077 ecl_assert_throw( (size_fifo>0), StandardException(LOC, OutOfRangeError, "SimpleFIFO start with zero size buffer")); 00078 fill( d ); 00079 } 00080 virtual ~PushAndPop() {} 00081 00082 T & operator[] (int idx) 00083 { 00084 return data[ ((follower+idx)%size_fifo) ]; 00085 } 00086 00087 const T & operator[] (int idx) const 00088 { 00089 return data[ ((follower+idx)%size_fifo) ]; 00090 } 00091 00092 void operator() (const PushAndPop<T,Size> & otherOne ) 00093 { 00094 leader = otherOne.leader; 00095 follower = otherOne.follower; 00096 for( int i=0; i<size_fifo; i++ ) 00097 { 00098 data[i] = otherOne.data[i]; 00099 } 00100 } 00101 00102 void push_back( const T & datum ) 00103 { 00104 data[ leader++ ] = datum; 00105 leader %= size_fifo; 00106 if( leader == follower ) 00107 { 00108 follower++; 00109 follower %= size_fifo; 00110 //std::cout << "PushAndPop::push_back : exceeds maximum size, follower catch the leader " << std::endl; 00111 } 00112 } 00113 00114 T pop_front() 00115 { 00116 ecl_assert_throw( (follower != leader), StandardException(LOC, OutOfRangeError, "PushAndPop follower==leader")); 00117 T value = data[follower++]; 00118 follower %= size_fifo; 00119 return value; 00120 } 00121 00122 void fill( const T & d ) 00123 { 00124 for( unsigned int i=0; i<size_fifo; i++ ) data[i] = d; 00125 } 00126 00132 unsigned int asize() 00133 { 00134 return size_fifo; 00135 } 00136 00137 unsigned int size() const 00138 { 00139 if( leader > follower ) return leader - follower; 00140 else if( leader < follower ) return size_fifo-follower+leader; 00141 return 0; 00142 } 00143 00144 void clear() 00145 { 00146 follower = 0; 00147 leader = 0; 00148 } 00149 00150 void showMe() 00151 { 00152 std::cout << "[Size|Leader|Follower]: " << size_fifo << "|" << leader << "|" << follower << std::endl; 00153 } 00154 00155 private: 00156 ecl::Array <T,Size+1>data; 00157 unsigned int size_fifo; 00158 int leader; 00159 int follower; 00160 }; 00161 00162 00163 00164 } // namespace ecl 00165 00166 #endif /* ECL_CONTAINERS_PUSH_AND_POP_HPP_ */