DenseLinAlgPack: Concreate C++ Classes for Dense Blas-Compatible Linear Algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DenseLinAlgPack_IOFormat.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef LINALGPACK_IO_FORMAT_H
43 #define LINALGPACK_IO_FORMAT_H
44 
45 #include <ios>
46 
47 #include "DenseLinAlgPack_IOBasic.hpp"
48 
49 namespace DenseLinAlgPack {
50 namespace LinAlgPackIO {
51 
53 /* * This class is used to encapsulate a set of bit flags.
54  */
55 class bit_flags {
56 public:
57 
59  typedef LinAlgPackIO::fmtflags fmtflags;
60 
62  bit_flags() : flags_((fmtflags)(0x0000)) {}
63 
65  fmtflags flags() const {
66  return flags_;
67  }
68 
71  fmtflags f_tmp = flags_;
72  flags_ = f;
73  return f_tmp;
74  }
75 
78  return flags( (fmtflags)(flags() | f) );
79  }
80 
83  return flags( (fmtflags)(flags() | (f&mask)) );
84  }
85 
87  void unsetf(fmtflags mask) {
88  flags( (fmtflags)(flags() & ~mask) );
89  }
90 
91 private:
92  fmtflags flags_;
93 
94 }; // end class flags
95 
97 /* * Memento class that saves the state of a standard stream.
98  *
99  * This is a variation of the "Memento" Pattern in Gama et. al.
100  *
101  * Allow default copy constructor and assignment operator.
102  * The default constuctor is private so the only way to
103  * create an object of this class if from another object
104  * or from save_format().
105  */
107 public:
109  static ios_format_memento save_format(const std::ios& s);
110 
112  void set_format(std::ios& s) const;
113 
114 private:
115  LinAlgPackIO::fmtflags flags_;
116  int prec_;
117  int wdt_;
118  int fill_;
119 
121  ios_format_memento() : flags_((fmtflags)(0)), prec_(6), wdt_(0)
122  , fill_(' ') {}
123 
124 }; // end class ios_format_memento
125 
126 template<class T> class bound_format;
127 template<class T> class const_bound_format;
128 
130 /* * This class is used to allow some flexiblility in inputing
131  * and outputing of DVector, DVectorSlice, DMatrix and DMatrixSlice objects.
132  * It maintains format information for a #std::ios_base# object and adds
133  * additional format information.
134  *
135  * The idea for this class is based on the user-defined manipulator given in
136  * Stroustrup 1997, p. 635. The main difference is that the non-member funciton
137  * bind(format,object) is used to create a bound format object and not that
138  * member function operator(). To use operator() would require a template
139  * member function and they are not supposed to be allowed in MS VC++ 5.0.
140  *
141  * Warning: The default constructor sets the formating flags to false but this
142  * may not be the default value for the actual ios stream. It is recommended
143  * that you start with the formating settings of a valid ios stream and then
144  * change the flags that you want. You can do this on construction with
145  *
146  * #format f(cin);#\\
147  *
148  * or after construction using
149  *
150  * #format f;#\\
151  * #f.copy_format(cin);#\\
152  *
153  * then set the formating using the manipulator like functions.
154  *
155  * The default copy constructor and assignment operator functions are allowed.
156  */
157 class format {
158 public:
159 
161  typedef LinAlgPackIO::fmtflags fmtflags;
162 
164  format() : prec_(6), wdt_(0), fill_(' ') {}
165 
167  format(const std::ios& s) {
168  copy_format(s);
169  }
170 
171  /* * @name Access format flags objects
172  */
173  // @{
174 
176  bit_flags& ios_base_flags() { return ios_base_flags_; }
178  const bit_flags& ios_base_flags() const { return ios_base_flags_; }
179 
181  bit_flags& extra_flags() { return extra_flags_; }
183  const bit_flags& extra_flags() const { return extra_flags_; }
184 
185  // @}
186 
187  /* * @name Manipulator like functions for standard floating-point number formating.
188  *
189  * These member functions are ment to mirror the standard input/output
190  * manipulator functions. Their names are the same and you can set
191  * a list of options in one statement like:
192  *
193  * #format_obj.showpos().setprecision(6).fixed();#\\
194  *
195  * The primary difference is that #width# presists over all uses in output
196  * operations while the standard #width# manipulator only applys to the next
197  * operation. See \Ref{bound_format} and \Ref{operator>>} for details
198  * on how objects of this class are used to specify formating for input/output
199  * operations.
200  */
201  // @{
202 
204  format& showpoint() { ios_base_flags().setf(std::ios_base::showpoint); return *this; }
206  format& noshowpoint() { ios_base_flags().unsetf(std::ios_base::showpoint); return *this; }
208  format& showpos() { ios_base_flags().setf(std::ios_base::showpos); return *this; }
210  format& noshowpos() { ios_base_flags().unsetf(std::ios_base::showpos); return *this; }
212  format& skipws() { ios_base_flags().setf(std::ios_base::skipws); return *this; }
214  format& noskipws() { ios_base_flags().unsetf(std::ios_base::skipws); return *this; }
216  format& uppercase() { ios_base_flags().setf(std::ios_base::uppercase); return *this; }
218  format& nouppercase() { ios_base_flags().unsetf(std::ios_base::uppercase); return *this; }
220  format& internal() {
221  ios_base_flags().setf(std::ios_base::internal, std::ios_base::adjustfield);
222  return *this;
223  }
226  ios_base_flags().setf(std::ios_base::left, std::ios_base::adjustfield);
227  return *this;
228  }
231  ios_base_flags().setf(std::ios_base::right, std::ios_base::adjustfield);
232  return *this;
233  }
236  ios_base_flags().setf((fmtflags)0, std::ios_base::floatfield);
237  return *this;
238  }
241  ios_base_flags().setf(std::ios_base::fixed, std::ios_base::floatfield);
242  return *this;
243  }
246  ios_base_flags().setf(std::ios_base::scientific, std::ios_base::floatfield);
247  return *this;
248  }
250  format& setfill(int c) { fill_ = c; return *this; }
252  format& setprecision(int p) { prec_ = p; return *this; }
254  format& setw(int w) { wdt_ = w; return *this; }
255 
256  // @}
257 
258  /* * @name Manipulator like functions for extra I/O formatin.
259  *
260  * These member functions are ment to mirror the type of standard input/output
261  * manipulator functions accept they are used to set extra flags for
262  * #DenseLinAlgPack::ignore_dim_bit# and #DenseLinAlgPack::no_insert_newlines_bit#.
263  * This allows them to be set in the same statement that sets a standard
264  * option. For example you can write:
265  *
266  * #format_obj.showpos().setprecision(6).fixed().ignore_dim().no_insert_newlines();#\\
267  *
268  * Like the member functions that simulate the standard manipulators these
269  * options presist after input/output operations.
270  */
271  // @{
272 
275  {
276  extra_flags().setf((fmtflags)(ignore_dim_bit));
277  return *this;
278  }
281  {
282  extra_flags().unsetf((fmtflags)(ignore_dim_bit));
283  return *this;
284  }
287  {
288  extra_flags().unsetf((fmtflags)(no_insert_newlines_bit));
289  return *this;
290  }
293  {
294  extra_flags().setf((fmtflags)(no_insert_newlines_bit));
295  return *this;
296  }
297 
298  // @}
299 
300  /* * @name Other access functions
301  */
302  // @{
303 
305  int precision() const { return prec_; }
307  int precision(int p) { int tmp = prec_; prec_ = p; return tmp; }
309  int width() const { return wdt_; }
311  int width(int w) { int tmp = wdt_; wdt_ = w; return tmp; }
313  int fill() const { return fill_; }
315  int fill(int c) { int tmp = fill_; fill_ = c; return tmp; }
316 
317  // @}
318 
319  /* * @name Utility functions for saving and replacing a streams format state
320  */
321  // @{
322 
324  void copy_format(const std::ios& s);
325 
327  void set_format(std::ios& s) const;
328 
329  // @}
330 
331 
332 // ToDo: Enable these once member templates are supported. This is much more
333 // attractive syntasticaly than using bind() and cbind()
334 //
335 // ///
336 // template<class T>
337 // bound_format<T> operator()(T& obj);
338 //
339 // ///
340 // template<class T>
341 // const_bound_format<T> operator()(const T& obj) const;
342 
343 private:
344  bit_flags ios_base_flags_;
345  bit_flags extra_flags_;
346  int prec_;
347  int wdt_;
348  int fill_;
349 
350 }; // end class LinAlgPackIOFormat
351 
352 
353 // ////////////////////////////////////////////////////////////////////////////////
354 // Format binding classes and functions
355 
356 template<class T> class const_bound_format;
357 
359 /* * Special I/O manipulator class for non-constant objects.
360  *
361  * This class as a special manipulator and is composed of a composition
362  * of a format object and a templated object that is used in an input
363  * or output operation.
364  *
365  * An object of this class should only be created by using
366  * the bind(format,obj) function. It object can not default constructed
367  * or assigned.
368  *
369  * Objects of this class can be implicitly converted to const_bound_format
370  * for use in output operations.
371  */
372 template<class T>
373 class bound_format {
374 public:
375 
377  bound_format(const format& f, T& obj) : f_(f), obj_(obj) {}
378 
380  const format& f() const { return f_; }
382  T& obj() { return obj_; }
384  const T& obj() const { return obj_; }
385 
386 private:
387  const format& f_;
388  T& obj_;
389 
390  // not defined and not to be called
391  bound_format();
392  bound_format& operator=(const bound_format&);
393 
394 }; // end class bound_format
395 
397 /* * Special I/O manipulator class for constant objects.
398  *
399  * This class as a special manipulator and is composed of a composition
400  * of a format object and a const templated object that is used only in
401  * an output operation.
402  *
403  * An object of this class can only be created by using
404  * the bind(f,obj) operation. It can not be default constructed or assigned.
405  * It is only to be used in input or output operations.
406  */
407 template<class T>
408 class const_bound_format {
409 public:
410 
412  const_bound_format(const format& f, const T& obj) : f_(f), obj_(obj) {}
413 
415  const_bound_format(const bound_format<T>& bf) : f_(bf.f()), obj_(bf.obj()) {}
416 
418  const format& f() const { return f_; }
420  const T& obj() const { return obj_; }
421 
422 private:
423  const format& f_;
424  const T& obj_;
425 
426  // not defined and not to be called
428  const_bound_format& operator=(const const_bound_format&);
429 
430 }; // end class const_bound_format
431 
433 /* * Returns a bound_format<T> object using this format object.
434  *
435  * Using templated input/output operator functions this function
436  * is used to bind a format to a non-const target object for a
437  * input/output stream operation. For example, to bind the format
438  * for a single output operation using the streams set formating
439  * and addition formating use something like:
440  *
441  * #DVector v(1.0,5);#\\
442  * #format f; f.copy_format(cout);#\\
443  * #f.width(10).fixed().ignore_dim();#\\
444  * #cout << bind(f,v);#\\1
445  */
446 template<class T>
447 inline bound_format<T> bind(const format& f, T& obj) {
448  return bound_format<T>(f,obj);
449 }
450 
452 /* * Returns a const_bound_format<T> using this format object.
453  *
454  * This function works the same as the previous \Ref{bind}#()# function
455  * accept it is for a const target object. It could not use
456  * the name #bind# due to ambiguity problems.
457  */
458 template<class T>
459 inline const_bound_format<T> cbind(const format& f, const T& obj) {
460  return const_bound_format<T>(f,obj);
461 }
462 
463 // ///////////////////////////////////////
464 // Inline functions for members of format
465 
466 // Use once member templates are supported. See class format
467 //
468 //template<class T>
469 //inline bound_format<T> format::operator()(T& obj) {
470 // return bind(*this,obj);
471 //}
472 
473 //template<class T>
474 //inline const_bound_format<T> format::operator()(const T& obj) const {
475 // return cbind(*this,obj);
476 //}
477 
478 } // end namespace LinAlgPackIO
479 } // end namespace DenseLinAlgPack
480 
481 #endif // LINALGPACK_IO_FORMAT_H
void set_format(std::ios &s) const
Reset a steams format.
static ios_format_memento save_format(const std::ios &s)
Save a streams format.
void set_format(std::ios &s) const
Set a streams format to the one in this object.
fmtflags flags(fmtflags f)
Set the flags.
fmtflags setf(fmtflags f, fmtflags mask)
Set a flag under a mask.
void unsetf(fmtflags mask)
Unset a flag(s)
void copy_format(const std::ios &s)
Copy a streams format to this object.
const_bound_format(const bound_format< T > &bf)
Allow implicit conversion from a bound_format to a const bound_format.
bit_flags()
Initialize the flags to 0x0000.
format(const std::ios &s)
Copy the formats from a ios stream (This is the suggested method.