|
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_TABULAR_OUTPUTTER_HPP 00043 #define TEUCHOS_TABULAR_OUTPUTTER_HPP 00044 00045 00046 #include "Teuchos_FancyOStream.hpp" 00047 #include "Teuchos_Array.hpp" 00048 #include "Teuchos_Tuple.hpp" 00049 #include "Teuchos_RCP.hpp" 00050 #include "Teuchos_Time.hpp" 00051 #include "Teuchos_Exceptions.hpp" 00052 00053 00054 namespace Teuchos { 00055 00056 00061 class TEUCHOSCORE_LIB_DLL_EXPORT TabularOutputter { 00062 public: 00063 00066 00068 enum EFieldType { DOUBLE, INT, STRING }; 00069 enum { numFieldTypes = 3 }; 00070 00072 enum EFieldJustification { LEFT, RIGHT }; 00073 enum { numFieldJustifications = 2 }; 00074 00076 enum EFloatingOutputType { SCIENTIFIC, GENERAL }; 00077 enum { numFloatingOutputTypes = 2 }; 00078 00080 class MissingFieldsError : public ExceptionBase 00081 {public:MissingFieldsError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00082 00084 class InvalidFieldSpecError : public ExceptionBase 00085 {public:InvalidFieldSpecError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00086 00088 class MissingHeaderError : public ExceptionBase 00089 {public:MissingHeaderError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00090 00092 class InvalidFieldOutputError : public ExceptionBase 00093 {public:InvalidFieldOutputError(const std::string& what_arg) : ExceptionBase(what_arg) {}}; 00094 00096 00098 TabularOutputter(std::ostream &out); 00099 00101 TabularOutputter(const RCP<std::ostream> &out); 00102 00104 void setOStream( const RCP<std::ostream> &out ); 00105 00107 void pushFieldSpec( const std::string &fieldName, 00108 const EFieldType fieldType = DOUBLE, 00109 const EFieldJustification fieldJustification = RIGHT, 00110 const EFloatingOutputType floatingOutputType = SCIENTIFIC, 00111 const int width = -1 00112 ); 00113 00118 void setFieldTypePrecision( const EFieldType fieldType, const int prec ); 00119 00121 void outputHeader(); 00122 00124 template<typename T> 00125 void outputField( const T& t ); 00126 00128 void nextRow(const bool allowRemainingFields = false); 00129 00130 private: 00131 00132 // Private types 00133 00134 struct FieldSpec { 00135 FieldSpec(std::string fieldName_in, EFieldType fieldType_in, 00136 EFieldJustification fieldJustification_in, 00137 EFloatingOutputType floatingOutputType_in, 00138 const int outputWidth_in 00139 ) 00140 :fieldName(fieldName_in), fieldType(fieldType_in), 00141 fieldJustification(fieldJustification_in), 00142 floatingOutputType(floatingOutputType_in), 00143 outputWidth(outputWidth_in), 00144 precision(-1) // Gets set later 00145 {} 00146 std::string fieldName; 00147 EFieldType fieldType; 00148 EFieldJustification fieldJustification; 00149 EFloatingOutputType floatingOutputType; 00150 int outputWidth; 00151 int precision; 00152 }; 00153 00154 // Private data members 00155 00156 static const std::string fieldSpacer_; 00157 00158 //use pragmas to disable some false-positive warnings for windows sharedlibs export 00159 #ifdef _MSC_VER 00160 #pragma warning(push) 00161 #pragma warning(disable:4251) 00162 #endif 00163 Array<FieldSpec> fieldSpecs_; 00164 RCP<FancyOStream> out_; 00165 Tuple<int,numFieldTypes> fieldTypePrecision_; 00166 #ifdef _MSC_VER 00167 #pragma warning(pop) 00168 #endif 00169 00170 int currFieldIdx_; 00171 00172 Time timer_; 00173 int numLoops_; 00174 00175 // Private member functions 00176 00177 void initialize(); 00178 00179 double adjustTime( const double &time_in ) 00180 { 00181 return ( time_in > 0.0 ? time_in : -1.0 ); 00182 } 00183 00184 public: // Should be hidden 00185 00186 void startTimer(const int numLoops) 00187 { 00188 timer_.reset(); 00189 timer_.start(); 00190 numLoops_ = numLoops; 00191 } 00192 00193 double stopTimer() 00194 { 00195 #ifdef TEUCHOS_DEBUG 00196 TEUCHOS_TEST_FOR_EXCEPT(numLoops_ == -1); 00197 #endif 00198 timer_.stop(); 00199 const double relTime = 00200 adjustTime(timer_.totalElapsedTime()) / numLoops_; 00201 numLoops_ = -1; 00202 return relTime; 00203 } 00204 00205 private: 00206 00207 // Not defined and not to be called! 00208 TabularOutputter(); 00209 00210 }; 00211 00212 00214 #define TEUCHOS_START_PERF_OUTPUT_TIMER(OUTPUTTER, NUMLOOPS) \ 00215 (OUTPUTTER).startTimer(NUMLOOPS); \ 00216 for ( int k = 0; k < (NUMLOOPS); ++k ) 00217 00218 00220 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \ 00221 (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \ 00222 for ( int k = 0; k < (NUMLOOPS); ++k ) 00223 00224 00226 #define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS) \ 00227 (OUTPUTTER).startTimer((NUMLOOPS)*(NUMINNERLOOPS)); \ 00228 for ( int k = 0; k < (NUMLOOPS); ++k ) 00229 00230 00234 #define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME) \ 00235 const double VARNAME = (OUTPUTTER).stopTimer(); \ 00236 (OUTPUTTER).outputField(VARNAME) 00237 00238 00239 // 00240 // Implementations 00241 // 00242 00243 00244 template<typename T> 00245 void TabularOutputter::outputField( const T& t ) 00246 { 00247 00248 using std::setw; 00249 00250 #ifdef TEUCHOS_DEBUG 00251 TEUCHOS_TEST_FOR_EXCEPTION( 00252 currFieldIdx_ == -1, 00253 MissingHeaderError, 00254 "Error, you can not output a field until you print the header with" 00255 " outputHeader()." 00256 ); 00257 TEUCHOS_TEST_FOR_EXCEPTION( 00258 !(currFieldIdx_ < as<int>(fieldSpecs_.size())), 00259 InvalidFieldOutputError, 00260 "Error, you have already output all of the " 00261 << fieldSpecs_.size() << " fields for this tabular output." 00262 " You must call nextRow() before outputting to the next row." 00263 ); 00264 #endif 00265 00266 FieldSpec &fieldSpec = fieldSpecs_[currFieldIdx_]; 00267 00268 *out_ << fieldSpacer_ << std::setprecision(fieldSpec.precision); 00269 00270 switch(fieldSpec.fieldJustification) { 00271 case LEFT: 00272 *out_ << std::left; 00273 break; 00274 case RIGHT: 00275 *out_ << std::right; 00276 break; 00277 default: { 00278 TEUCHOS_TEST_FOR_EXCEPT(true); 00279 } 00280 } 00281 00282 switch(fieldSpec.floatingOutputType) { 00283 case SCIENTIFIC: 00284 *out_ << std::scientific; 00285 break; 00286 case GENERAL: 00287 *out_ << std::fixed; 00288 break; 00289 default: { 00290 TEUCHOS_TEST_FOR_EXCEPT(true); 00291 } 00292 } 00293 00294 *out_ << setw(fieldSpec.outputWidth) << t; 00295 00296 ++currFieldIdx_; 00297 00298 } 00299 00300 00301 00302 } // namespace Teuchos 00303 00304 00305 #endif // TEUCHOS_TABULAR_OUTPUTTER_HPP
1.7.6.1