|
DenseLinAlgPack: Concreate C++ Classes for Dense Blas-Compatible Linear Algebra
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef LINALGPACK_IO_FORMAT_H 00043 #define LINALGPACK_IO_FORMAT_H 00044 00045 #include <ios> 00046 00047 #include "DenseLinAlgPack_IOBasic.hpp" 00048 00049 namespace DenseLinAlgPack { 00050 namespace LinAlgPackIO { 00051 00053 /* * This class is used to encapsulate a set of bit flags. 00054 */ 00055 class bit_flags { 00056 public: 00057 00059 typedef LinAlgPackIO::fmtflags fmtflags; 00060 00062 bit_flags() : flags_((fmtflags)(0x0000)) {} 00063 00065 fmtflags flags() const { 00066 return flags_; 00067 } 00068 00070 fmtflags flags(fmtflags f) { 00071 fmtflags f_tmp = flags_; 00072 flags_ = f; 00073 return f_tmp; 00074 } 00075 00077 fmtflags setf(fmtflags f) { 00078 return flags( (fmtflags)(flags() | f) ); 00079 } 00080 00082 fmtflags setf(fmtflags f, fmtflags mask) { 00083 return flags( (fmtflags)(flags() | (f&mask)) ); 00084 } 00085 00087 void unsetf(fmtflags mask) { 00088 flags( (fmtflags)(flags() & ~mask) ); 00089 } 00090 00091 private: 00092 fmtflags flags_; 00093 00094 }; // end class flags 00095 00097 /* * Memento class that saves the state of a standard stream. 00098 * 00099 * This is a variation of the "Memento" Pattern in Gama et. al. 00100 * 00101 * Allow default copy constructor and assignment operator. 00102 * The default constuctor is private so the only way to 00103 * create an object of this class if from another object 00104 * or from save_format(). 00105 */ 00106 class ios_format_memento { 00107 public: 00109 static ios_format_memento save_format(const std::ios& s); 00110 00112 void set_format(std::ios& s) const; 00113 00114 private: 00115 LinAlgPackIO::fmtflags flags_; 00116 int prec_; 00117 int wdt_; 00118 int fill_; 00119 00121 ios_format_memento() : flags_((fmtflags)(0)), prec_(6), wdt_(0) 00122 , fill_(' ') {} 00123 00124 }; // end class ios_format_memento 00125 00126 template<class T> class bound_format; 00127 template<class T> class const_bound_format; 00128 00130 /* * This class is used to allow some flexiblility in inputing 00131 * and outputing of DVector, DVectorSlice, DMatrix and DMatrixSlice objects. 00132 * It maintains format information for a #std::ios_base# object and adds 00133 * additional format information. 00134 * 00135 * The idea for this class is based on the user-defined manipulator given in 00136 * Stroustrup 1997, p. 635. The main difference is that the non-member funciton 00137 * bind(format,object) is used to create a bound format object and not that 00138 * member function operator(). To use operator() would require a template 00139 * member function and they are not supposed to be allowed in MS VC++ 5.0. 00140 * 00141 * Warning: The default constructor sets the formating flags to false but this 00142 * may not be the default value for the actual ios stream. It is recommended 00143 * that you start with the formating settings of a valid ios stream and then 00144 * change the flags that you want. You can do this on construction with 00145 * 00146 * #format f(cin);#\\ 00147 * 00148 * or after construction using 00149 * 00150 * #format f;#\\ 00151 * #f.copy_format(cin);#\\ 00152 * 00153 * then set the formating using the manipulator like functions. 00154 * 00155 * The default copy constructor and assignment operator functions are allowed. 00156 */ 00157 class format { 00158 public: 00159 00161 typedef LinAlgPackIO::fmtflags fmtflags; 00162 00164 format() : prec_(6), wdt_(0), fill_(' ') {} 00165 00167 format(const std::ios& s) { 00168 copy_format(s); 00169 } 00170 00171 /* * @name Access format flags objects 00172 */ 00173 // @{ 00174 00176 bit_flags& ios_base_flags() { return ios_base_flags_; } 00178 const bit_flags& ios_base_flags() const { return ios_base_flags_; } 00179 00181 bit_flags& extra_flags() { return extra_flags_; } 00183 const bit_flags& extra_flags() const { return extra_flags_; } 00184 00185 // @} 00186 00187 /* * @name Manipulator like functions for standard floating-point number formating. 00188 * 00189 * These member functions are ment to mirror the standard input/output 00190 * manipulator functions. Their names are the same and you can set 00191 * a list of options in one statement like: 00192 * 00193 * #format_obj.showpos().setprecision(6).fixed();#\\ 00194 * 00195 * The primary difference is that #width# presists over all uses in output 00196 * operations while the standard #width# manipulator only applys to the next 00197 * operation. See \Ref{bound_format} and \Ref{operator>>} for details 00198 * on how objects of this class are used to specify formating for input/output 00199 * operations. 00200 */ 00201 // @{ 00202 00204 format& showpoint() { ios_base_flags().setf(std::ios_base::showpoint); return *this; } 00206 format& noshowpoint() { ios_base_flags().unsetf(std::ios_base::showpoint); return *this; } 00208 format& showpos() { ios_base_flags().setf(std::ios_base::showpos); return *this; } 00210 format& noshowpos() { ios_base_flags().unsetf(std::ios_base::showpos); return *this; } 00212 format& skipws() { ios_base_flags().setf(std::ios_base::skipws); return *this; } 00214 format& noskipws() { ios_base_flags().unsetf(std::ios_base::skipws); return *this; } 00216 format& uppercase() { ios_base_flags().setf(std::ios_base::uppercase); return *this; } 00218 format& nouppercase() { ios_base_flags().unsetf(std::ios_base::uppercase); return *this; } 00220 format& internal() { 00221 ios_base_flags().setf(std::ios_base::internal, std::ios_base::adjustfield); 00222 return *this; 00223 } 00225 format& left() { 00226 ios_base_flags().setf(std::ios_base::left, std::ios_base::adjustfield); 00227 return *this; 00228 } 00230 format& right() { 00231 ios_base_flags().setf(std::ios_base::right, std::ios_base::adjustfield); 00232 return *this; 00233 } 00235 format& general() { 00236 ios_base_flags().setf((fmtflags)0, std::ios_base::floatfield); 00237 return *this; 00238 } 00240 format& fixed() { 00241 ios_base_flags().setf(std::ios_base::fixed, std::ios_base::floatfield); 00242 return *this; 00243 } 00245 format& scientific() { 00246 ios_base_flags().setf(std::ios_base::scientific, std::ios_base::floatfield); 00247 return *this; 00248 } 00250 format& setfill(int c) { fill_ = c; return *this; } 00252 format& setprecision(int p) { prec_ = p; return *this; } 00254 format& setw(int w) { wdt_ = w; return *this; } 00255 00256 // @} 00257 00258 /* * @name Manipulator like functions for extra I/O formatin. 00259 * 00260 * These member functions are ment to mirror the type of standard input/output 00261 * manipulator functions accept they are used to set extra flags for 00262 * #DenseLinAlgPack::ignore_dim_bit# and #DenseLinAlgPack::no_insert_newlines_bit#. 00263 * This allows them to be set in the same statement that sets a standard 00264 * option. For example you can write: 00265 * 00266 * #format_obj.showpos().setprecision(6).fixed().ignore_dim().no_insert_newlines();#\\ 00267 * 00268 * Like the member functions that simulate the standard manipulators these 00269 * options presist after input/output operations. 00270 */ 00271 // @{ 00272 00274 format& ignore_dim() 00275 { 00276 extra_flags().setf((fmtflags)(ignore_dim_bit)); 00277 return *this; 00278 } 00280 format& no_ignore_dim() 00281 { 00282 extra_flags().unsetf((fmtflags)(ignore_dim_bit)); 00283 return *this; 00284 } 00286 format& insert_newlines() 00287 { 00288 extra_flags().unsetf((fmtflags)(no_insert_newlines_bit)); 00289 return *this; 00290 } 00292 format& no_insert_newlines() 00293 { 00294 extra_flags().setf((fmtflags)(no_insert_newlines_bit)); 00295 return *this; 00296 } 00297 00298 // @} 00299 00300 /* * @name Other access functions 00301 */ 00302 // @{ 00303 00305 int precision() const { return prec_; } 00307 int precision(int p) { int tmp = prec_; prec_ = p; return tmp; } 00309 int width() const { return wdt_; } 00311 int width(int w) { int tmp = wdt_; wdt_ = w; return tmp; } 00313 int fill() const { return fill_; } 00315 int fill(int c) { int tmp = fill_; fill_ = c; return tmp; } 00316 00317 // @} 00318 00319 /* * @name Utility functions for saving and replacing a streams format state 00320 */ 00321 // @{ 00322 00324 void copy_format(const std::ios& s); 00325 00327 void set_format(std::ios& s) const; 00328 00329 // @} 00330 00331 00332 // ToDo: Enable these once member templates are supported. This is much more 00333 // attractive syntasticaly than using bind() and cbind() 00334 // 00335 // /// 00336 // template<class T> 00337 // bound_format<T> operator()(T& obj); 00338 // 00339 // /// 00340 // template<class T> 00341 // const_bound_format<T> operator()(const T& obj) const; 00342 00343 private: 00344 bit_flags ios_base_flags_; 00345 bit_flags extra_flags_; 00346 int prec_; 00347 int wdt_; 00348 int fill_; 00349 00350 }; // end class LinAlgPackIOFormat 00351 00352 00353 // //////////////////////////////////////////////////////////////////////////////// 00354 // Format binding classes and functions 00355 00356 template<class T> class const_bound_format; 00357 00359 /* * Special I/O manipulator class for non-constant objects. 00360 * 00361 * This class as a special manipulator and is composed of a composition 00362 * of a format object and a templated object that is used in an input 00363 * or output operation. 00364 * 00365 * An object of this class should only be created by using 00366 * the bind(format,obj) function. It object can not default constructed 00367 * or assigned. 00368 * 00369 * Objects of this class can be implicitly converted to const_bound_format 00370 * for use in output operations. 00371 */ 00372 template<class T> 00373 class bound_format { 00374 public: 00375 00377 bound_format(const format& f, T& obj) : f_(f), obj_(obj) {} 00378 00380 const format& f() const { return f_; } 00382 T& obj() { return obj_; } 00384 const T& obj() const { return obj_; } 00385 00386 private: 00387 const format& f_; 00388 T& obj_; 00389 00390 // not defined and not to be called 00391 bound_format(); 00392 bound_format& operator=(const bound_format&); 00393 00394 }; // end class bound_format 00395 00397 /* * Special I/O manipulator class for constant objects. 00398 * 00399 * This class as a special manipulator and is composed of a composition 00400 * of a format object and a const templated object that is used only in 00401 * an output operation. 00402 * 00403 * An object of this class can only be created by using 00404 * the bind(f,obj) operation. It can not be default constructed or assigned. 00405 * It is only to be used in input or output operations. 00406 */ 00407 template<class T> 00408 class const_bound_format { 00409 public: 00410 00412 const_bound_format(const format& f, const T& obj) : f_(f), obj_(obj) {} 00413 00415 const_bound_format(const bound_format<T>& bf) : f_(bf.f()), obj_(bf.obj()) {} 00416 00418 const format& f() const { return f_; } 00420 const T& obj() const { return obj_; } 00421 00422 private: 00423 const format& f_; 00424 const T& obj_; 00425 00426 // not defined and not to be called 00427 const_bound_format(); 00428 const_bound_format& operator=(const const_bound_format&); 00429 00430 }; // end class const_bound_format 00431 00433 /* * Returns a bound_format<T> object using this format object. 00434 * 00435 * Using templated input/output operator functions this function 00436 * is used to bind a format to a non-const target object for a 00437 * input/output stream operation. For example, to bind the format 00438 * for a single output operation using the streams set formating 00439 * and addition formating use something like: 00440 * 00441 * #DVector v(1.0,5);#\\ 00442 * #format f; f.copy_format(cout);#\\ 00443 * #f.width(10).fixed().ignore_dim();#\\ 00444 * #cout << bind(f,v);#\\1 00445 */ 00446 template<class T> 00447 inline bound_format<T> bind(const format& f, T& obj) { 00448 return bound_format<T>(f,obj); 00449 } 00450 00452 /* * Returns a const_bound_format<T> using this format object. 00453 * 00454 * This function works the same as the previous \Ref{bind}#()# function 00455 * accept it is for a const target object. It could not use 00456 * the name #bind# due to ambiguity problems. 00457 */ 00458 template<class T> 00459 inline const_bound_format<T> cbind(const format& f, const T& obj) { 00460 return const_bound_format<T>(f,obj); 00461 } 00462 00463 // /////////////////////////////////////// 00464 // Inline functions for members of format 00465 00466 // Use once member templates are supported. See class format 00467 // 00468 //template<class T> 00469 //inline bound_format<T> format::operator()(T& obj) { 00470 // return bind(*this,obj); 00471 //} 00472 00473 //template<class T> 00474 //inline const_bound_format<T> format::operator()(const T& obj) const { 00475 // return cbind(*this,obj); 00476 //} 00477 00478 } // end namespace LinAlgPackIO 00479 } // end namespace DenseLinAlgPack 00480 00481 #endif // LINALGPACK_IO_FORMAT_H
1.7.6.1