Teuchos_TabularOutputter.hpp

Go to the documentation of this file.
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 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   Array<FieldSpec> fieldSpecs_;
00146   RCP<FancyOStream> out_;
00147   Tuple<int,numFieldTypes> fieldTypePrecision_;
00148 
00149   int currFieldIdx_;
00150 
00151   Time timer_;
00152   int numLoops_;
00153 
00154   // Private member functions
00155 
00156   void initialize();
00157 
00158   double adjustTime( const double &time_in )
00159     {
00160       return ( time_in > 0.0 ? time_in : -1.0 );
00161     }
00162 
00163 public: // Should be hidden
00164 
00165   void startTimer(const int numLoops)
00166     {
00167       timer_.reset();
00168       timer_.start();
00169       numLoops_ = numLoops;
00170     }
00171 
00172   double stopTimer()
00173     {
00174 #ifdef TEUCHOS_DEBUG
00175       TEST_FOR_EXCEPT(numLoops_ == -1);
00176 #endif      
00177       timer_.stop();
00178       const double relTime = 
00179         adjustTime(timer_.totalElapsedTime()) / numLoops_;
00180       numLoops_ = -1;
00181       return relTime;
00182     }
00183 
00184 private:
00185   
00186   // Not defined and not to be called!
00187   TabularOutputter();
00188 
00189 };
00190 
00191 
00193 #define TEUCHOS_START_PERF_OUTPUT_TIMER(OUTPUTTER, NUMLOOPS) \
00194   (OUTPUTTER).startTimer(NUMLOOPS); \
00195   for ( int k = 0; k < (NUMLOOPS); ++k )
00196 
00197 
00201 #define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME) \
00202   const double VARNAME = (OUTPUTTER).stopTimer(); \
00203   (OUTPUTTER).outputField(VARNAME)
00204 
00205 
00206 //
00207 // Implementations
00208 //
00209 
00210 
00211 template<typename T>
00212 void TabularOutputter::outputField( const T& t )
00213 {
00214 
00215   using std::setw;
00216 
00217 #ifdef TEUCHOS_DEBUG
00218   TEST_FOR_EXCEPTION(
00219     currFieldIdx_ == -1,
00220     MissingHeaderError,
00221     "Error, you can not output a field until you print the header with"
00222     " outputHeader()."
00223     );
00224   TEST_FOR_EXCEPTION(
00225     !(currFieldIdx_ < as<int>(fieldSpecs_.size())),
00226     InvalidFieldOutputError,
00227     "Error, you have already output all of the "
00228     << fieldSpecs_.size() << " fields for this tabular output."
00229     "  You must call nextRow() before outputting to the next row."
00230     );
00231 #endif
00232 
00233   FieldSpec &fieldSpec = fieldSpecs_[currFieldIdx_];
00234   
00235   *out_ << fieldSpacer_ << std::setprecision(fieldSpec.precision);
00236 
00237   switch(fieldSpec.fieldJustification) {
00238     case LEFT:
00239       *out_ << std::left;
00240       break;
00241     case RIGHT:
00242       *out_ << std::right;
00243       break;
00244     default: {
00245       TEST_FOR_EXCEPT(true);
00246     }
00247   }
00248 
00249   switch(fieldSpec.floatingOutputType) {
00250     case SCIENTIFIC:
00251       *out_ << std::scientific;
00252       break;
00253     case GENERAL:
00254       *out_ << std::fixed;
00255       break;
00256     default: {
00257       TEST_FOR_EXCEPT(true);
00258     }
00259   }
00260 
00261   *out_ << setw(fieldSpec.outputWidth) << t;
00262 
00263   ++currFieldIdx_;
00264   
00265 }
00266 
00267 
00268 
00269 } // namespace Teuchos
00270 
00271 
00272 #endif // TEUCHOS_TABULAR_OUTPUTTER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:14:01 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1