00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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 00037 #include <gsl/gsl_vector.h> 00038 00039 #include <o2scl/err_hnd.h> 00040 #include <o2scl/string_conv.h> 00041 #include <o2scl/array.h> 00042 #include <o2scl/vector.h> 00043 00044 #ifndef DOXYGENP 00045 namespace o2scl { 00046 #endif 00047 00048 /// Forward declaration 00049 template<class data_t> class uvector_base_tlate; 00050 /// Forward declaration 00051 template<class data_t> class uvector_view_tlate; 00052 /// Forward declaration 00053 template<class data_t> class uvector_tlate; 00054 00055 /** 00056 \brief A const vector view with unit stride 00057 00058 \future Could allow user-defined specification of 00059 restrict keyword 00060 */ 00061 template<class data_t> class uvector_const_view_tlate { 00062 00063 #ifndef DOXYGEN_INTERNAL 00064 00065 protected: 00066 00067 // Make sure everyone can access the base data 00068 friend class uvector_base_tlate<data_t>; 00069 friend class uvector_view_tlate<data_t>; 00070 friend class uvector_tlate<data_t>; 00071 00072 /// The data 00073 data_t *data; 00074 /// The vector sz 00075 size_t sz; 00076 /// Zero if memory is owned elsewhere, 1 otherwise 00077 int owner; 00078 00079 #endif 00080 00081 public: 00082 00083 /// \name Copy constructors 00084 //@{ 00085 /// Copy constructor - create a new view of the same vector 00086 uvector_const_view_tlate(const uvector_const_view_tlate &v) { 00087 data=v.data; 00088 sz=v.sz; 00089 owner=0; 00090 } 00091 00092 /// Copy constructor - create a new view of the same vector 00093 uvector_const_view_tlate& operator=(const uvector_const_view_tlate &v) { 00094 data=v.data; 00095 sz=v.sz; 00096 owner=0; 00097 00098 return *this; 00099 } 00100 //@} 00101 00102 ~uvector_const_view_tlate() {}; 00103 00104 /// \name Get and set methods 00105 //@{ 00106 /** 00107 \brief Array-like indexing 00108 */ 00109 const data_t &operator[](size_t i) const { 00110 #if O2SCL_NO_RANGE_CHECK 00111 #else 00112 if (i>=sz) { 00113 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00114 +" in uvector_const_view_tlate::operator[] const. Size: "+ 00115 itos(sz)+ 00116 " (index should be less than size).").c_str(),gsl_eindex); 00117 return data[0]; 00118 } 00119 #endif 00120 return data[i]; 00121 } 00122 00123 /** 00124 \brief Array-like indexing 00125 */ 00126 const data_t &operator()(size_t i) const { 00127 #if O2SCL_NO_RANGE_CHECK 00128 #else 00129 if (i>=sz) { 00130 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00131 +" in uvector_const_view_tlate::operator() const. Size: "+ 00132 itos(sz)+ 00133 " (index should be less than size).").c_str(),gsl_eindex); 00134 return data[0]; 00135 } 00136 #endif 00137 return data[i]; 00138 } 00139 00140 /** \brief Get (with optional range-checking) */ 00141 data_t get(size_t i) const { 00142 #if O2SCL_NO_RANGE_CHECK 00143 #else 00144 if (i>=sz) { 00145 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00146 +" in uvector_const_view_tlate::get(). Size: "+ 00147 itos(sz)+ 00148 " (index should be less than size).").c_str(),gsl_eindex); 00149 return data[0]; 00150 } 00151 #endif 00152 return data[i]; 00153 } 00154 00155 /** \brief Get pointer (with optional range-checking) */ 00156 const data_t *get_const_ptr(size_t i) const { 00157 #if O2SCL_NO_RANGE_CHECK 00158 #else 00159 if (i>=sz) { 00160 O2SCL_ERR2("Index out of range in ", 00161 "uvector_const_view::get_const_ptr().",1); 00162 return NULL; 00163 } 00164 #endif 00165 return (const data_t *)(data+i); 00166 } 00167 00168 /** 00169 \brief Method to return vector size 00170 00171 If no memory has been allocated, this will quietly 00172 return zero. 00173 */ 00174 size_t size() const { 00175 return sz; 00176 } 00177 //@} 00178 00179 /// \name Other methods 00180 //@{ 00181 00182 /// Return true if this object owns the data it refers to 00183 bool is_owner() const { 00184 if (owner==1) return true; 00185 return false; 00186 } 00187 00188 /** \brief Exhaustively look through the array for a 00189 particular value 00190 00191 This can only fail if \em all of the entries in the array are 00192 not finite, in which case it calls O2SCL_ERR() and returns 00193 0. 00194 00195 If more than one entry is the same distance from <tt>x0</tt>, 00196 this function returns the entry with smallest index. 00197 */ 00198 size_t lookup(const data_t x0) const { 00199 00200 const uvector_const_view_tlate<data_t> *a=this; 00201 size_t row=0, i=0, nvar=size(); 00202 while(!finite((*a)[i]) && i<nvar-1) i++; 00203 if (i==nvar-1) { 00204 O2SCL_ERR("Array not finite in intp_base::lookup()",1); 00205 return 0; 00206 } 00207 data_t best=(*a)[i], bdiff=fabs((*a)[i]-x0); 00208 for(;i<nvar;i++) { 00209 if (finite((*a)[i]) && fabs((*a)[i]-x0)<bdiff) { 00210 row=i; 00211 best=(*a)[i]; 00212 bdiff=fabs((*a)[i]-x0); 00213 } 00214 } 00215 return row; 00216 } 00217 00218 /** \brief Find the maximum element */ 00219 data_t max() const { 00220 data_t maxval; 00221 if (sz>0) { 00222 maxval=data[0]; 00223 for(size_t i=1;i<sz;i++) { 00224 if (data[i]>maxval) { 00225 maxval=data[i]; 00226 } 00227 } 00228 } else { 00229 return 0.0; 00230 } 00231 return maxval; 00232 } 00233 00234 /** \brief Find the minimum element */ 00235 data_t min() const { 00236 data_t minval; 00237 if (sz>0) { 00238 minval=data[0]; 00239 for(size_t i=1;i<sz;i++) { 00240 if (data[i]<minval) { 00241 minval=data[i]; 00242 } 00243 } 00244 } else { 00245 return 0.0; 00246 } 00247 return minval; 00248 } 00249 //@} 00250 00251 /** \brief Norm */ 00252 data_t norm() const { 00253 data_t result=0; 00254 for(size_t i=0;i<sz;i++) { 00255 result+=(*this)[i]*(*this)[i]; 00256 } 00257 return std::sqrt(result); 00258 } 00259 00260 #ifndef DOXYGEN_INTERNAL 00261 00262 protected: 00263 00264 /** \brief Empty constructor provided for use by 00265 uvector_tlate(const uvector_tlate &v) 00266 */ 00267 uvector_const_view_tlate() {}; 00268 00269 #endif 00270 00271 }; 00272 00273 /// Desc 00274 template<class data_t> class uvector_base_tlate : 00275 public uvector_const_view_tlate<data_t> { 00276 00277 public: 00278 00279 /// \name Copy constructors 00280 //@{ 00281 /// Copy constructor - create a new view of the same vector 00282 uvector_base_tlate(uvector_base_tlate &v) : 00283 uvector_const_view_tlate<data_t>() { 00284 this->data=v.data; 00285 this->sz=v.sz; 00286 this->owner=0; 00287 } 00288 00289 /// Copy constructor - create a new view of the same vector 00290 uvector_base_tlate& operator=(uvector_base_tlate &v) { 00291 this->data=v.data; 00292 this->sz=v.sz; 00293 this->owner=0; 00294 00295 return *this; 00296 } 00297 //@} 00298 00299 /// \name Get and set methods 00300 //@{ 00301 /** 00302 \brief Array-like indexing 00303 */ 00304 data_t &operator[](size_t i) { 00305 #if O2SCL_NO_RANGE_CHECK 00306 #else 00307 if (i>=this->sz) { 00308 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00309 +" in uvector_const_view_tlate::operator[]. Size: "+ 00310 itos(this->sz)+ 00311 " (index should be less than size).").c_str(),gsl_eindex); 00312 return this->data[0]; 00313 } 00314 #endif 00315 return this->data[i]; 00316 } 00317 00318 /** 00319 \brief Array-like indexing 00320 */ 00321 const data_t &operator[](size_t i) const { 00322 #if O2SCL_NO_RANGE_CHECK 00323 #else 00324 if (i>=this->sz) { 00325 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00326 +" in uvector_const_view_tlate::operator[] const. Size: "+ 00327 itos(this->sz)+ 00328 " (index should be less than size).").c_str(),gsl_eindex); 00329 return this->data[0]; 00330 } 00331 #endif 00332 return this->data[i]; 00333 } 00334 00335 /** 00336 \brief Array-like indexing 00337 */ 00338 data_t &operator()(size_t i) { 00339 #if O2SCL_NO_RANGE_CHECK 00340 #else 00341 if (i>=this->sz) { 00342 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00343 +" in uvector_const_view_tlate::operator(). Size: "+ 00344 itos(this->sz)+ 00345 " (index should be less than size).").c_str(),gsl_eindex); 00346 return this->data[0]; 00347 } 00348 #endif 00349 return this->data[i]; 00350 } 00351 00352 /** 00353 \brief Array-like indexing 00354 */ 00355 const data_t &operator()(size_t i) const { 00356 #if O2SCL_NO_RANGE_CHECK 00357 #else 00358 if (i>=this->sz) { 00359 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00360 +" in uvector_const_view_tlate::operator() const. Size: "+ 00361 itos(this->sz)+ 00362 " (index should be less than size).").c_str(),gsl_eindex); 00363 return this->data[0]; 00364 } 00365 #endif 00366 return this->data[i]; 00367 } 00368 00369 /** \brief Get pointer (with optional range-checking) */ 00370 data_t *get_ptr(size_t i) { 00371 #if O2SCL_NO_RANGE_CHECK 00372 #else 00373 if (i>=this->sz) { 00374 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00375 +" in uvector_const_view_tlate::get_ptr(). Size: "+ 00376 itos(this->sz)+ 00377 " (index should be less than size).").c_str(),gsl_eindex); 00378 return this->data; 00379 } 00380 #endif 00381 return this->data+i; 00382 } 00383 00384 /** \brief Set (with optional range-checking) */ 00385 int set(size_t i, data_t val) { 00386 #if O2SCL_NO_RANGE_CHECK 00387 #else 00388 if (i>=this->sz) { 00389 O2SCL_ERR_RET((((std::string)"Array index ")+itos(i)+" out of bounds" 00390 +" in uvector_const_view_tlate::set(). Size: "+ 00391 itos(this->sz)+ 00392 " (index should be less than size).").c_str(),gsl_eindex); 00393 } 00394 #endif 00395 this->data[i]=val; 00396 return 0; 00397 } 00398 00399 /** \brief Set all of the value to be the value \c val */ 00400 int set_all(data_t val) { 00401 for(size_t i=0;i<this->sz;i++) { 00402 this->data[i]=val; 00403 } 00404 return 0; 00405 } 00406 00407 //@} 00408 00409 /// \name Arithmetic 00410 //@{ 00411 /** \brief operator+= */ 00412 uvector_base_tlate<data_t> &operator+= 00413 (const uvector_base_tlate<data_t> &x) { 00414 size_t lsz=x.size(); 00415 if (lsz>this->sz) lsz=this->sz; 00416 for(size_t i=0;i<lsz;i++) (*this)[i]+=x[i]; 00417 00418 return *this; 00419 } 00420 00421 /** \brief operator-= */ 00422 uvector_base_tlate<data_t> &operator-= 00423 (const uvector_base_tlate<data_t> &x) { 00424 size_t lsz=x.size(); 00425 if (lsz>this->sz) lsz=this->sz; 00426 for(size_t i=0;i<lsz;i++) (*this)[i]-=x[i]; 00427 00428 return *this; 00429 } 00430 00431 /** \brief operator+= */ 00432 uvector_base_tlate<data_t> &operator+=(const data_t &y) { 00433 for(size_t i=0;i<this->sz;i++) (*this)[i]+=y; 00434 00435 return *this; 00436 } 00437 00438 /** \brief operator-= */ 00439 uvector_base_tlate<data_t> &operator-=(const data_t &y) { 00440 for(size_t i=0;i<this->sz;i++) (*this)[i]-=y; 00441 00442 return *this; 00443 } 00444 00445 /** \brief operator*= */ 00446 uvector_base_tlate<data_t> &operator*=(const data_t &y) { 00447 for(size_t i=0;i<this->sz;i++) (*this)[i]*=y; 00448 00449 return *this; 00450 } 00451 //@} 00452 00453 #ifndef DOXYGEN_INTERNAL 00454 00455 protected: 00456 00457 /** \brief Empty constructor for use by children 00458 00459 \comment 00460 This is private because I want to prevent the casual end-user 00461 from creating uvector_base objects. End-users should really be 00462 focused on making normal vectors and views. 00463 \endcomment 00464 */ 00465 uvector_base_tlate() {} 00466 00467 #endif 00468 00469 }; 00470 00471 #ifdef O2SCL_NEVER_DEFINED 00472 }{ 00473 #endif 00474 00475 /** \brief A base class for uvectors 00476 */ 00477 template<class data_t> class uvector_view_tlate : 00478 public uvector_base_tlate<data_t> { 00479 00480 public: 00481 00482 /// \name Copy constructors 00483 //@{ 00484 /// Copy constructor - create a new view of the same vector 00485 uvector_view_tlate(const uvector_view_tlate &v) : 00486 uvector_base_tlate<data_t>() { 00487 this->data=v.data; 00488 this->sz=v.sz; 00489 this->owner=0; 00490 } 00491 00492 /// Copy constructor - create a new view of the same vector 00493 uvector_view_tlate& operator=(const uvector_view_tlate &v) { 00494 this->data=v.data; 00495 this->sz=v.sz; 00496 this->owner=0; 00497 00498 return *this; 00499 } 00500 00501 /// Copy constructor - create a new view of the same vector 00502 uvector_view_tlate(uvector_base_tlate<data_t> &v) : 00503 uvector_base_tlate<data_t>() { 00504 this->data=v.data; 00505 this->sz=v.sz; 00506 this->owner=0; 00507 } 00508 00509 /// Copy constructor - create a new view of the same vector 00510 uvector_view_tlate& operator=(uvector_base_tlate<data_t> &v) { 00511 this->data=v.data; 00512 this->sz=v.sz; 00513 this->owner=0; 00514 00515 return *this; 00516 } 00517 //@} 00518 00519 /// \name Get and set methods 00520 //@{ 00521 /** 00522 \brief Array-like indexing 00523 */ 00524 data_t &operator[](size_t i) const { 00525 #if O2SCL_NO_RANGE_CHECK 00526 #else 00527 if (i>=this->sz) { 00528 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00529 +" in uvector_view_tlate::operator[]. Size: "+ 00530 itos(this->sz)+ 00531 " (index should be less than size).").c_str(),gsl_eindex); 00532 return this->data[0]; 00533 } 00534 #endif 00535 return this->data[i]; 00536 } 00537 00538 /** 00539 \brief Array-like indexing 00540 */ 00541 data_t &operator()(size_t i) const { 00542 #if O2SCL_NO_RANGE_CHECK 00543 #else 00544 if (i>=this->sz) { 00545 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00546 +" in uvector_view_tlate::operator(). Size: "+ 00547 itos(this->sz)+ 00548 " (index should be less than size).").c_str(),gsl_eindex); 00549 return this->data[0]; 00550 } 00551 #endif 00552 return this->data[i]; 00553 } 00554 00555 /** \brief Get pointer (with optional range-checking) */ 00556 data_t *get_ptr(size_t i) const { 00557 #if O2SCL_NO_RANGE_CHECK 00558 #else 00559 if (i>=this->sz) { 00560 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00561 +" in uvector_view_tlate::get_ptr(). Size: "+ 00562 itos(this->sz)+ 00563 " (index should be less than size).").c_str(),gsl_eindex); 00564 return this->data; 00565 } 00566 #endif 00567 return this->data+i; 00568 } 00569 00570 /** \brief Set (with optional range-checking) */ 00571 int set(size_t i, data_t val) const { 00572 #if O2SCL_NO_RANGE_CHECK 00573 #else 00574 if (i>=this->sz) { 00575 O2SCL_ERR_RET((((std::string)"Array index ")+itos(i)+" out of bounds" 00576 +" in uvector_view_tlate::set(). Size: "+ 00577 itos(this->sz)+ 00578 " (index should be less than size).").c_str(),gsl_eindex); 00579 } 00580 #endif 00581 this->data[i]=val; 00582 return 0; 00583 } 00584 00585 /** \brief Set all of the value to be the value \c val */ 00586 int set_all(data_t val) const { 00587 for(size_t i=0;i<this->sz;i++) { 00588 this->data[i]=val; 00589 } 00590 return 0; 00591 } 00592 00593 //@} 00594 00595 #ifndef DOXYGEN_INTERNAL 00596 00597 protected: 00598 00599 /** \brief Empty constructor provided for use by 00600 uvector_view_tlate(const uvector_view_tlate &v) 00601 */ 00602 uvector_view_tlate() {} 00603 00604 #endif 00605 00606 }; 00607 00608 /** 00609 \brief A vector with unit stride 00610 00611 There are several useful methods which are defined in the parent 00612 class, \ref uvector_view_tlate . There is also an << operator 00613 for this class documented "Functions" section of \ref 00614 uvector_tlate.h. 00615 */ 00616 template<class data_t> class uvector_tlate : 00617 public uvector_base_tlate<data_t> { 00618 00619 public: 00620 00621 // This is required so that the uvector_view_tlate constructor 00622 // can access uvector_tlate data. 00623 friend class uvector_view_tlate<data_t>; 00624 00625 /// \name Standard constructor 00626 //@{ 00627 /** \brief Create an uvector of size \c n with owner as 'true' */ 00628 uvector_tlate(size_t n=0) { 00629 00630 this->sz=0; 00631 this->data=0; 00632 00633 // This must be set to 1 even if n=0 so that future 00634 // calls to operator= work properly 00635 this->owner=1; 00636 00637 if (n>0) { 00638 this->data=(data_t *)malloc(n*sizeof(data_t)); 00639 if (this->data) { 00640 this->sz=n; 00641 } else { 00642 O2SCL_ERR("No memory for data in uvector_tlate constructor", 00643 gsl_enomem); 00644 } 00645 } 00646 } 00647 //@} 00648 00649 /// \name Copy constructors 00650 //@{ 00651 /// Deep copy constructor - allocate new space and make a copy 00652 uvector_tlate(const uvector_tlate &v) : 00653 uvector_base_tlate<data_t>() { 00654 00655 this->sz=0; 00656 this->data=0; 00657 this->owner=1; 00658 00659 size_t n=v.sz; 00660 if (n>0) { 00661 this->data=(data_t *)malloc(n*sizeof(data_t)); 00662 if (this->data) { 00663 this->sz=n; 00664 this->owner=1; 00665 for(size_t i=0;i<n;i++) { 00666 this->data[i]=v[i]; 00667 } 00668 } else { 00669 O2SCL_ERR("No memory for data in uvector_tlate constructor", 00670 gsl_enomem); 00671 } 00672 } else { 00673 this->sz=0; 00674 } 00675 } 00676 00677 /// Deep copy constructor - allocate new space and make a copy 00678 uvector_tlate(const uvector_const_view_tlate<data_t> &v) : 00679 uvector_base_tlate<data_t>() { 00680 00681 this->sz=0; 00682 this->data=0; 00683 this->owner=1; 00684 00685 size_t n=v.size(); 00686 if (n>0) { 00687 this->data=(data_t *)malloc(n*sizeof(data_t)); 00688 if (this->data) { 00689 this->sz=n; 00690 this->owner=1; 00691 for(size_t i=0;i<n;i++) { 00692 this->data[i]=v[i]; 00693 } 00694 } else { 00695 O2SCL_ERR("No memory for data in uvector_tlate constructor", 00696 gsl_enomem); 00697 } 00698 } else { 00699 this->sz=0; 00700 } 00701 } 00702 00703 /** \brief Deep copy constructor - if owner is true, allocate space and 00704 make a new copy, otherwise, just copy into the view 00705 */ 00706 uvector_tlate& operator=(const uvector_tlate &v) { 00707 00708 // Check for self-assignment 00709 if (this==&v) return *this; 00710 00711 size_t sz2=v.sz; 00712 this->sz=0; 00713 this->data=0; 00714 if (this->owner) { 00715 allocate(sz2); 00716 } else { 00717 if (this->sz!=sz2) { 00718 O2SCL_ERR("Sizes don't match in uvector_tlate::operator=()", 00719 gsl_ebadlen); 00720 return *this; 00721 } 00722 } 00723 for(size_t i=0;i<sz2;i++) { 00724 this->data[i]=v[i]; 00725 } 00726 return *this; 00727 } 00728 00729 /** \brief Deep copy constructor - if owner is true, allocate space and 00730 make a new copy, otherwise, just copy into the view 00731 */ 00732 uvector_tlate& operator=(const uvector_const_view_tlate<data_t> &v) { 00733 00734 // Check for self-assignment 00735 if (this==&v) return *this; 00736 00737 size_t sz2=v.size(); 00738 this->sz=0; 00739 this->data=0; 00740 if (this->owner) { 00741 allocate(sz2); 00742 } else { 00743 if (this->sz!=sz2) { 00744 O2SCL_ERR("Sizes don't match in uvector_tlate::operator=()", 00745 gsl_ebadlen); 00746 return *this; 00747 } 00748 } 00749 for(size_t i=0;i<sz2;i++) { 00750 this->data[i]=v[i]; 00751 } 00752 return *this; 00753 } 00754 //@} 00755 00756 ~uvector_tlate() { 00757 if (this->sz>0) { 00758 if (this->owner==1) { 00759 std::free(this->data); 00760 } 00761 this->sz=0; 00762 } 00763 } 00764 00765 /// \name Memory allocation 00766 //@{ 00767 /** 00768 \brief Allocate memory for size \c n after freeing any memory 00769 presently in use 00770 */ 00771 int allocate(size_t nsize) { 00772 if (this->sz>0) free(); 00773 00774 if (nsize>0) { 00775 this->data=(data_t *)malloc(nsize*sizeof(data_t)); 00776 if (this->data) { 00777 this->sz=nsize; 00778 this->owner=1; 00779 } else { 00780 O2SCL_ERR_RET("No memory for data in uvector_tlate::allocate()", 00781 gsl_enomem); 00782 } 00783 } else { 00784 O2SCL_ERR_RET("Zero size in uvector::allocate()",gsl_einval); 00785 } 00786 return 0; 00787 } 00788 00789 /** 00790 \brief Free the memory 00791 00792 This function will safely do nothing if used without first 00793 allocating memory or if called multiple times in succession. 00794 */ 00795 int free() { 00796 if (this->sz>0) { 00797 if (this->owner==1) { 00798 std::free(this->data); 00799 } 00800 this->sz=0; 00801 } 00802 return 0; 00803 } 00804 //@} 00805 00806 /// \name Other methods 00807 //@{ 00808 /// Erase an element from the array. 00809 int erase(size_t ix) { 00810 00811 // Only proceed if the user gave an element inside the array 00812 if (this->sz>ix) { 00813 00814 // Decrement the size 00815 this->sz--; 00816 00817 // Allocate new space 00818 data_t *newdat=(data_t *)(malloc(this->sz*sizeof(data_t))); 00819 00820 // Copy into the new space 00821 for(size_t i=0;i<this->sz;i++) { 00822 if (i<ix) newdat[i]=this->data[i]; 00823 else newdat[i]=this->data[i+1]; 00824 } 00825 00826 // Free the old space and reset the pointer 00827 std::free(this->data); 00828 this->data=newdat; 00829 00830 } else { 00831 O2SCL_ERR_RET("Cannot erase() beyond end of uvector_tlate.", 00832 gsl_einval); 00833 } 00834 00835 return 0; 00836 } 00837 //@} 00838 00839 /** 00840 \brief Sort the vector and ensure all elements are unique by 00841 removing duplicates 00842 */ 00843 int sort_unique() { 00844 o2scl::vector_sort<data_t,uvector_tlate<data_t> >(this->sz,*this); 00845 for(size_t i=1;i<this->sz;i++) { 00846 if ((*this)[i]==(*this)[i-1]) { 00847 int ret=erase(i-1); 00848 if (ret!=0) { 00849 O2SCL_ERR_RET("Erase failed in uvector_tlate::sort_unique().", 00850 gsl_esanity); 00851 } 00852 i--; 00853 } 00854 } 00855 return 0; 00856 } 00857 //@} 00858 00859 }; 00860 00861 /** \brief Create a vector from an array 00862 */ 00863 template<class data_t> class uvector_array_tlate : 00864 public uvector_view_tlate<data_t> { 00865 public: 00866 /** \brief Create a vector from \c dat with size \c n */ 00867 uvector_array_tlate(size_t n, data_t *dat) { 00868 if (n>0) { 00869 this->data=dat; 00870 this->sz=n; 00871 this->owner=0; 00872 } 00873 } 00874 }; 00875 00876 /** \brief Create a vector from a subvector of another 00877 */ 00878 template<class data_t> class uvector_subvector_tlate : 00879 public uvector_view_tlate<data_t> { 00880 public: 00881 /** \brief Create a vector from \c orig */ 00882 uvector_subvector_tlate(uvector_view_tlate<data_t> &orig, 00883 size_t offset, size_t n) { 00884 if (offset+n-1<orig.size) { 00885 this->data=orig.data+offset; 00886 this->sz=n; 00887 this->owner=0; 00888 } else { 00889 this->sz=0; 00890 O2SCL_ERR("Subvector failed in uvector_sub_view().",1); 00891 } 00892 } 00893 }; 00894 00895 /** \brief Create a vector from an const array 00896 */ 00897 template<class data_t> class uvector_const_array_tlate : 00898 public uvector_const_view_tlate<data_t> { 00899 public: 00900 /** \brief Create a vector from \c dat with size \c n */ 00901 uvector_const_array_tlate(size_t n, const data_t *dat) { 00902 if (n>0) { 00903 // We have to do an explicit cast here, but we prevent the 00904 // user from changing the data. 00905 this->data=(data_t *)dat; 00906 this->sz=n; 00907 this->owner=0; 00908 } 00909 } 00910 00911 ~uvector_const_array_tlate() {}; 00912 00913 }; 00914 00915 /** \brief Create a const vector from a subvector of another vector 00916 */ 00917 template<class data_t> class uvector_const_subvector_tlate : 00918 public uvector_const_view_tlate<data_t> { 00919 public: 00920 /** \brief Create a vector from \c orig 00921 */ 00922 uvector_const_subvector_tlate 00923 (const uvector_view_tlate<data_t> &orig, 00924 size_t offset, size_t n) { 00925 if (offset+n-1<orig.sz) { 00926 this->data=orig.data+offset; 00927 this->sz=n; 00928 this->owner=0; 00929 } else { 00930 this->sz=0; 00931 O2SCL_ERR("Subvector failed in uvector_subvector().",1); 00932 } 00933 } 00934 00935 }; 00936 00937 #ifdef O2SCL_NEVER_DEFINED 00938 /// uvector typedef 00939 typedef uvector_tlate<data_t,size_t> uvector; 00940 /// uvector_view typedef 00941 typedef uvector_view_tlate<data_t,size_t> uvector_view; 00942 /// uvector_base typedef 00943 typedef uvector_base_tlate<data_t,size_t> uvector_base; 00944 /// uvector_const_view typedef 00945 typedef uvector_const_view_tlate<data_t,size_t> uvector_const_view; 00946 /// uvector_array typedef 00947 typedef uvector_array_tlate<data_t,size_t> uvector_array; 00948 /// uvector_subvector typedef 00949 typedef uvector_subvector_tlate<data_t,size_t> uvector_subvector; 00950 /// uvector_const_array typedef 00951 typedef uvector_const_array_tlate<data_t,size_t> uvector_const_array; 00952 /// uvector_const_subvector typedef 00953 typedef uvector_const_subvector_tlate<data_t,size_t> uvector_const_subvector; 00954 #else 00955 /// uvector typedef 00956 typedef uvector_tlate<double> uvector; 00957 /// uvector_view typedef 00958 typedef uvector_view_tlate<double> uvector_view; 00959 /// uvector_base typedef 00960 typedef uvector_base_tlate<double> uvector_base; 00961 /// uvector_const_view typedef 00962 typedef uvector_const_view_tlate<double> uvector_const_view; 00963 /// uvector_array typedef 00964 typedef uvector_array_tlate<double> uvector_array; 00965 /// uvector_subvector typedef 00966 typedef uvector_subvector_tlate<double> uvector_subvector; 00967 /// uvector_const_array typedef 00968 typedef uvector_const_array_tlate<double> uvector_const_array; 00969 /// uvector_const_subvector typedef 00970 typedef uvector_const_subvector_tlate<double> uvector_const_subvector; 00971 #endif 00972 00973 /// uvector_int typedef 00974 typedef uvector_tlate<int> uvector_int; 00975 /// uvector_int_view typedef 00976 typedef uvector_view_tlate<int> uvector_int_view; 00977 /// uvector_int_array typedef 00978 typedef uvector_array_tlate<int> uvector_int_array; 00979 /// uvector_int_subvector typedef 00980 typedef uvector_subvector_tlate<int> uvector_int_subvector; 00981 /// uvector_int_const_array typedef 00982 typedef uvector_const_array_tlate<int> uvector_int_const_array; 00983 /// uvector_int_const_subvector typedef 00984 typedef uvector_const_subvector_tlate<int> uvector_int_const_subvector; 00985 00986 /** 00987 \brief A operator for naive vector output 00988 00989 This outputs all of the vector elements. All of these are 00990 separated by one space character, though no trailing space or \c 00991 endl is sent to the output. If the vector is empty, nothing 00992 is done. 00993 */ 00994 template<class data_t> 00995 std::ostream &operator<< 00996 (std::ostream &os, 00997 const uvector_const_view_tlate<data_t> &v) { 00998 if (v.size()>0) { 00999 for(size_t i=0;i<v.size()-1;i++) { 01000 os << v[i] << ' '; 01001 } 01002 os << v[v.size()-1]; 01003 } 01004 return os; 01005 } 01006 01007 /** \brief A simple class to provide an \c allocate() function 01008 for \ref uvector 01009 */ 01010 class uvector_alloc { 01011 public: 01012 /// Allocate \c v for \c i elements 01013 void allocate(uvector &o, size_t i) { o.allocate(i); } 01014 /// Free memory 01015 void free(uvector &o) { o.free(); } 01016 }; 01017 01018 /** \brief A simple class to provide an \c allocate() function 01019 for \ref uvector_int 01020 */ 01021 class uvector_int_alloc { 01022 public: 01023 /// Allocate \c v for \c i elements 01024 void allocate(uvector_int &o, size_t i) { o.allocate(i); } 01025 /// Free memory 01026 void free(uvector_int &o) { o.free(); } 01027 }; 01028 01029 /** \brief A vector with unit-stride where the memory allocation is 01030 performed in the constructor 01031 */ 01032 #ifdef DOXYGENP 01033 template<size_t N=0> class ufvector : 01034 public uvector_tlate<data_t> 01035 #else 01036 template<size_t N=0> class ufvector : 01037 public uvector_tlate<double> 01038 #endif 01039 { 01040 public: 01041 ufvector() : uvector_tlate<double>(N) { 01042 } 01043 }; 01044 01045 #ifndef DOXYGENP 01046 } 01047 #endif 01048 01049 #endif 01050
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