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 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_TABULAR_OUTPUTTER_HPP
11 #define TEUCHOS_TABULAR_OUTPUTTER_HPP
12 
13 
14 #include "Teuchos_FancyOStream.hpp"
15 #include "Teuchos_Array.hpp"
16 #include "Teuchos_Tuple.hpp"
17 #include "Teuchos_RCP.hpp"
18 #include "Teuchos_Time.hpp"
19 #include "Teuchos_Exceptions.hpp"
20 
21 
22 namespace Teuchos {
23 
24 
29 class TEUCHOSCORE_LIB_DLL_EXPORT TabularOutputter {
30 public:
31 
34 
36  enum EFieldType { DOUBLE, INT, STRING };
37  enum { numFieldTypes = 3 };
38 
40  enum EFieldJustification { LEFT, RIGHT };
41  enum { numFieldJustifications = 2 };
42 
44  enum EFloatingOutputType { SCIENTIFIC, GENERAL };
45  enum { numFloatingOutputTypes = 2 };
46 
49  {public:MissingFieldsError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
50 
53  {public:InvalidFieldSpecError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
54 
57  {public:MissingHeaderError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
58 
61  {public:InvalidFieldOutputError(const std::string& what_arg) : ExceptionBase(what_arg) {}};
62 
64 
66  TabularOutputter(std::ostream &out);
67 
70 
72  void setOStream( const RCP<std::ostream> &out );
73 
75  void pushFieldSpec( const std::string &fieldName,
76  const EFieldType fieldType = DOUBLE,
77  const EFieldJustification fieldJustification = RIGHT,
78  const EFloatingOutputType floatingOutputType = SCIENTIFIC,
79  const int width = -1
80  );
81 
86  void setFieldTypePrecision( const EFieldType fieldType, const int prec );
87 
89  void outputHeader();
90 
92  template<typename T>
93  void outputField( const T& t );
94 
96  void nextRow(const bool allowRemainingFields = false);
97 
98 private:
99 
100  // Private types
101 
102  struct FieldSpec {
103  FieldSpec(std::string fieldName_in, EFieldType fieldType_in,
104  EFieldJustification fieldJustification_in,
105  EFloatingOutputType floatingOutputType_in,
106  const int outputWidth_in
107  )
108  :fieldName(fieldName_in), fieldType(fieldType_in),
109  fieldJustification(fieldJustification_in),
110  floatingOutputType(floatingOutputType_in),
111  outputWidth(outputWidth_in),
112  precision(-1) // Gets set later
113  {}
114  std::string fieldName;
115  EFieldType fieldType;
116  EFieldJustification fieldJustification;
117  EFloatingOutputType floatingOutputType;
118  int outputWidth;
119  int precision;
120  };
121 
122  // Private data members
123 
124  static const std::string fieldSpacer_;
125 
126 //use pragmas to disable some false-positive warnings for windows sharedlibs export
127 #ifdef _MSC_VER
128 #pragma warning(push)
129 #pragma warning(disable:4251)
130 #endif
131  Array<FieldSpec> fieldSpecs_;
132  RCP<FancyOStream> out_;
133  Tuple<int,numFieldTypes> fieldTypePrecision_;
134 #ifdef _MSC_VER
135 #pragma warning(pop)
136 #endif
137 
138  int currFieldIdx_;
139 
140  Time timer_;
141  int numLoops_;
142 
143  // Private member functions
144 
145  void initialize();
146 
147  double adjustTime( const double &time_in )
148  {
149  return ( time_in > 0.0 ? time_in : -1.0 );
150  }
151 
152 public: // Should be hidden
153 
154  void startTimer(const int numLoops)
155  {
156  timer_.reset();
157  timer_.start();
158  numLoops_ = numLoops;
159  }
160 
161  double stopTimer()
162  {
163 #ifdef TEUCHOS_DEBUG
164  TEUCHOS_TEST_FOR_EXCEPT(numLoops_ == -1);
165 #endif
166  timer_.stop();
167  const double relTime =
168  adjustTime(timer_.totalElapsedTime()) / numLoops_;
169  numLoops_ = -1;
170  return relTime;
171  }
172 
173 private:
174 
175  // Not defined and not to be called!
176  TabularOutputter();
177 
178 };
179 
180 
182 #define TEUCHOS_START_PERF_OUTPUT_TIMER(OUTPUTTER, NUMLOOPS) \
183  (OUTPUTTER).startTimer(NUMLOOPS); \
184  for ( int k = 0; k < (NUMLOOPS); ++k )
185 
186 
188 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \
189  (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \
190  for ( int k = 0; k < (NUMLOOPS); ++k )
191 
192 
194 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \
195  (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \
196  for ( int k = 0; k < (NUMLOOPS); ++k )
197 
198 
202 #define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME) \
203  const double VARNAME = (OUTPUTTER).stopTimer(); \
204  (OUTPUTTER).outputField(VARNAME)
205 
206 
207 //
208 // Implementations
209 //
210 
211 
212 template<typename T>
214 {
215 
216  using std::setw;
217 
218 #ifdef TEUCHOS_DEBUG
220  currFieldIdx_ == -1,
222  "Error, you can not output a field until you print the header with"
223  " outputHeader()."
224  );
226  !(currFieldIdx_ < as<int>(fieldSpecs_.size())),
228  "Error, you have already output all of the "
229  << fieldSpecs_.size() << " fields for this tabular output."
230  " You must call nextRow() before outputting to the next row."
231  );
232 #endif
233 
234  FieldSpec &fieldSpec = fieldSpecs_[currFieldIdx_];
235 
236  *out_ << fieldSpacer_ << std::setprecision(fieldSpec.precision);
237 
238  switch(fieldSpec.fieldJustification) {
239  case LEFT:
240  *out_ << std::left;
241  break;
242  case RIGHT:
243  *out_ << std::right;
244  break;
245  default: {
247  }
248  }
249 
250  switch(fieldSpec.floatingOutputType) {
251  case SCIENTIFIC:
252  *out_ << std::scientific;
253  break;
254  case GENERAL:
255  *out_ << std::fixed;
256  break;
257  default: {
259  }
260  }
261 
262  *out_ << setw(fieldSpec.outputWidth) << t;
263 
264  ++currFieldIdx_;
265 
266 }
267 
268 
269 
270 } // namespace Teuchos
271 
272 
273 #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...