Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_TabularOutputter.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) 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 Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_TABULAR_OUTPUTTER_HPP
43 #define TEUCHOS_TABULAR_OUTPUTTER_HPP
44 
45 
46 #include "Teuchos_FancyOStream.hpp"
47 #include "Teuchos_Array.hpp"
48 #include "Teuchos_Tuple.hpp"
49 #include "Teuchos_RCP.hpp"
50 #include "Teuchos_Time.hpp"
51 #include "Teuchos_Exceptions.hpp"
52 
53 
54 namespace Teuchos {
55 
56 
61 class TEUCHOSCORE_LIB_DLL_EXPORT TabularOutputter {
62 public:
63 
66 
68  enum EFieldType { DOUBLE, INT, STRING };
69  enum { numFieldTypes = 3 };
70 
72  enum EFieldJustification { LEFT, RIGHT };
73  enum { numFieldJustifications = 2 };
74 
76  enum EFloatingOutputType { SCIENTIFIC, GENERAL };
77  enum { numFloatingOutputTypes = 2 };
78 
81  {public:MissingFieldsError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
82 
85  {public:InvalidFieldSpecError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
86 
89  {public:MissingHeaderError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
90 
93  {public:InvalidFieldOutputError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
94 
96 
98  TabularOutputter(std::ostream &out);
99 
102 
104  void setOStream( const RCP<std::ostream> &out );
105 
107  void pushFieldSpec( const std::string &fieldName,
108  const EFieldType fieldType = DOUBLE,
109  const EFieldJustification fieldJustification = RIGHT,
110  const EFloatingOutputType floatingOutputType = SCIENTIFIC,
111  const int width = -1
112  );
113 
118  void setFieldTypePrecision( const EFieldType fieldType, const int prec );
119 
121  void outputHeader();
122 
124  template<typename T>
125  void outputField( const T& t );
126 
128  void nextRow(const bool allowRemainingFields = false);
129 
130 private:
131 
132  // Private types
133 
134  struct FieldSpec {
135  FieldSpec(std::string fieldName_in, EFieldType fieldType_in,
136  EFieldJustification fieldJustification_in,
137  EFloatingOutputType floatingOutputType_in,
138  const int outputWidth_in
139  )
140  :fieldName(fieldName_in), fieldType(fieldType_in),
141  fieldJustification(fieldJustification_in),
142  floatingOutputType(floatingOutputType_in),
143  outputWidth(outputWidth_in),
144  precision(-1) // Gets set later
145  {}
146  std::string fieldName;
147  EFieldType fieldType;
148  EFieldJustification fieldJustification;
149  EFloatingOutputType floatingOutputType;
150  int outputWidth;
151  int precision;
152  };
153 
154  // Private data members
155 
156  static const std::string fieldSpacer_;
157 
158 //use pragmas to disable some false-positive warnings for windows sharedlibs export
159 #ifdef _MSC_VER
160 #pragma warning(push)
161 #pragma warning(disable:4251)
162 #endif
163  Array<FieldSpec> fieldSpecs_;
164  RCP<FancyOStream> out_;
165  Tuple<int,numFieldTypes> fieldTypePrecision_;
166 #ifdef _MSC_VER
167 #pragma warning(pop)
168 #endif
169 
170  int currFieldIdx_;
171 
172  Time timer_;
173  int numLoops_;
174 
175  // Private member functions
176 
177  void initialize();
178 
179  double adjustTime( const double &time_in )
180  {
181  return ( time_in > 0.0 ? time_in : -1.0 );
182  }
183 
184 public: // Should be hidden
185 
186  void startTimer(const int numLoops)
187  {
188  timer_.reset();
189  timer_.start();
190  numLoops_ = numLoops;
191  }
192 
193  double stopTimer()
194  {
195 #ifdef TEUCHOS_DEBUG
196  TEUCHOS_TEST_FOR_EXCEPT(numLoops_ == -1);
197 #endif
198  timer_.stop();
199  const double relTime =
200  adjustTime(timer_.totalElapsedTime()) / numLoops_;
201  numLoops_ = -1;
202  return relTime;
203  }
204 
205 private:
206 
207  // Not defined and not to be called!
208  TabularOutputter();
209 
210 };
211 
212 
214 #define TEUCHOS_START_PERF_OUTPUT_TIMER(OUTPUTTER, NUMLOOPS) \
215  (OUTPUTTER).startTimer(NUMLOOPS); \
216  for ( int k = 0; k < (NUMLOOPS); ++k )
217 
218 
220 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \
221  (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \
222  for ( int k = 0; k < (NUMLOOPS); ++k )
223 
224 
226 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \
227  (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \
228  for ( int k = 0; k < (NUMLOOPS); ++k )
229 
230 
234 #define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME) \
235  const double VARNAME = (OUTPUTTER).stopTimer(); \
236  (OUTPUTTER).outputField(VARNAME)
237 
238 
239 //
240 // Implementations
241 //
242 
243 
244 template<typename T>
246 {
247 
248  using std::setw;
249 
250 #ifdef TEUCHOS_DEBUG
252  currFieldIdx_ == -1,
254  "Error, you can not output a field until you print the header with"
255  " outputHeader()."
256  );
258  !(currFieldIdx_ < as<int>(fieldSpecs_.size())),
260  "Error, you have already output all of the "
261  << fieldSpecs_.size() << " fields for this tabular output."
262  " You must call nextRow() before outputting to the next row."
263  );
264 #endif
265 
266  FieldSpec &fieldSpec = fieldSpecs_[currFieldIdx_];
267 
268  *out_ << fieldSpacer_ << std::setprecision(fieldSpec.precision);
269 
270  switch(fieldSpec.fieldJustification) {
271  case LEFT:
272  *out_ << std::left;
273  break;
274  case RIGHT:
275  *out_ << std::right;
276  break;
277  default: {
279  }
280  }
281 
282  switch(fieldSpec.floatingOutputType) {
283  case SCIENTIFIC:
284  *out_ << std::scientific;
285  break;
286  case GENERAL:
287  *out_ << std::fixed;
288  break;
289  default: {
291  }
292  }
293 
294  *out_ << setw(fieldSpec.outputWidth) << t;
295 
296  ++currFieldIdx_;
297 
298 }
299 
300 
301 
302 } // namespace Teuchos
303 
304 
305 #endif // TEUCHOS_TABULAR_OUTPUTTER_HPP
void outputField(const T &t)
Output to the next field.
Basic wall-clock timer class.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Utility class that makes it easy to create formatted tables of output.
Templated array class derived from the STL std::vector.
size_type size() const
Base exception class for Teuchos.
Reference-counted pointer class and non-member templated function implementations.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call...