QueueArray.h

00001 /*  _________________________________________________________________________
00002  *
00003  *  UTILIB: A utility library for developing portable C++ codes.
00004  *  Copyright (c) 2001, Sandia National Laboratories.
00005  *  This software is distributed under the GNU Lesser General Public License.
00006  *  For more information, see the README file in the top UTILIB directory.
00007  *  _________________________________________________________________________
00008  */
00009 
00010 //
00011 // QueueArray.h
00012 //
00020 #ifndef __QueueArray_h
00021 #define __QueueArray_h
00022 
00023 #ifdef __GNUC__
00024 #pragma interface
00025 #endif
00026 
00027 #ifdef NON_ANSI
00028 #include <iostream.h>
00029 #else
00030 #include <iostream>
00031 using namespace std;
00032 #endif
00033 
00034 #ifndef ANSI_HDRS
00035 #include <stddef.h>
00036 #include <stdlib.h>
00037 #else
00038 #include <cstddef>
00039 #include <cstdlib>
00040 #endif
00041 
00042 #include "_math.h"
00043 #include "BasicArray.h"
00044 #include "PackBuf.h"
00045 
00046 
00050 
00051 template <class T>
00052 class UTILIB_API QueueArray
00053 {
00054 public:
00055 
00057   QueueArray();
00059   virtual ~QueueArray() {}
00060 
00062   virtual T& top()
00063                 {
00064                 if (Len>0)
00065                    return Data[First];
00066                 ErrAbort("QueueArray::top -- Empty stack.");
00067                 return Data[0];
00068                 }
00070   virtual void add( const T& );
00072   virtual void remove( T& val );
00073 
00075   int empty() const
00076                 {return (Len == 0);}
00078   operator int() const
00079                 {return (Len > 0);}
00081   size_type len() const
00082                 {return Len;}
00083 
00085   void clear();
00086 
00088   void write(ostream& os) const;
00090   void read(istream& is);
00092   void write(PackBuffer& os) const;
00094   void read(UnPackBuffer& is);
00095 
00096 protected:
00097 
00099   size_type Len;
00101   size_type First;
00103   size_type Last;
00105   BasicArray<T> Data;
00107   BasicArray<size_t> next;
00108 
00109 };
00110 
00111 template <class T>
00112 inline UTILIB_API QueueArray<T>& operator>>(QueueArray<T>& list, T& val)
00113 {list.remove(val); return list;}
00114 
00115 template <class T>
00116 inline UTILIB_API QueueArray<T>& operator<<(QueueArray<T>& list, const T& val)
00117 {list.add(val); return list;}
00118 
00120 template <class T>
00121 inline UTILIB_API ostream& operator<<(ostream& output, const QueueArray<T>& set)
00122 { set.write(output); return(output); }
00123 
00125 template <class T>
00126 inline UTILIB_API istream& operator>>(istream& input, QueueArray<T>& set)
00127 { set.read(input); return(input); }
00128 
00130 template <class T>
00131 inline UTILIB_API PackBuffer& operator<<(PackBuffer& output, const QueueArray<T>& set)
00132 { set.write(output); return(output); }
00133 
00135 template <class T>
00136 inline UTILIB_API UnPackBuffer& operator>>(UnPackBuffer& input, QueueArray<T>& set){ set.read(input); return(input); }
00137 
00138 
00139 
00140 //
00141 // Note, we are using internal indeces that are 1-based, indexing into
00142 // zero based arrays.  This is because the smallest value that the 'next'
00143 // array can represent is zero.
00144 //
00145 template <class T>
00146 QueueArray<T>::QueueArray()
00147  : Len(0), First(1), Last(1)
00148 { Data.resize(10); next.resize(10); next[0] = 0;}
00149 
00150 
00151 template <class T>
00152 void QueueArray<T>::clear()
00153 {
00154 Len=0;
00155 First = 1;
00156 Last = 1;
00157 next[0] = 0;
00158 }
00159 
00160 
00161 template <class T>
00162 void QueueArray<T>::remove( T& Value )
00163 {
00164 if (Len == 0)
00165    ErrAbort("QueueArray<T>::remove -- empty list!");
00166 
00167 size_type curr = First;
00168 Value = Data[curr];
00169 
00170 //
00171 // Move the First pointer down the list
00172 //
00173 if (next[curr] == 0) {
00174    //
00175    // The 'next' value is empty, so return to initial conditions for
00176    // code.
00177    //
00178    Len=0;
00179    First = 1;
00180    Last = 1;
00181    }
00182 else {
00183    Len--;
00184    First = next[curr];
00185    }
00186 
00187 //
00188 // Setup the 'free list'
00189 //
00190 size_type tmp = next[0];
00191 next[0] = curr;
00192 next[curr] = tmp;
00193 }
00194 
00195 
00196 template <class T>
00197 void QueueArray<T>::add( const T& val )
00198 {
00199 Len++;
00200 size_type curr;
00201 if (next[0] == 0)
00202    curr = Len;
00203 else {
00204    //
00205    // Remove an element from the free list
00206    //
00207    curr = next[0];
00208    next[0] = next[curr];
00209    }
00210 if (Data.size() == curr) {
00211    Data.resize(curr + max((Data.size() / 10),(size_type)10));
00212    next.resize(curr + max((next.size() / 10),(size_type)10));
00213    }
00214 
00215 if (Len == 1)
00216    First = curr;
00217 next[curr] = 0;
00218 if (Len > 1)
00219    next[Last] = curr;
00220 Data[curr] = val;
00221 Last = curr;
00222 }
00223 
00224 
00225 template <class T>
00226 void QueueArray<T>::write(ostream& os) const
00227 {
00228 os << Len << " [ ";
00229 if (Len > 0) {
00230    size_type curr = First;
00231    os << Data[curr];
00232    for (size_type i=1; i<Len; i++) {
00233      curr = next[curr] ;
00234      os << ", " << Data[curr];
00235      }
00236    os << " ";
00237    }
00238 os << "]";
00239 }
00240 
00241 
00242 template <class T>
00243 void QueueArray<T>::read(istream& /*is*/)
00244 {
00245 }
00246 
00247 template <class T>
00248 void QueueArray<T>::write(PackBuffer& os) const
00249 {
00250 os << Len;
00251 size_type curr = First;
00252 for (size_type i=0; i<Len; i++) {
00253   os << Data[curr];
00254   curr = next[curr];
00255   }
00256 }
00257 
00258 
00259 template <class T>
00260 void QueueArray<T>::read(UnPackBuffer& is)
00261 {
00262 is >> Len;
00263 if (Data.len() <= (Len+1))
00264    Data.resize(max(1,(Len+1)));
00265 Len=0;
00266 First = 1;
00267 Last = 1;
00268 for (size_type i=0; i<Len; i++) {
00269   is >> Data[Len];
00270   add(Data[Len]);
00271   }
00272 }
00273 
00274 #endif