Teuchos - Trilinos Tools Package  Version of the Day
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!
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.
void reset()
Reset the cummulative time and call count.
Utility class that makes it easy to create formatted tables of output.
void start(bool reset=false)
Start the timer, if the timer is enabled (see disable()).
double stop()
Stop the timer, if the timer is enabled (see disable()).
Wall-clock timer.
Templated array class derived from the STL std::vector.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
double totalElapsedTime(bool readCurrentTime=false) const
The total time in seconds accumulated by this timer.
Smart reference counting pointer class for automatic garbage collection.
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...