|
Teuchos - Trilinos Tools Package Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) 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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef TEUCHOS_TABULAR_OUTPUTTER_HPP 00030 #define TEUCHOS_TABULAR_OUTPUTTER_HPP 00031 00032 00033 #include "Teuchos_FancyOStream.hpp" 00034 #include "Teuchos_Array.hpp" 00035 #include "Teuchos_Tuple.hpp" 00036 #include "Teuchos_RCP.hpp" 00037 #include "Teuchos_Time.hpp" 00038 #include "Teuchos_Exceptions.hpp" 00039 00040 00041 namespace Teuchos { 00042 00043 00048 class TEUCHOS_LIB_DLL_EXPORT TabularOutputter { 00049 public: 00050 00053 00055 enum EFieldType { DOUBLE, INT, STRING }; 00056 enum { numFieldTypes = 3 }; 00057 00059 enum EFieldJustification { LEFT, RIGHT }; 00060 enum { numFieldJustifications = 2 }; 00061 00063 enum EFloatingOutputType { SCIENTIFIC, GENERAL }; 00064 enum { numFloatingOutputTypes = 2 }; 00065 00067 class MissingFieldsError : public ExceptionBase 00068 {public:MissingFieldsError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00069 00071 class InvalidFieldSpecError : public ExceptionBase 00072 {public:InvalidFieldSpecError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00073 00075 class MissingHeaderError : public ExceptionBase 00076 {public:MissingHeaderError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00077 00079 class InvalidFieldOutputError : public ExceptionBase 00080 {public:InvalidFieldOutputError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00081 00083 00085 TabularOutputter(std::ostream &out); 00086 00088 TabularOutputter(const RCP<std::ostream> &out); 00089 00091 void setOStream( const RCP<std::ostream> &out ); 00092 00094 void pushFieldSpec( const std::string &fieldName, 00095 const EFieldType fieldType = DOUBLE, 00096 const EFieldJustification fieldJustification = RIGHT, 00097 const EFloatingOutputType floatingOutputType = SCIENTIFIC, 00098 const int width = -1 00099 ); 00100 00105 void setFieldTypePrecision( const EFieldType fieldType, const int prec ); 00106 00108 void outputHeader(); 00109 00111 template<typename T> 00112 void outputField( const T& t ); 00113 00115 void nextRow(const bool allowRemainingFields = false); 00116 00117 private: 00118 00119 // Private types 00120 00121 struct FieldSpec { 00122 FieldSpec(std::string fieldName_in, EFieldType fieldType_in, 00123 EFieldJustification fieldJustification_in, 00124 EFloatingOutputType floatingOutputType_in, 00125 const int outputWidth_in 00126 ) 00127 :fieldName(fieldName_in), fieldType(fieldType_in), 00128 fieldJustification(fieldJustification_in), 00129 floatingOutputType(floatingOutputType_in), 00130 outputWidth(outputWidth_in), 00131 precision(-1) // Gets set later 00132 {} 00133 std::string fieldName; 00134 EFieldType fieldType; 00135 EFieldJustification fieldJustification; 00136 EFloatingOutputType floatingOutputType; 00137 int outputWidth; 00138 int precision; 00139 }; 00140 00141 // Private data members 00142 00143 static const std::string fieldSpacer_; 00144 00145 //use pragmas to disable some false-positive warnings for windows sharedlibs export 00146 #ifdef _MSC_VER 00147 #pragma warning(push) 00148 #pragma warning(disable:4251) 00149 #endif 00150 Array<FieldSpec> fieldSpecs_; 00151 RCP<FancyOStream> out_; 00152 Tuple<int,numFieldTypes> fieldTypePrecision_; 00153 #ifdef _MSC_VER 00154 #pragma warning(pop) 00155 #endif 00156 00157 int currFieldIdx_; 00158 00159 Time timer_; 00160 int numLoops_; 00161 00162 // Private member functions 00163 00164 void initialize(); 00165 00166 double adjustTime( const double &time_in ) 00167 { 00168 return ( time_in > 0.0 ? time_in : -1.0 ); 00169 } 00170 00171 public: // Should be hidden 00172 00173 void startTimer(const int numLoops) 00174 { 00175 timer_.reset(); 00176 timer_.start(); 00177 numLoops_ = numLoops; 00178 } 00179 00180 double stopTimer() 00181 { 00182 #ifdef TEUCHOS_DEBUG 00183 TEST_FOR_EXCEPT(numLoops_ == -1); 00184 #endif 00185 timer_.stop(); 00186 const double relTime = 00187 adjustTime(timer_.totalElapsedTime()) / numLoops_; 00188 numLoops_ = -1; 00189 return relTime; 00190 } 00191 00192 private: 00193 00194 // Not defined and not to be called! 00195 TabularOutputter(); 00196 00197 }; 00198 00199 00201 #define TEUCHOS_START_PERF_OUTPUT_TIMER(OUTPUTTER, NUMLOOPS) \ 00202 (OUTPUTTER).startTimer(NUMLOOPS); \ 00203 for ( int k = 0; k < (NUMLOOPS); ++k ) 00204 00205 00207 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \ 00208 (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \ 00209 for ( int k = 0; k < (NUMLOOPS); ++k ) 00210 00211 00213 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \ 00214 (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \ 00215 for ( int k = 0; k < (NUMLOOPS); ++k ) 00216 00217 00221 #define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME) \ 00222 const double VARNAME = (OUTPUTTER).stopTimer(); \ 00223 (OUTPUTTER).outputField(VARNAME) 00224 00225 00226 // 00227 // Implementations 00228 // 00229 00230 00231 template<typename T> 00232 void TabularOutputter::outputField( const T& t ) 00233 { 00234 00235 using std::setw; 00236 00237 #ifdef TEUCHOS_DEBUG 00238 TEST_FOR_EXCEPTION( 00239 currFieldIdx_ == -1, 00240 MissingHeaderError, 00241 "Error, you can not output a field until you print the header with" 00242 " outputHeader()." 00243 ); 00244 TEST_FOR_EXCEPTION( 00245 !(currFieldIdx_ < as<int>(fieldSpecs_.size())), 00246 InvalidFieldOutputError, 00247 "Error, you have already output all of the " 00248 << fieldSpecs_.size() << " fields for this tabular output." 00249 " You must call nextRow() before outputting to the next row." 00250 ); 00251 #endif 00252 00253 FieldSpec &fieldSpec = fieldSpecs_[currFieldIdx_]; 00254 00255 *out_ << fieldSpacer_ << std::setprecision(fieldSpec.precision); 00256 00257 switch(fieldSpec.fieldJustification) { 00258 case LEFT: 00259 *out_ << std::left; 00260 break; 00261 case RIGHT: 00262 *out_ << std::right; 00263 break; 00264 default: { 00265 TEST_FOR_EXCEPT(true); 00266 } 00267 } 00268 00269 switch(fieldSpec.floatingOutputType) { 00270 case SCIENTIFIC: 00271 *out_ << std::scientific; 00272 break; 00273 case GENERAL: 00274 *out_ << std::fixed; 00275 break; 00276 default: { 00277 TEST_FOR_EXCEPT(true); 00278 } 00279 } 00280 00281 *out_ << setw(fieldSpec.outputWidth) << t; 00282 00283 ++currFieldIdx_; 00284 00285 } 00286 00287 00288 00289 } // namespace Teuchos 00290 00291 00292 #endif // TEUCHOS_TABULAR_OUTPUTTER_HPP
1.7.4