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