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