Teuchos_TabularOutputter.hpp

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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:44 2011 for Teuchos - Trilinos Tools Package by  doxygen 1.6.3