Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

array.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*
00002  *                                   IT++                                    *
00003  *---------------------------------------------------------------------------*
00004  * Copyright (c) 1995-2002 by Tony Ottosson, Thomas Eriksson, Pål Frenger,   *
00005  * Tobias Ringström, and Jonas Samuelsson.                                   *
00006  *                                                                           *
00007  * Permission to use, copy, modify, and distribute this software and its     *
00008  * documentation under the terms of the GNU General Public License is hereby *
00009  * granted. No representations are made about the suitability of this        *
00010  * software for any purpose. It is provided "as is" without expressed or     *
00011  * implied warranty. See the GNU General Public License for more details.    *
00012  *---------------------------------------------------------------------------*/
00016 //  SPUC - Signal processing using C++ - A DSP library
00017 
00031 #ifndef __array_h
00032 #define __array_h
00033 
00034 #include <spucconfig.h>
00035 //#include <spucassert.h>
00036 #include <iostream>
00037 namespace SPUC {
00060 template<class T>
00061 class Array {
00062  public:
00064   Array();
00066   Array(int n);
00068   Array(const Array<T> &a);
00070   virtual ~Array();
00071         
00073   T &operator()(int i) {
00074 //    it_assert0(i>=0&&i<ndata,"Array::operator()"); 
00075           return data[i]; }
00077   T operator()(int i) const {
00078     //it_assert0(i>=0&&i<ndata,"Array::operator()");
00079           return data[i]; }
00081   Array<T> operator()(int i1, int i2) const;
00083   Array<T> operator()(const Array<int> &indices) const;
00084   
00086   void operator=(T e);
00088   void operator=(const Array<T> &a);
00089         
00091   //  friend Array<T> concat TEMPLATE_FUN(const Array<T> &a1, const T e);
00093   //  friend Array<T> concat TEMPLATE_FUN(const T e, const Array<T> &a);
00095   //  friend Array<T> concat TEMPLATE_FUN(const Array<T> &a1,const Array<T> &a2);
00097   //  friend Array<T> concat TEMPLATE_FUN(const Array<T> &a1, const Array<T> &a2, const Array<T> &a3);
00098 
00100   int size() const { return ndata; }
00102   int length() const { return ndata; }
00104   void set_size(int n, bool copy=false);
00106   void set_length(int n, bool copy=false) { set_size(n, copy); }
00107 
00109   T shift_right(T e);
00111   Array<T> shift_right(const Array<T> &a);
00113   T shift_left(T e);
00115   Array<T> shift_left(const Array<T> &a);
00117   void swap(int i, int j);
00118 
00120   void set_subarray(int i1, int i2, const Array<T> &a);
00122   void set_subarray(int i1, int i2, const T t);
00123 
00124 //protected:
00125  private:
00126   bool in_range(int i) { return ((i<ndata) && (i>=0)); }
00127   int ndata;
00128   T *data;
00129 
00130  private:
00131   void alloc(int n);
00132   void free();
00133 };
00134 
00135 // --------------------------- Implementation starts here ----------------------------------
00136 
00137 template<class T>
00138 Array<T>::Array()
00139 {
00140     data = 0;
00141     ndata = 0;
00142 }
00143 
00144 template<class T>
00145 Array<T>::Array(int n)
00146 {
00147     alloc(n);
00148 }
00149 
00150 template<class T>
00151 Array<T>::Array(const Array<T> &a)
00152 {
00153 
00154   data=NULL;
00155   ndata=0;
00156   alloc(a.ndata);
00157   for (int i=0; i<a.ndata; i++)
00158     data[i] = a.data[i];
00159 }
00160 
00161 template<class T>
00162 Array<T>::~Array()
00163 {
00164   free();
00165 }
00166 
00167 template<class T>
00168 void Array<T>::alloc(int n)
00169 {
00170   if (n == 0) {
00171     data = NULL;
00172     ndata = 0;
00173   }
00174   else {
00175     data = new T[n];
00176 //    it_assert1(data!=0, "Out of memory in Array::alloc");
00177   }
00178   ndata = n;
00179 }
00180 
00181 template<class T>
00182 void Array<T>::free()
00183 {
00184 
00185   delete [] data;
00186         
00187   data = 0;
00188   ndata = 0;
00189 }
00190 
00191 template<class T>
00192 Array<T> Array<T>::operator()(int i1, int i2) const
00193 {
00194         //    it_assert0(i1>=0 && i2>=0 && i1<ndata && i2<ndata && i2>=i1, "Array::operator()(i1,i2)");
00195     Array<T> s(i2-i1+1);
00196     int i;
00197         
00198     for (i=0; i<s.ndata; i++)
00199         s.data[i] = data[i1+i];
00200         
00201     return s;
00202 }
00203 
00204 template<class T>
00205 Array<T> Array<T>::operator()(const Array<int> &indices) const
00206 {
00207     Array<T> a(indices.size());
00208 
00209     for (int i=0; i<a.size(); i++) {
00210                 //      it_assert0(indices(i)>=0&&indices(i)<ndata,"Array::operator()(indicies)");
00211         a(i) = data[indices(i)];
00212     }
00213 
00214     return a;
00215 }
00216 
00217 template<class T>
00218 void Array<T>::operator=(const Array<T> &a)
00219 {
00220     set_size(a.ndata);
00221     for (int i=0; i<ndata; i++)
00222         data[i] = a.data[i];
00223 }
00224 
00225 
00226 template<class T>
00227 void Array<T>::operator=(T e)
00228 {
00229     for (int i=0; i<ndata; i++)
00230         data[i] = e;
00231 }
00232 
00233 
00234 template<class T>
00235 void Array<T>::set_size(int sz, bool copy)
00236 {
00237     int i, min;
00238     T *tmp;
00239 
00240     if (ndata == sz)
00241       return;
00242                 
00243     if (copy) {
00244       tmp = data;
00245       min = ndata < sz ? ndata : sz;
00246       alloc(sz);
00247       for (i=0; i<min; i++)
00248         data[i] = tmp[i];
00249       delete [] tmp;
00250     } else {
00251       free();
00252       alloc(sz);
00253     }
00254     ndata = sz;
00255 }
00256 
00257 template<class T>
00258 T Array<T>::shift_right(T x)
00259 {
00260     T ret;
00261 
00262         //    it_assert1(ndata>0, "shift_right");
00263     ret = data[ndata-1];
00264     for (int i=ndata-1; i>0; i--)
00265         data[i] = data[i-1];
00266     data[0] = x;
00267         
00268     return ret;
00269 }
00270 
00271 
00272 template<class T>
00273 Array<T> Array<T>::shift_right(const Array<T> &a)
00274 {
00275     int i;
00276     Array<T> out(a.ndata);
00277 
00278     it_assert1(a.ndata<=ndata, "Shift Array too large");
00279     for (i=0; i<a.ndata; i++)
00280         out.data[i] = data[ndata-a.ndata+i];
00281     for (i=ndata-1; i>=a.ndata; i--)
00282         data[i] = data[i-a.ndata];
00283     for (i=0; i<a.ndata; i++)
00284         data[i] = a.data[i];
00285         
00286     return out;
00287 }
00288 
00289 template<class T>
00290 T Array<T>::shift_left(T x)
00291 {
00292     T temp = data[0];
00293         
00294     for (int i=0; i<ndata-1; i++)
00295         data[i]=data[i+1];
00296     data[ndata-1] = x;
00297         
00298     return temp;
00299 }
00300 
00301 template<class T>
00302 Array<T> Array<T>::shift_left(const Array<T> &a)
00303 {
00304     int i;
00305     Array<T> out(a.ndata);
00306 
00307     it_assert1(a.ndata<=ndata, "Shift Array too large");
00308     for (i=0; i<a.ndata; i++)
00309         out.data[i] = data[i];
00310     for (i=0; i<ndata-a.ndata; i++) {
00311       // out.data[i] = data[i]; removed. Is not necessary
00312         data[i] = data[i+a.ndata];
00313     }
00314     for (i=ndata-a.ndata; i<ndata; i++)
00315         data[i] = a.data[i-ndata+a.ndata];
00316         
00317     return out;
00318 }
00319 
00320 template<class T>
00321 void Array<T>::swap(int i, int j)
00322 {
00323     it_assert1(in_range(i) && in_range(j) , "Shift Array too large");
00324     
00325     T temp = data[i];
00326     data[i] = data[j];
00327     data[j] = temp;
00328 }
00329 
00330 template<class T>
00331 void Array<T>::set_subarray(int i1, int i2, const Array<T> &a)
00332 {
00333   if (i1 == -1) i1 = ndata-1;
00334   if (i2 == -1) i2 = ndata-1;
00335   
00336   //  it_assert1(in_range(i1) && in_range(i2), "Array<T>::set_subarray(): indicies out of range");
00337   //  it_assert1(i2>=i1, "Array<T>::set_subarray(): i2 >= i1 necessary");
00338   //  it_assert1(i2-i1+1 == a.ndata, "Array<T>::set_subarray(): wrong sizes");
00339 
00340   memcpy(data+i1, a.data, a.ndata*sizeof(T));
00341 }
00342 
00343 template<class T>
00344 void Array<T>::set_subarray(int i1, int i2, const T t)
00345 {
00346   if (i1 == -1) i1 = ndata-1;
00347   if (i2 == -1) i2 = ndata-1;
00348   
00349   //  it_assert1(in_range(i1) && in_range(i2), "Array<T>::set_subarray(): indicies out of range");
00350   //  it_assert1(i2>=i1, "Array<T>::set_subarray(): i2 >= i1 necessary");
00351 
00352   for (int i=i1;i<=i2;i++)
00353     data[i] = t;
00354 }
00355 
00356 #ifndef DOXYGEN_SHOULD_SKIP_THIS 
00357 //Doxygen warnings on these functions
00358 
00359 template<class T>
00360 Array<T> concat(const Array<T> &a, const T e)
00361 {
00362     Array<T> temp(a.size()+1);
00363 
00364     for (int i=0; i<a.size(); i++)
00365         temp(i) = a(i);
00366     temp(a.size()) = e;
00367 
00368     return temp;
00369 }
00370 
00371 template<class T>
00372 Array<T> concat(const T e, const Array<T> &a)
00373 {
00374     Array<T> temp(a.size()+1);
00375 
00376     temp(0) = e;
00377 
00378     for (int i=0; i<a.size(); i++)
00379         temp(i+1) = a(i);
00380 
00381     return temp;
00382 }
00383 
00384 template<class T>
00385 Array<T> concat(const Array<T> &a1, const Array<T> &a2)
00386 {
00387     int i;
00388     Array<T> temp(a1.size()+a2.size());
00389 
00390     for (i=0;i<a1.size();i++) {
00391         temp(i) = a1(i);
00392     }
00393     for (i=0;i<a2.size();i++) {
00394         temp(a1.size()+i) = a2(i);
00395     }
00396     return temp;
00397 }
00398 
00399 template<class T>
00400 Array<T> concat(const Array<T> &a1, const Array<T> &a2, const Array<T> &a3)
00401 {
00402   // There should be some error control?
00403     int i;
00404     Array<T> temp(a1.size()+a2.size()+a3.size());
00405 
00406     for (i=0;i<a1.size();i++) {
00407         temp(i) = a1(i);
00408     }
00409     for (i=0;i<a2.size();i++) {
00410         temp(a1.size()+i) = a2(i);
00411     }
00412     for (i=0;i<a3.size();i++) {
00413         temp(a1.size()+a2.size()+i) = a3(i);
00414     }
00415     return temp;
00416 }
00417 
00418 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
00419 
00424 #ifdef XXX
00425 template<class T>
00426 inline std::ostream &operator<<(std::ostream &o, const Array<T> &a)
00427 {
00428   o << "{";
00429     for (int i=0; i<a.size()-1; i++)
00430         o << a(i) << " ";
00431     if (a.size() > 0)
00432         o << a(a.size()-1);
00433 
00434     o << "}";
00435 
00436     return o;
00437 }
00438 #endif
00439 } // namespace SPUC 
00440 
00441 #endif // __array_h

Generated on Fri Sep 16 11:02:28 2005 for spuc by  doxygen 1.4.4