00001
00002
00010 #include <exception>
00011 #include <iostream>
00012
00013
00015 namespace std {}
00016
00017 template <class T> class test_deque;
00018
00026 template <class T>
00027 class deque {
00028 public:
00029 typedef typename T value_type;
00030 typedef typename T * pointer;
00031 typedef typename T & reference;
00032
00033 typedef typename const value_type const_value_type;
00034 typedef typename const T * const_pointer;
00035 typedef typename const T & const_reference;
00036
00037 typedef typename unsigned size_type;
00038
00040 deque( size_type N );
00041 ~deque() { if (m_vec != 0) { delete [] m_vec; } }
00042
00044 bool empty() const { return (size() == 0); }
00045
00047 size_type size() const { return m_size; }
00049 size_type capacity() const { return m_capacity; }
00050
00055 value_type& front() { return at_check(m_front); }
00056
00061 const value_type& front() const { return const_cast<deque*>(this)->front(); }
00062
00063
00068 value_type& back() { return at_check(m_front+m_size-1); }
00069
00074 const value_type& back() const { return const_cast<deque*>(this)->back(); }
00075
00078 value_type& operator[](size_type i) {
00079 size_type i_real = m_front + i;
00080 i_real = ( i_real < m_capacity ? i_real : i_real - m_capacity );
00081 return m_vec[ i_real ];
00082 }
00085 value_type& operator[](size_type i) const { return const_cast<deque*>(this)->operator[](i); }
00086
00089 value_type& at(size_type i) { return at_check(m_front+i); }
00092 value_type& at(size_type i) const { return const_cast<deque*>(this)->at(i); }
00093
00094 void push_front( const value_type& val );
00095 void push_back( const value_type& val );
00096 void pop_front();
00097 void pop_back();
00098
00099 template <class T> friend std::istream& operator>>( std::istream& CIN, deque<T>& Q);
00100 template <class T> friend std::ostream& operator<<( std::ostream& COUT, const deque<T>& Q);
00101 private:
00102 bool ok() const;
00103 inline friend bool check_ok( const deque<T>& Q) { return Q.ok(); }
00104 value_type& at_check(size_type i);
00105 explicit deque(const deque&);
00106
00107 template <class T> friend class test_deque;
00108 private:
00109 unsigned m_front;
00110 unsigned m_size;
00111 unsigned m_capacity;
00112 value_type * m_vec;
00113 };
00114
00115 template <class T>
00116 deque<T>::deque( size_type N ) : m_front(0), m_size(0), m_capacity(0), m_vec(0) {
00117 if (N == 0) {
00118 throw std::length_error("deque<T>::deque(0)");
00119 }
00120 else {
00121 try {
00122 m_capacity = N;
00123 m_vec = new value_type [ m_capacity ];
00124 }
00125 catch (std::bad_alloc) {
00126 throw;
00127 }
00128 }
00129 }
00130
00154 template <class T>
00155 T& deque<T>::at_check(size_type i) {
00156
00157 size_type i_real = ( i < m_capacity ? i : i - m_capacity );
00158 if ( (m_front <= i) && (i < m_front + m_size) ) {
00159 return m_vec[i_real];
00160 }
00161 else {
00162 throw std::out_of_range("deque<T>::at()");
00163 }
00164 }
00165
00170 template <class T>
00171 void deque<T>::push_back(const value_type& val) {
00172 if (m_size < m_capacity) {
00173 size_type i_real = m_front + m_size;
00174 i_real = (i_real < m_capacity ? i_real : i_real - m_capacity);
00175 m_vec[i_real] = val;
00176 m_size++;
00177 }
00178 else {
00179 throw std::out_of_range("deque<T>::push_back()");
00180 }
00181 }
00182
00187 template <class T>
00188 void deque<T>::push_front(const value_type& val) {
00189 if (m_size < m_capacity) {
00190 m_front = ( m_front>0 ? m_front-1 : m_capacity-1 );
00191 m_vec[m_front] = val;
00192 m_size++;
00193 }
00194 else {
00195 throw std::out_of_range("deque<T>::push_front()");
00196 }
00197 }
00202 template <class T>
00203 inline void deque<T>::pop_front() {
00204 if (m_size > 0) {
00205
00206 m_front++;
00207 m_size--;
00208 if (m_front >= m_capacity) {
00209 m_front = 0;
00210 }
00211
00212 }
00213 else {
00214 throw std::out_of_range("deque<T>::pop_front()");
00215 }
00216 }
00217
00222 template <class T>
00223 inline void deque<T>::pop_back() {
00224 if (m_size > 0) {
00225 m_size--;
00226 }
00227 else {
00228 throw std::out_of_range("deque<T>::pop_front()");
00229 }
00230 }
00231
00232 #if 0
00233
00234 template <class T>
00235 inline bool deque<T>::full() const {
00236 return (m_size == m_ capacity);
00237 }
00238 #endif
00239
00289 template <class T>
00290 bool check_ok( const deque<T>& Q);
00291
00308 template <class T>
00309 bool deque<T>::ok() const {
00310 if (this == 0) {
00312 return false;
00313 }
00314
00315 if ( ! (m_capacity > 0) ) {
00317 return false;
00318 }
00319 if ( ! (m_front < m_capacity) ) {
00321 return false;
00322 }
00323 if ( ! (m_size <= m_capacity) ) {
00325 return false;
00326 }
00327 if ( ! (size() <= m_capacity) ) {
00329 return false;
00330 }
00331 if ( ! (m_vec != 0) ) {
00333 return false;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343 bool check_ok( const deque<T>::value_type & );
00344
00345 for (unsigned i=0; i<m_capacity; ++i) {
00346 if ( ! check_ok( m_vec[i] ) ) {
00349 return false;
00350 }
00351 }
00352 return true;
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 }
00375
00376