uvector_tlate.h

Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_UVECTOR_TLATE_H
00024 #define O2SCL_UVECTOR_TLATE_H
00025 
00026 /** \file uvector_tlate.h
00027     \brief File for definitions of unit-stride vectors
00028 */
00029 
00030 #include <iostream>
00031 #include <cstdlib>
00032 #include <string>
00033 #include <fstream>
00034 #include <sstream>
00035 #include <vector>
00036 #include <o2scl/err_hnd.h>
00037 #include <o2scl/string_conv.h>
00038 #include <gsl/gsl_vector.h>
00039 
00040 #ifndef DOXYGENP
00041 namespace o2scl {
00042 #endif
00043 
00044   /** 
00045       \brief A vector view with unit stride
00046   */
00047   template<class data_t> class uvector_view_tlate {
00048     
00049 #ifndef DOXYGEN_INTERNAL
00050 
00051   protected:
00052 
00053     /// The data
00054     data_t *data;
00055     /// The vector sz
00056     size_t sz;
00057     /// Zero if memory is owned elsewhere, 1 otherwise
00058     int owner;
00059     
00060 #endif
00061 
00062   public:
00063 
00064     /// \name Copy constructors
00065     //@{
00066     /// Copy constructor - create a new view of the same vector
00067     uvector_view_tlate(const uvector_view_tlate &v) {
00068       data=v.data;
00069       sz=v.sz;
00070       owner=0;      
00071     }
00072     
00073     /// Copy constructor - create a new view of the same vector
00074     uvector_view_tlate& operator=(const uvector_view_tlate &v) {
00075       data=v.data;
00076       sz=v.sz;
00077       owner=0;      
00078 
00079       return *this;
00080     }
00081     //@}
00082 
00083     ~uvector_view_tlate() {};
00084     
00085     /// \name Get and set methods
00086     //@{
00087     /** 
00088         \brief Array-like indexing 
00089     */
00090     data_t &operator[](size_t i) {
00091 #if GSL_RANGE_CHECK
00092       if (i>=sz) {
00093         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00094                  +" in uvector_view_tlate::operator[]. Size: "+
00095                  itos(sz)+
00096                  " (index should be less than size).").c_str(),gsl_index);
00097         return data[0];
00098       }
00099 #endif
00100       return data[i];
00101     }
00102     
00103     /** 
00104         \brief Array-like indexing 
00105     */
00106     const data_t &operator[](size_t i) const {
00107 #if GSL_RANGE_CHECK
00108       if (i>=sz) {
00109         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00110                  +" in uvector_view_tlate::operator[] const. Size: "+
00111                  itos(sz)+
00112                  " (index should be less than size).").c_str(),gsl_index);
00113         return data[0];
00114       }
00115 #endif
00116       return data[i];
00117     }
00118     
00119     /** 
00120         \brief Array-like indexing 
00121     */
00122     data_t &operator()(size_t i) {
00123 #if GSL_RANGE_CHECK
00124       if (i>=sz) {
00125         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00126                  +" in uvector_view_tlate::operator(). Size: "+
00127                  itos(sz)+
00128                  " (index should be less than size).").c_str(),gsl_index);
00129         return data[0];
00130       }
00131 #endif
00132       return data[i];
00133     }
00134     
00135     /** 
00136         \brief Array-like indexing 
00137     */
00138     const data_t &operator()(size_t i) const {
00139 #if GSL_RANGE_CHECK
00140       if (i>=sz) {
00141         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00142                  +" in uvector_view_tlate::operator() const. Size: "+
00143                  itos(sz)+
00144                  " (index should be less than size).").c_str(),gsl_index);
00145         return data[0];
00146       }
00147 #endif
00148       return data[i];
00149     }
00150     
00151     /** \brief Get (with optional range-checking) */
00152     data_t get(size_t i) const {
00153 #if GSL_RANGE_CHECK
00154       if (i>=sz) {
00155         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00156                  +" in uvector_view_tlate::get(). Size: "+
00157                  itos(sz)+
00158                  " (index should be less than size).").c_str(),gsl_index);
00159         return data[0];
00160       }
00161 #endif
00162       return data[i];
00163     }
00164     
00165     /** \brief Get pointer (with optional range-checking) */
00166     data_t *get_ptr(size_t i) {
00167 #if GSL_RANGE_CHECK
00168       if (i>=sz) {
00169         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00170                  +" in uvector_view_tlate::get_ptr(). Size: "+
00171                  itos(sz)+
00172                  " (index should be less than size).").c_str(),gsl_index);
00173         return data;
00174       }
00175 #endif
00176       return data+i;
00177     }
00178     
00179     /** \brief Get pointer (with optional range-checking) */
00180     const data_t *get_const_ptr(size_t i) const {
00181 #if GSL_RANGE_CHECK
00182       if (i>=sz) {
00183         set_err("Index out of range in uvector_view::get_const_ptr().",1);
00184         return NULL;
00185       }
00186 #endif
00187       return (const data_t *)(data+i);
00188     }
00189     
00190     /** \brief Set (with optional range-checking) */
00191     int set(size_t i, data_t val) {
00192 #if GSL_RANGE_CHECK
00193       if (i>=sz) {
00194         set_err_ret((((std::string)"Array index ")+itos(i)+" out of bounds"
00195                      +" in uvector_view_tlate::set(). Size: "+
00196                      itos(sz)+
00197                      " (index should be less than size).").c_str(),gsl_index);
00198       }
00199 #endif
00200       data[i]=val;
00201       return 0;
00202     }
00203 
00204     /** \brief Set all of the value to be the value \c val */
00205     int set_all(data_t val) {
00206       for(size_t i=0;i<sz;i++) {
00207         data[i]=val;
00208       }
00209       return 0;
00210     }
00211 
00212     /** 
00213         \brief Method to return vector size 
00214         
00215         If no memory has been allocated, this will quietly 
00216         return zero.
00217     */
00218     size_t size() const {
00219       return sz;
00220     }
00221     //@}
00222 
00223     /// \name Other methods
00224     //@{
00225 
00226     /** \brief Swap vectors */
00227     int swap(uvector_view_tlate<data_t> &x) {
00228       size_t t1, t2;
00229       double *t3;
00230       int t5;
00231       
00232       t1=sz;
00233       t3=data;
00234       t5=owner;
00235       
00236       sz=x.sz;
00237       data=x.data;
00238       owner=x.owner;
00239 
00240       x.sz=t1;
00241       x.data=t3;
00242       x.owner=t5;
00243 
00244       return 0;
00245     }
00246 
00247     /// Return true if this object owns the data it refers to
00248     bool is_owner() const {
00249       if (owner==1) return true;
00250       return false;
00251     }
00252 
00253     /** \brief Exhaustively look through the array for a
00254         particular value 
00255 
00256         This can only fail if \em all of the entries in the array are
00257         not finite, in which case it calls set_err() and returns
00258         0. The error handler is reset at the beginning of lookup().
00259     */
00260     size_t lookup(const data_t x0) const {
00261       err_hnd->reset();
00262       const uvector_view_tlate<data_t> *a=this;
00263       size_t row=0, i=0, nvar=size();
00264       while(!finite((*a)[i]) && i<nvar-1) i++;
00265       if (i==nvar-1) {
00266         set_err("Array not finite in intp_base::lookup()",1);
00267         return 0;
00268       }
00269       data_t best=(*a)[i], bdiff=fabs((*a)[i]-x0);
00270       for(;i<nvar;i++) {
00271         if (finite((*a)[i]) && fabs((*a)[i]-x0)<bdiff) {
00272           row=i;
00273           best=(*a)[i];
00274           bdiff=fabs((*a)[i]-x0);
00275         }
00276       }
00277       return row;
00278     }
00279 
00280     /** \brief Find the maximum element */
00281     data_t max() const {
00282       data_t maxval;
00283       if (sz>0) {
00284         maxval=data[0];
00285         for(size_t i=1;i<sz;i++) {
00286           if (data[i]>maxval) {
00287             maxval=data[i];
00288           }
00289         }
00290       } else {
00291         return 0.0;
00292       }
00293       return maxval;
00294     }
00295 
00296     /** \brief Find the minimum element */
00297     data_t min() const {
00298       data_t minval;
00299       if (sz>0) {
00300         minval=data[0];
00301         for(size_t i=1;i<sz;i++) {
00302           if (data[i]<minval) {
00303             minval=data[i];
00304           }
00305         }
00306       } else {
00307         return 0.0;
00308       }
00309       return minval;
00310     }
00311     //@}
00312 
00313     /// \name Arithmetic
00314     //@{
00315     /** \brief operator+= */
00316     uvector_view_tlate<data_t> &operator+=
00317       (const uvector_view_tlate<data_t> &x) {
00318       size_t lsz=x.sz;
00319       if (lsz>sz) lsz=sz;
00320       for(size_t i=0;i<lsz;i++) (*this)[i]+=x[i];
00321       
00322       return *this;
00323     }
00324     
00325     /** \brief operator-= */
00326     uvector_view_tlate<data_t> &operator-=
00327       (const uvector_view_tlate<data_t> &x) {
00328       size_t lsz=x.sz;
00329       if (lsz>sz) lsz=sz;
00330       for(size_t i=0;i<lsz;i++) (*this)[i]-=x[i];
00331       
00332       return *this;
00333     }
00334     
00335     /** \brief operator+= */
00336     uvector_view_tlate<data_t> &operator+=(const data_t &y) {
00337       for(size_t i=0;i<sz;i++) (*this)[i]+=y;
00338 
00339       return *this;
00340     }
00341 
00342     /** \brief operator-= */
00343     uvector_view_tlate<data_t> &operator-=(const data_t &y) {
00344       for(size_t i=0;i<sz;i++) (*this)[i]-=y;
00345 
00346       return *this;
00347     }
00348 
00349     /** \brief operator*= */
00350     uvector_view_tlate<data_t> &operator*=(const data_t &y) {
00351       for(size_t i=0;i<sz;i++) (*this)[i]*=y;
00352 
00353       return *this;
00354     }
00355     
00356     /** \brief Norm */
00357     data_t norm() const {
00358       data_t result=0;
00359       for(size_t i=0;i<sz;i++) {
00360         result+=(*this)[i]*(*this)[i];
00361       }
00362       return sqrt(result);
00363     }
00364     //@}
00365     
00366 #ifndef DOXYGEN_INTERNAL
00367 
00368     protected:
00369 
00370     /** \brief Empty constructor provided for use by 
00371         uvector_tlate(const uvector_tlate &v)
00372     */
00373     uvector_view_tlate() {};
00374 
00375 #endif
00376     
00377   };
00378 
00379   /** 
00380       \brief A vector with unit stride
00381   
00382       There are several global binary operators associated with
00383       objects of type \ref uvector_tlate. The are documented in the
00384       "Functions" section of \ref uvector_tlate.h.
00385   */
00386   template<class data_t> class uvector_tlate : 
00387     public uvector_view_tlate<data_t> {
00388     public:
00389 
00390     /// \name Standard constructor
00391     //@{
00392     /** \brief Create an uvector of size \c n with owner as 'true' */
00393     uvector_tlate(size_t n=0) {
00394 
00395       this->sz=0;
00396       this->data=0;
00397 
00398       // This must be set to 1 even if n=0 so that future
00399       // calls to operator= work properly
00400       this->owner=1;
00401 
00402       if (n>0) {
00403         this->data=(data_t *)malloc(n*sizeof(data_t));
00404         if (this->data) {
00405           this->sz=n;
00406         } else {
00407           set_err("No memory for data in uvector_tlate constructor",
00408                   gsl_enomem);
00409         }
00410       }
00411     }
00412     //@}
00413     
00414     /// \name Copy constructors
00415     //@{
00416     /// Deep copy constructor - allocate new space and make a copy
00417     uvector_tlate(const uvector_tlate &v) : 
00418       uvector_view_tlate<data_t>() {
00419       size_t n=v.sz;
00420       this->sz=0;
00421       this->data=0;
00422       if (n>0) {
00423         this->data=(data_t *)malloc(n*sizeof(data_t));
00424         if (this->data) {
00425           this->sz=n;
00426           this->owner=1;
00427           for(size_t i=0;i<n;i++) {
00428             this->data[i]=v[i];
00429           }
00430         } else {
00431           set_err("No memory for data in uvector_tlate constructor",
00432                   gsl_enomem);
00433         }
00434       } else {
00435         this->sz=0;
00436       }
00437     }
00438     
00439     /// Deep copy constructor - allocate new space and make a copy
00440     uvector_tlate(const uvector_view_tlate<data_t> &v) : 
00441       uvector_view_tlate<data_t>() {
00442       size_t n=v.size();
00443       this->sz=0;
00444       this->data=0;
00445       if (n>0) {
00446         this->data=(data_t *)malloc(n*sizeof(data_t));
00447         if (this->data) {
00448           this->sz=n;
00449           this->owner=1;
00450           for(size_t i=0;i<n;i++) {
00451             this->data[i]=v[i];
00452           }
00453         } else {
00454           set_err("No memory for data in uvector_tlate constructor",
00455                   gsl_enomem);
00456         }
00457       } else {
00458         this->sz=0;
00459       }
00460     }
00461 
00462     /** \brief Deep copy constructor - if owner is true, allocate space and
00463         make a new copy, otherwise, just copy into the view
00464     */
00465     uvector_tlate& operator=(const uvector_tlate &v) {
00466       size_t sz2=v.sz;
00467       this->sz=0;
00468       this->data=0;
00469       if (this->owner) {
00470         allocate(sz2);
00471       } else {
00472         if (this->sz!=sz2) {
00473           set_err("Sizes don't match in uvector_tlate::operator=()",
00474                   gsl_ebadlen);
00475           return *this;
00476         }
00477       }
00478       for(size_t i=0;i<sz2;i++) {
00479         this->data[i]=v[i];
00480       }
00481       return *this;
00482     }
00483 
00484     /** \brief Deep copy constructor - if owner is true, allocate space and
00485         make a new copy, otherwise, just copy into the view
00486     */
00487     uvector_tlate& operator=(const uvector_view_tlate<data_t> &v) {
00488       size_t sz2=v.size();
00489       this->sz=0;
00490       this->data=0;
00491       if (this->owner) {
00492         allocate(sz2);
00493       } else {
00494         if (this->sz!=sz2) {
00495           set_err("Sizes don't match in uvector_tlate::operator=()",
00496                   gsl_ebadlen);
00497           return *this;
00498         }
00499       }
00500       for(size_t i=0;i<sz2;i++) {
00501         this->data[i]=v[i];
00502       }
00503       return *this;
00504     }
00505     //@}
00506 
00507     ~uvector_tlate() {
00508       if (this->sz>0) {
00509         if (this->owner==1) {
00510           std::free(this->data);
00511         }
00512         this->sz=0;
00513       }
00514     }
00515 
00516     /// \name Memory allocation
00517     //@{
00518     /** 
00519         \brief Allocate memory for size \c n after freeing any memory 
00520         presently in use
00521     */
00522     int allocate(size_t nsize) {
00523       if (this->sz>0) free();
00524 
00525       if (nsize>0) {
00526         this->data=(data_t *)malloc(nsize*sizeof(data_t));
00527         if (this->data) {
00528           this->sz=nsize;
00529           this->owner=1;
00530         } else {
00531           set_err_ret("No memory for data in uvector_tlate::allocate()",
00532                       gsl_enomem);
00533         }
00534       } else {
00535         set_err_ret("Zero size in uvector::allocate()",gsl_einval);
00536       }
00537       return 0;
00538     }
00539 
00540     /** 
00541         \brief Free the memory 
00542     
00543         This function will safely do nothing if used without first
00544         allocating memory or if called multiple times in succession.
00545     */
00546     int free() {
00547       if (this->sz>0) {
00548         if (this->owner==1) {
00549           std::free(this->data);
00550         }
00551         this->sz=0;
00552       }
00553       return 0;
00554     }
00555     //@}
00556 
00557     /// \name Other methods
00558     //@{
00559     /// Erase an element from the array. 
00560     int erase(size_t ix) {
00561 
00562       // Only proceed if the user gave an element inside the array
00563       if (this->sz>ix) {
00564 
00565         // Decrement the size 
00566         this->sz--;
00567 
00568         // Allocate new space
00569         data_t *newdat=(data_t *)(malloc(this->sz*sizeof(data_t)));
00570 
00571         // Copy into the new space
00572         for(size_t i=0;i<this->sz;i++) {
00573           if (i<ix) newdat[i]=this->data[i];
00574           else newdat[i]=this->data[i+1];
00575         }
00576 
00577         // Free the old space and reset the pointer
00578         std::free(this->data);
00579         this->data=newdat;
00580 
00581       } else {
00582         set_err_ret("Cannot erase() beyond end of uvector_tlate.",
00583                     gsl_einval);
00584       }
00585 
00586       return 0;
00587     }
00588     //@}
00589 
00590   };
00591 
00592   /** \brief Create a vector from an array 
00593   */
00594   template<class data_t> class uvector_array_tlate : 
00595     public uvector_view_tlate<data_t> {
00596     public:
00597     /** \brief Create a vector from \c dat with size \c n */
00598     uvector_array_tlate(size_t n, data_t *dat) {
00599       if (n>0) {
00600         this->data=dat;
00601         this->sz=n;
00602         this->owner=0;
00603       }
00604     }
00605   };
00606 
00607   /** \brief Create a vector from a subvector of another
00608   */
00609   template<class data_t> class uvector_subvector_tlate : 
00610     public uvector_view_tlate<data_t> {
00611     public:
00612     /** \brief Create a vector from \c orig      */
00613     uvector_subvector_tlate(uvector_view_tlate<data_t> &orig, 
00614                             size_t offset, size_t n) {
00615       if (offset+n-1<orig.size) {
00616         this->data=orig.data+offset;
00617         this->sz=n;
00618         this->owner=0;
00619       } else {
00620         this->sz=0;
00621         set_err("Subvector failed in uvector_sub_view().",1);
00622       }
00623     }
00624   };
00625 
00626   /** \brief Create a vector from an const array 
00627   */
00628   template<class data_t> class uvector_const_array_tlate :
00629     public uvector_view_tlate<data_t> {
00630     public:
00631     /** \brief Create a vector from \c dat with size \c n */
00632     uvector_const_array_tlate(size_t n, const data_t *dat) {
00633       if (n>0) {
00634         // We have to do an explicit cast here, but we prevent the
00635         // user from changing the data.
00636         this->data=(data_t *)dat;
00637         this->sz=n;
00638         this->owner=0;
00639       }
00640     }
00641     
00642     ~uvector_const_array_tlate() {};
00643     
00644 #ifndef DOXYGEN_INTERNAL
00645 
00646     protected:
00647 
00648     /** \name Ensure \c const by hiding non-const members
00649     */
00650     //@{
00651     data_t &operator[](size_t i) { return this->data[0]; }
00652     data_t &operator()(size_t i) { return this->data[0]; }
00653     data_t *get_ptr(size_t i) { return NULL; }
00654     int set(size_t i, data_t val) { return 0; }
00655     int swap(uvector_view_tlate<data_t> &x) {
00656       return 0; 
00657     }
00658     int set_all(double val) { return 0; }
00659     uvector_view_tlate<data_t> &operator+=
00660       (const uvector_view_tlate<data_t> &x) {
00661       return *this;
00662     }
00663     uvector_view_tlate<data_t> &operator-=
00664       (const uvector_view_tlate<data_t> &x) {
00665       return *this;
00666     }
00667     uvector_view_tlate<data_t> &operator*=(const data_t &y) {
00668       return *this;
00669     }
00670     //@}
00671 
00672 #endif
00673 
00674   };
00675 
00676   /** \brief Create a const vector from a subvector of another vector
00677   */
00678   template<class data_t> class uvector_const_subvector_tlate :
00679     public uvector_view_tlate<data_t> {
00680     public:
00681     /** \brief Create a vector from \c orig 
00682      */
00683     uvector_const_subvector_tlate
00684       (const uvector_view_tlate<data_t> &orig, 
00685        size_t offset, size_t n) {
00686       if (offset+n-1<orig.sz) {
00687         this->data=orig.data+offset;
00688         this->sz=n;
00689         this->owner=0;
00690       } else {
00691         this->sz=0;
00692         set_err("Subvector failed in uvector_subvector().",1);
00693       }
00694     }
00695 
00696 #ifndef DOXYGENP
00697 
00698   protected:
00699 
00700     /** \name Ensure \c const by hiding non-const members
00701     */
00702     //@{
00703     data_t &operator[](size_t i) { return this->data[0]; }
00704     data_t &operator()(size_t i) { return this->data[0]; }
00705     data_t *get_ptr(size_t i) { return NULL; }
00706     int set(size_t i, data_t val) { return 0; }
00707     int swap(uvector_view_tlate<data_t> &x) {
00708       return 0; 
00709     }
00710     int set_all(double val) { return 0; }
00711     uvector_view_tlate<data_t> &operator+=
00712       (const uvector_view_tlate<data_t> &x) {
00713       return *this;
00714     }
00715     uvector_view_tlate<data_t> &operator-=
00716       (const uvector_view_tlate<data_t> &x) {
00717       return *this;
00718     }
00719     uvector_view_tlate<data_t> &operator*=(const data_t &y) {
00720       return *this;
00721     }
00722     //@}
00723 
00724 #endif
00725 
00726   };
00727 
00728 #ifdef DOXYGENP
00729   /// uvector typedef
00730   typedef uvector_tlate<data_t,size_t> uvector;
00731   /// uvector_view typedef
00732   typedef uvector_view_tlate<data_t,size_t> uvector_view;
00733   /// uvector_array typedef
00734   typedef uvector_array_tlate<data_t,size_t> uvector_array;
00735   /// uvector_subvector typedef
00736   typedef uvector_subvector_tlate<data_t,size_t> uvector_subvector;
00737   /// uvector_const_array typedef
00738   typedef uvector_const_array_tlate<data_t,size_t> uvector_const_array;
00739   /// uvector_const_subvector typedef
00740   typedef uvector_const_subvector_tlate<data_t,size_t> uvector_const_subvector;
00741 #else
00742   /// uvector typedef
00743   typedef uvector_tlate<double> uvector;
00744   /// uvector_view typedef
00745   typedef uvector_view_tlate<double> uvector_view;
00746   /// uvector_array typedef
00747   typedef uvector_array_tlate<double> uvector_array;
00748   /// uvector_subvector typedef
00749   typedef uvector_subvector_tlate<double> uvector_subvector;
00750   /// uvector_const_array typedef
00751   typedef uvector_const_array_tlate<double> uvector_const_array;
00752   /// uvector_const_subvector typedef
00753   typedef uvector_const_subvector_tlate<double> uvector_const_subvector;
00754 #endif
00755   
00756   /// uvector_int typedef
00757   typedef uvector_tlate<int> uvector_int;
00758   /// uvector_int_view typedef
00759   typedef uvector_view_tlate<int> uvector_int_view;
00760   /// uvector_int_array typedef
00761   typedef uvector_array_tlate<int> uvector_int_array;
00762   /// uvector_int_subvector typedef
00763   typedef uvector_subvector_tlate<int> uvector_int_subvector;
00764   /// uvector_int_const_array typedef
00765   typedef uvector_const_array_tlate<int> uvector_int_const_array;
00766   /// uvector_int_const_subvector typedef
00767   typedef uvector_const_subvector_tlate<int> uvector_int_const_subvector;
00768 
00769   /** 
00770       \brief A operator for naive vector output
00771 
00772       This outputs all of the vector elements. All of these are
00773       separated by one space character, though no trailing space or \c
00774       endl is sent to the output.
00775    */
00776   template<class data_t>
00777     std::ostream &operator<<
00778     (std::ostream &os, 
00779      const uvector_view_tlate<data_t> &v) {
00780     if (v.size()>0) {
00781       for(size_t i=0;i<v.size()-1;i++) {
00782         os << v[i] << ' ';
00783       }
00784       os << v[v.size()-1];
00785     } else {
00786       os << "<empty>";
00787     }
00788     return os;
00789   }
00790   
00791   /** \brief A vector with unit-stride where the memory allocation is 
00792       performed in the constructor
00793   */
00794 #ifdef DOXYGENP
00795   template<size_t N=0> class ufvector : 
00796     public uvector_tlate<data_t>
00797 #else
00798     template<size_t N=0> class ufvector : 
00799     public uvector_tlate<double>
00800 #endif
00801     {
00802       public:
00803       ufvector() : uvector_tlate<double>(N) {
00804       }
00805     };
00806   
00807 #ifndef DOXYGENP
00808 }
00809 #endif
00810 
00811 #endif
00812 

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page