Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2001-2009 Vivien Mallet 00002 // Copyright (C) 2003-2009 Marc Duruflé 00003 // 00004 // This file is part of the linear-algebra library Seldon, 00005 // http://seldon.sourceforge.net/. 00006 // 00007 // Seldon is free software; you can redistribute it and/or modify it under the 00008 // terms of the GNU Lesser General Public License as published by the Free 00009 // Software Foundation; either version 2.1 of the License, or (at your option) 00010 // any later version. 00011 // 00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY 00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00015 // more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public License 00018 // along with Seldon. If not, see http://www.gnu.org/licenses/. 00019 00020 00021 #ifndef SELDON_FILE_VECTOR_CXX 00022 00023 #include "Vector.hxx" 00024 00025 namespace Seldon 00026 { 00027 00028 00030 // C_VECTOR_BASE // 00032 00033 00034 /**************** 00035 * CONSTRUCTORS * 00036 ****************/ 00037 00038 00040 00043 template <class T, class Allocator> 00044 inline Vector_Base<T, Allocator>::Vector_Base() 00045 { 00046 m_ = 0; 00047 data_ = NULL; 00048 } 00049 00050 00052 00056 template <class T, class Allocator> 00057 inline Vector_Base<T, Allocator>::Vector_Base(int i) 00058 { 00059 m_ = i; 00060 data_ = NULL; 00061 } 00062 00063 00065 00069 template <class T, class Allocator> 00070 inline Vector_Base<T, Allocator>:: 00071 Vector_Base(const Vector_Base<T, Allocator>& A) 00072 { 00073 m_ = A.GetM(); 00074 data_ = NULL; 00075 } 00076 00077 00078 /************** 00079 * DESTRUCTOR * 00080 **************/ 00081 00082 00084 template <class T, class Allocator> 00085 inline Vector_Base<T, Allocator>::~Vector_Base() 00086 { 00087 00088 #ifdef SELDON_CHECK_MEMORY 00089 try 00090 { 00091 #endif 00092 00093 if (data_ != NULL) 00094 { 00095 vect_allocator_.deallocate(data_, m_); 00096 m_ = 0; 00097 data_ = NULL; 00098 } 00099 00100 #ifdef SELDON_CHECK_MEMORY 00101 } 00102 catch (...) 00103 { 00104 m_ = 0; 00105 data_ = NULL; 00106 } 00107 #endif 00108 00109 } 00110 00111 00112 /******************* 00113 * BASIC FUNCTIONS * 00114 *******************/ 00115 00116 00118 00121 template <class T, class Allocator> 00122 int Vector_Base<T, Allocator>::GetM() const 00123 { 00124 return m_; 00125 } 00126 00127 00129 00132 template <class T, class Allocator> 00133 int Vector_Base<T, Allocator>::GetLength() const 00134 { 00135 return m_; 00136 } 00137 00138 00140 00143 template <class T, class Allocator> 00144 int Vector_Base<T, Allocator>::GetSize() const 00145 { 00146 return m_; 00147 } 00148 00149 00151 00154 template <class T, class Allocator> 00155 typename Vector_Base<T, Allocator>::pointer 00156 Vector_Base<T, Allocator>::GetData() const 00157 { 00158 return data_; 00159 } 00160 00161 00163 00166 template <class T, class Allocator> 00167 typename Vector_Base<T, Allocator>::const_pointer 00168 Vector_Base<T, Allocator>::GetDataConst() const 00169 { 00170 return reinterpret_cast<typename Vector_Base<T, 00171 Allocator>::const_pointer>(data_); 00172 } 00173 00174 00176 00179 template <class T, class Allocator> 00180 void* Vector_Base<T, Allocator>::GetDataVoid() const 00181 { 00182 return reinterpret_cast<void*>(data_); 00183 } 00184 00185 00187 00190 template <class T, class Allocator> 00191 const void* Vector_Base<T, Allocator>::GetDataConstVoid() const 00192 { 00193 return reinterpret_cast<const void*>(data_); 00194 } 00195 00196 00198 // VECTOR<VECT_FULL> // 00200 00201 00202 /**************** 00203 * CONSTRUCTORS * 00204 ****************/ 00205 00206 00208 00211 template <class T, class Allocator> 00212 Vector<T, VectFull, Allocator>::Vector(): 00213 Vector_Base<T, Allocator>() 00214 { 00215 } 00216 00217 00219 00222 template <class T, class Allocator> 00223 Vector<T, VectFull, Allocator>::Vector(int i): 00224 Vector_Base<T, Allocator>(i) 00225 { 00226 00227 #ifdef SELDON_CHECK_MEMORY 00228 try 00229 { 00230 #endif 00231 00232 this->data_ = this->vect_allocator_.allocate(i, this); 00233 00234 #ifdef SELDON_CHECK_MEMORY 00235 } 00236 catch (...) 00237 { 00238 this->m_ = 0; 00239 this->data_ = NULL; 00240 } 00241 if (this->data_ == NULL) 00242 this->m_ = 0; 00243 if (this->data_ == NULL && i != 0) 00244 throw NoMemory("Vector<VectFull>::Vector(int)", 00245 string("Unable to allocate memory for a vector of size ") 00246 + to_str(i*sizeof(T)) + " bytes (" 00247 + to_str(i) + " elements)."); 00248 #endif 00249 00250 } 00251 00252 00254 00264 template <class T, class Allocator> 00265 Vector<T, VectFull, Allocator> 00266 ::Vector(int i, typename Vector<T, VectFull, Allocator>::pointer data): 00267 Vector_Base<T, Allocator>() 00268 { 00269 SetData(i, data); 00270 } 00271 00272 00274 00277 template <class T, class Allocator> 00278 Vector<T, VectFull, Allocator>:: 00279 Vector(const Vector<T, VectFull, Allocator>& V): 00280 Vector_Base<T, Allocator>(V) 00281 { 00282 00283 #ifdef SELDON_CHECK_MEMORY 00284 try 00285 { 00286 #endif 00287 00288 this->data_ = this->vect_allocator_.allocate(V.GetM(), this); 00289 00290 #ifdef SELDON_CHECK_MEMORY 00291 } 00292 catch (...) 00293 { 00294 this->m_ = 0; 00295 this->data_ = NULL; 00296 } 00297 if (this->data_ == NULL) 00298 this->m_ = 0; 00299 if (this->data_ == NULL && V.GetM() != 0) 00300 throw NoMemory("Vector<VectFull>::Vector(Vector<VectFull>&)", 00301 string("Unable to allocate memory for a vector of size ") 00302 + to_str(V.GetM()*sizeof(T)) + " bytes (" 00303 + to_str(V.GetM()) + " elements)."); 00304 #endif 00305 00306 this->vect_allocator_.memorycpy(this->data_, V.GetData(), V.GetM()); 00307 00308 } 00309 00310 00311 /************** 00312 * DESTRUCTOR * 00313 **************/ 00314 00315 00317 template <class T, class Allocator> 00318 Vector<T, VectFull, Allocator>::~Vector() 00319 { 00320 } 00321 00322 00323 /********************* 00324 * MEMORY MANAGEMENT * 00325 *********************/ 00326 00327 00329 00333 template <class T, class Allocator> 00334 inline void Vector<T, VectFull, Allocator>::Clear() 00335 { 00336 this->~Vector(); 00337 } 00338 00339 00341 00347 template <class T, class Allocator> 00348 inline void Vector<T, VectFull, Allocator>::Reallocate(int i) 00349 { 00350 00351 if (i != this->m_) 00352 { 00353 00354 this->m_ = i; 00355 00356 #ifdef SELDON_CHECK_MEMORY 00357 try 00358 { 00359 #endif 00360 00361 this->data_ = 00362 reinterpret_cast<pointer>(this->vect_allocator_ 00363 .reallocate(this->data_, i, this)); 00364 00365 #ifdef SELDON_CHECK_MEMORY 00366 } 00367 catch (...) 00368 { 00369 this->m_ = 0; 00370 this->data_ = NULL; 00371 return; 00372 } 00373 if (this->data_ == NULL) 00374 { 00375 this->m_ = 0; 00376 return; 00377 } 00378 #endif 00379 00380 } 00381 } 00382 00383 00385 00389 template <class T, class Allocator> 00390 inline void Vector<T, VectFull, Allocator>::Resize(int n) 00391 { 00392 00393 if (n == this->m_) 00394 return; 00395 00396 Vector<T, VectFull, Allocator> X_new(n); 00397 for (int i = 0; i < min(this->m_, n); i++) 00398 X_new(i) = this->data_[i]; 00399 00400 SetData(n, X_new.GetData()); 00401 X_new.Nullify(); 00402 } 00403 00404 00420 template <class T, class Allocator> 00421 inline void Vector<T, VectFull, Allocator> 00422 ::SetData(int i, typename Vector<T, VectFull, Allocator>::pointer data) 00423 { 00424 this->Clear(); 00425 00426 this->m_ = i; 00427 00428 this->data_ = data; 00429 } 00430 00431 00433 00445 template <class T, class Allocator> 00446 template <class Allocator0> 00447 inline void Vector<T, VectFull, Allocator> 00448 ::SetData(const Vector<T, VectFull, Allocator0>& V) 00449 { 00450 SetData(V.GetLength(), V.GetData()); 00451 } 00452 00453 00455 00460 template <class T, class Allocator> 00461 void Vector<T, VectFull, Allocator>::Nullify() 00462 { 00463 this->m_ = 0; 00464 this->data_ = NULL; 00465 } 00466 00467 00468 /********************************** 00469 * ELEMENT ACCESS AND AFFECTATION * 00470 **********************************/ 00471 00472 00474 00478 template <class T, class Allocator> 00479 inline typename Vector<T, VectFull, Allocator>::reference 00480 Vector<T, VectFull, Allocator>::operator() (int i) 00481 { 00482 00483 #ifdef SELDON_CHECK_BOUNDS 00484 if (i < 0 || i >= this->m_) 00485 throw WrongIndex("Vector<VectFull>::operator()", 00486 string("Index should be in [0, ") + to_str(this->m_-1) 00487 + "], but is equal to " + to_str(i) + "."); 00488 #endif 00489 00490 return this->data_[i]; 00491 } 00492 00493 00495 00499 template <class T, class Allocator> 00500 inline typename Vector<T, VectFull, Allocator>::reference 00501 Vector<T, VectFull, Allocator>::Get(int i) 00502 { 00503 00504 #ifdef SELDON_CHECK_BOUNDS 00505 if (i < 0 || i >= this->m_) 00506 throw WrongIndex("Vector<VectFull>::Get(int)", 00507 string("Index should be in [0, ") + to_str(this->m_-1) 00508 + "], but is equal to " + to_str(i) + "."); 00509 #endif 00510 00511 return this->data_[i]; 00512 } 00513 00514 00516 00520 template <class T, class Allocator> 00521 inline typename Vector<T, VectFull, Allocator>::const_reference 00522 Vector<T, VectFull, Allocator>::operator() (int i) const 00523 { 00524 00525 #ifdef SELDON_CHECK_BOUNDS 00526 if (i < 0 || i >= this->m_) 00527 throw WrongIndex("Vector<VectFull>::operator() const", 00528 string("Index should be in [0, ") + to_str(this->m_-1) 00529 + "], but is equal to " + to_str(i) + "."); 00530 #endif 00531 00532 return this->data_[i]; 00533 } 00534 00535 00537 00541 template <class T, class Allocator> 00542 inline typename Vector<T, VectFull, Allocator>::const_reference 00543 Vector<T, VectFull, Allocator>::Get(int i) const 00544 { 00545 00546 #ifdef SELDON_CHECK_BOUNDS 00547 if (i < 0 || i >= this->m_) 00548 throw WrongIndex("Vector<VectFull>::Get(int) const", 00549 string("Index should be in [0, ") + to_str(this->m_-1) 00550 + "], but is equal to " + to_str(i) + "."); 00551 #endif 00552 00553 return this->data_[i]; 00554 } 00555 00556 00558 00563 template <class T, class Allocator> 00564 inline Vector<T, VectFull, Allocator>& Vector<T, VectFull, Allocator> 00565 ::operator= (const Vector<T, VectFull, Allocator>& X) 00566 { 00567 this->Copy(X); 00568 00569 return *this; 00570 } 00571 00572 00574 00579 template <class T, class Allocator> 00580 inline void Vector<T, VectFull, Allocator> 00581 ::Copy(const Vector<T, VectFull, Allocator>& X) 00582 { 00583 this->Reallocate(X.GetLength()); 00584 00585 this->vect_allocator_.memorycpy(this->data_, X.GetData(), this->m_); 00586 } 00587 00588 00590 00595 template <class T, class Allocator> 00596 inline Vector<T, VectFull, Allocator> 00597 Vector<T, VectFull, Allocator>::Copy() const 00598 { 00599 return Vector<T, VectFull, Allocator>(*this); 00600 } 00601 00602 00604 00607 template <class T, class Allocator> template<class T0> 00608 inline Vector<T, VectFull, Allocator>& Vector<T, VectFull, Allocator> 00609 ::operator*= (const T0& alpha) 00610 { 00611 for (int i = 0; i < this->m_; i++) 00612 this->data_[i] *= alpha; 00613 00614 return *this; 00615 } 00616 00617 00619 00624 template <class T, class Allocator> 00625 inline void Vector<T, VectFull, Allocator>::Append(const T& x) 00626 { 00627 int i = this->GetLength(); 00628 this->Reallocate(i + 1); 00629 this->data_[i] = x; 00630 } 00631 00632 00634 00637 template <class T, class Allocator> template<class T0> 00638 inline void Vector<T, VectFull, Allocator>::PushBack(const T0& x) 00639 { 00640 Resize(this->m_+1); 00641 this->data_[this->m_-1] = x; 00642 } 00643 00644 00646 00649 template <class T, class Allocator> template<class Allocator0> 00650 inline void Vector<T, VectFull, Allocator> 00651 ::PushBack(const Vector<T, VectFull, Allocator0>& X) 00652 { 00653 int Nold = this->m_; 00654 Resize(this->m_ + X.GetM()); 00655 for (int i = 0; i < X.GetM(); i++) 00656 this->data_[Nold+i] = X(i); 00657 } 00658 00659 00660 /******************* 00661 * BASIC FUNCTIONS * 00662 *******************/ 00663 00664 00666 00669 template <class T, class Allocator> 00670 int Vector<T, VectFull, Allocator>::GetDataSize() 00671 { 00672 return this->m_; 00673 } 00674 00675 00676 /************************ 00677 * CONVENIENT FUNCTIONS * 00678 ************************/ 00679 00680 00682 00686 template <class T, class Allocator> 00687 void Vector<T, VectFull, Allocator>::Zero() 00688 { 00689 this->vect_allocator_.memoryset(this->data_, char(0), 00690 this->GetDataSize() * sizeof(value_type)); 00691 } 00692 00693 00695 template <class T, class Allocator> 00696 void Vector<T, VectFull, Allocator>::Fill() 00697 { 00698 for (int i = 0; i < this->m_; i++) 00699 this->data_[i] = i; 00700 } 00701 00702 00704 00707 template <class T, class Allocator> 00708 template <class T0> 00709 void Vector<T, VectFull, Allocator>::Fill(const T0& x) 00710 { 00711 for (int i = 0; i < this->m_; i++) 00712 this->data_[i] = x; 00713 } 00714 00715 00717 00720 template <class T, class Allocator> 00721 template <class T0> 00722 Vector<T, VectFull, Allocator>& 00723 Vector<T, VectFull, Allocator>::operator= (const T0& x) 00724 { 00725 this->Fill(x); 00726 00727 return *this; 00728 } 00729 00730 00732 00735 template <class T, class Allocator> 00736 void Vector<T, VectFull, Allocator>::FillRand() 00737 { 00738 srand(time(NULL)); 00739 for (int i = 0; i < this->m_; i++) 00740 this->data_[i] = rand(); 00741 } 00742 00743 00745 template <class T, class Allocator> 00746 void Vector<T, VectFull, Allocator>::Print() const 00747 { 00748 for (int i = 0; i < this->GetLength(); i++) 00749 cout << (*this)(i) << "\t"; 00750 cout << endl; 00751 } 00752 00753 00754 /********* 00755 * NORMS * 00756 *********/ 00757 00758 00760 00763 template <class T, class Allocator> 00764 typename Vector<T, VectFull, Allocator>::value_type 00765 Vector<T, VectFull, Allocator>::GetNormInf() const 00766 { 00767 value_type res = value_type(0); 00768 for (int i = 0; i < this->GetLength(); i++) 00769 { 00770 res = max(res, this->data_[i]); 00771 res = max(res, T(-this->data_[i])); 00772 } 00773 00774 return res; 00775 } 00776 00777 00779 00782 template <class T, class Allocator> 00783 int Vector<T, VectFull, Allocator>::GetNormInfIndex() const 00784 { 00785 00786 #ifdef SELDON_CHECK_DIMENSIONS 00787 if (this->GetLength() == 0) 00788 throw WrongDim("Vector<VectFull>::GetNormInfIndex()", 00789 "Vector is null."); 00790 #endif 00791 00792 value_type res = value_type(0), temp; 00793 int j = 0; 00794 for (int i = 0; i < this->GetLength(); i++) 00795 { 00796 temp = res; 00797 res = max(res, this->data_[i]); 00798 res = max(res, T(-this->data_[i])); 00799 if (temp != res) j = i; 00800 } 00801 00802 return j; 00803 } 00804 00805 00806 /************************** 00807 * OUTPUT/INPUT FUNCTIONS * 00808 **************************/ 00809 00810 00812 00818 template <class T, class Allocator> 00819 void Vector<T, VectFull, Allocator> 00820 ::Write(string FileName, bool with_size) const 00821 { 00822 ofstream FileStream; 00823 FileStream.open(FileName.c_str(), ofstream::binary); 00824 00825 #ifdef SELDON_CHECK_IO 00826 // Checks if the file was opened. 00827 if (!FileStream.is_open()) 00828 throw IOError("Vector<VectFull>::Write(string FileName, " 00829 "bool with_size)", 00830 string("Unable to open file \"") + FileName + "\"."); 00831 #endif 00832 00833 this->Write(FileStream, with_size); 00834 00835 FileStream.close(); 00836 } 00837 00838 00840 00846 template <class T, class Allocator> 00847 void Vector<T, VectFull, Allocator> 00848 ::Write(ostream& FileStream, bool with_size) const 00849 { 00850 00851 #ifdef SELDON_CHECK_IO 00852 // Checks if the stream is ready. 00853 if (!FileStream.good()) 00854 throw IOError("Vector<VectFull>::Write(ostream& FileStream, " 00855 "bool with_size)", 00856 "The stream is not ready."); 00857 #endif 00858 00859 if (with_size) 00860 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00861 sizeof(int)); 00862 00863 FileStream.write(reinterpret_cast<char*>(this->data_), 00864 this->m_ * sizeof(value_type)); 00865 00866 #ifdef SELDON_CHECK_IO 00867 // Checks if data was written. 00868 if (!FileStream.good()) 00869 throw IOError("Vector<VectFull>::Write(ostream& FileStream, " 00870 "bool with_size)", 00871 "Output operation failed."); 00872 #endif 00873 00874 } 00875 00876 00878 00883 template <class T, class Allocator> 00884 void Vector<T, VectFull, Allocator>::WriteText(string FileName) const 00885 { 00886 ofstream FileStream; 00887 FileStream.precision(cout.precision()); 00888 FileStream.flags(cout.flags()); 00889 FileStream.open(FileName.c_str()); 00890 00891 #ifdef SELDON_CHECK_IO 00892 // Checks if the file was opened. 00893 if (!FileStream.is_open()) 00894 throw IOError("Vector<VectFull>::WriteText(string FileName)", 00895 string("Unable to open file \"") + FileName + "\"."); 00896 #endif 00897 00898 this->WriteText(FileStream); 00899 00900 FileStream.close(); 00901 } 00902 00903 00905 00910 template <class T, class Allocator> 00911 void Vector<T, VectFull, Allocator>::WriteText(ostream& FileStream) const 00912 { 00913 00914 #ifdef SELDON_CHECK_IO 00915 // Checks if the stream is ready. 00916 if (!FileStream.good()) 00917 throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)", 00918 "The stream is not ready."); 00919 #endif 00920 00921 if (this->GetLength() != 0) 00922 FileStream << (*this)(0); 00923 00924 for (int i = 1; i < this->GetLength(); i++) 00925 FileStream << "\t" << (*this)(i); 00926 00927 #ifdef SELDON_CHECK_IO 00928 // Checks if data was written. 00929 if (!FileStream.good()) 00930 throw IOError("Vector<VectFull>::WriteText(ostream& FileStream)", 00931 "Output operation failed."); 00932 #endif 00933 00934 } 00935 00936 00937 #ifdef SELDON_WITH_HDF5 00938 00939 00945 template <class T, class Allocator> 00946 void Vector<T, VectFull, Allocator>::WriteHDF5(string FileName, 00947 string group_name, 00948 string dataset_name) const 00949 { 00950 hid_t file_id = H5Fopen(FileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); 00951 00952 #ifdef SELDON_CHECK_IO 00953 // Checks if the file was opened. 00954 if (!file_id) 00955 throw IOError("Vector<VectFull>::WriteHDF5(string FileName)", 00956 string("Unable to open file \"") + FileName + "\"."); 00957 #endif 00958 00959 hid_t dataset_id, dataspace_id, group_id; 00960 herr_t status; 00961 00962 T x(0); 00963 hid_t datatype = GetH5Type(x); 00964 00965 if (!H5Lexists(file_id, group_name.c_str(), H5P_DEFAULT)) 00966 group_id = H5Gcreate(file_id, group_name.c_str(), 0); 00967 group_id = H5Gopen(file_id, group_name.c_str()); 00968 00969 if (!H5Lexists(group_id, dataset_name.c_str(), H5P_DEFAULT)) 00970 { 00971 // Create the initial dataspace. 00972 hsize_t dim[1] = {0}; 00973 hsize_t maxdims[1] = {H5S_UNLIMITED}; 00974 dataspace_id = H5Screate_simple(1, dim, maxdims); 00975 00976 // Define chunking parameters to allow extension of the dataspace. 00977 hid_t cparms = H5Pcreate(H5P_DATASET_CREATE); 00978 hsize_t chunk_dims[1] = {this->GetLength()}; 00979 status = H5Pset_chunk(cparms, 1, chunk_dims); 00980 00981 // Create the dataset. 00982 hid_t filetype = H5Tvlen_create(datatype); 00983 dataset_id = H5Dcreate(group_id, dataset_name.c_str(), 00984 filetype, dataspace_id, cparms); 00985 } 00986 00987 // Opens the dataset, and extend it to store a new vector. 00988 dataset_id = H5Dopen(group_id, dataset_name.c_str()); 00989 dataspace_id = H5Dget_space(dataset_id); 00990 hsize_t dims_out[1]; 00991 status = H5Sget_simple_extent_dims(dataspace_id, dims_out, NULL); 00992 hsize_t new_dim[1]= {dims_out[0] + 1}; 00993 status = H5Dextend(dataset_id, new_dim); 00994 00995 // Selects the last memory part of the dataset, to store the vector. 00996 hsize_t offset[1] = {dims_out[0]}; 00997 hsize_t dim2[1] = {1}; 00998 dataspace_id = H5Dget_space(dataset_id); 00999 status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET, 01000 offset, NULL, 01001 dim2, NULL); 01002 01003 // Defines memory space. 01004 hid_t dataspace = H5Screate_simple(1, dim2, NULL); 01005 01006 // Writes the data to the memory hyperslab selected. 01007 hid_t memtype = H5Tvlen_create(datatype); 01008 hvl_t wdata[1]; 01009 wdata[0].len = this->GetLength(); 01010 wdata[0].p = this->GetDataVoid(); 01011 status = H5Dwrite(dataset_id, memtype, dataspace, 01012 dataspace_id, H5P_DEFAULT, wdata); 01013 01014 // Closes the dataset, group and file. 01015 status = H5Dclose(dataset_id); 01016 status = H5Gclose(group_id); 01017 status = H5Fclose(file_id); 01018 } 01019 #endif 01020 01021 01023 01031 template <class T, class Allocator> 01032 void Vector<T, VectFull, Allocator> 01033 ::Read(string FileName, bool with_size) 01034 { 01035 ifstream FileStream; 01036 FileStream.open(FileName.c_str(), ifstream::binary); 01037 01038 #ifdef SELDON_CHECK_IO 01039 // Checks if the file was opened. 01040 if (!FileStream.is_open()) 01041 throw IOError("Vector<VectFull>::Read(string FileName, bool with_size)", 01042 string("Unable to open file \"") + FileName + "\"."); 01043 #endif 01044 01045 this->Read(FileStream, with_size); 01046 01047 FileStream.close(); 01048 } 01049 01050 01052 01060 template <class T, class Allocator> 01061 void Vector<T, VectFull, Allocator> 01062 ::Read(istream& FileStream, bool with_size) 01063 { 01064 01065 #ifdef SELDON_CHECK_IO 01066 // Checks if the stream is ready. 01067 if (!FileStream.good()) 01068 throw IOError("Vector<VectFull>::Read(istream& FileStream, " 01069 "bool with_size)", 01070 "The stream is not ready."); 01071 #endif 01072 01073 if (with_size) 01074 { 01075 int new_size; 01076 FileStream.read(reinterpret_cast<char*>(&new_size), sizeof(int)); 01077 this->Reallocate(new_size); 01078 } 01079 01080 FileStream.read(reinterpret_cast<char*>(this->data_), 01081 this->GetLength() * sizeof(value_type)); 01082 01083 #ifdef SELDON_CHECK_IO 01084 // Checks if data was read. 01085 if (!FileStream.good()) 01086 throw IOError("Vector<VectFull>::Read(istream& FileStream, " 01087 "bool with_size)", 01088 "Output operation failed."); 01089 #endif 01090 01091 } 01092 01093 01095 01100 template <class T, class Allocator> 01101 void Vector<T, VectFull, Allocator>::ReadText(string FileName) 01102 { 01103 ifstream FileStream; 01104 FileStream.open(FileName.c_str()); 01105 01106 #ifdef SELDON_CHECK_IO 01107 // Checks if the file was opened. 01108 if (!FileStream.is_open()) 01109 throw IOError("Vector<VectFull>::ReadText(string FileName)", 01110 string("Unable to open file \"") + FileName + "\"."); 01111 #endif 01112 01113 this->ReadText(FileStream); 01114 01115 FileStream.close(); 01116 } 01117 01118 01120 01125 template <class T, class Allocator> 01126 void Vector<T, VectFull, Allocator>::ReadText(istream& FileStream) 01127 { 01128 // Previous values of the vector are cleared. 01129 Clear(); 01130 01131 #ifdef SELDON_CHECK_IO 01132 // Checks if the stream is ready. 01133 if (!FileStream.good()) 01134 throw IOError("Vector<VectFull>::ReadText(istream& FileStream)", 01135 "The stream is not ready."); 01136 #endif 01137 01138 T entry; 01139 int number_element = 0; 01140 while (!FileStream.eof()) 01141 { 01142 // Reads a new entry. 01143 FileStream >> entry; 01144 01145 if (FileStream.fail()) 01146 break; 01147 else 01148 { 01149 number_element++; 01150 01151 // If needed, resizes the vector. Its size is already doubled so 01152 // that the vector should be resized a limited number of times. 01153 if (number_element > this->m_) 01154 this->Resize(2 * number_element); 01155 01156 this->data_[number_element - 1] = entry; 01157 } 01158 } 01159 01160 // Resizes to the actual size. 01161 if (number_element > 0) 01162 this->Resize(number_element); 01163 else 01164 this->Clear(); 01165 } 01166 01167 01169 01174 template <class T, class Storage, class Allocator> 01175 ostream& operator << (ostream& out, 01176 const Vector<T, Storage, Allocator>& V) 01177 { 01178 for (int i = 0; i < V.GetLength() - 1; i++) 01179 out << V(i) << '\t'; 01180 if (V.GetLength() != 0) 01181 out << V(V.GetLength() - 1); 01182 01183 return out; 01184 } 01185 01186 01187 } // namespace Seldon. 01188 01189 #define SELDON_FILE_VECTOR_CXX 01190 #endif