Sierra Toolkit Version of the Day
Writer.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010, 2011 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #ifndef STK_UTIL_DIAG_WRITER_HPP
00010 #define STK_UTIL_DIAG_WRITER_HPP
00011 
00012 #include <ostream>
00013 #include <string>
00014 #include <vector>
00015 #include <utility>
00016 #include <stdint.h>
00017 
00018 #include <stk_util/diag/Writer_fwd.hpp>
00019 
00020 namespace stk {
00021 namespace diag {
00022 
00027 
00028 class WriterThrowSafe
00029 {
00030 public:
00031   explicit WriterThrowSafe(Writer &writer);
00032 
00033   ~WriterThrowSafe();
00034 
00035 private:
00036   Writer &      m_writer;
00037   int           m_depth;
00038 
00039   WriterThrowSafe(const WriterThrowSafe &);
00040   void operator = (const WriterThrowSafe &);
00041 };
00042 
00043 
00049 class Writer
00050 {
00051 public:
00060   enum Flags {
00061     DISABLED    =  0x00,
00062     ENABLED    =  0x01
00063   };
00064 
00065 private:
00081   struct LineMaskStack : public std::vector<std::pair<int, PrintMask> >
00082   {
00088     LineMaskStack() {
00089       push_back(std::pair<int, PrintMask>(0, LOG_ALWAYS));
00090     }
00091 
00098     LineMaskStack &pushDepth() {
00099       push_back(std::make_pair(back().first + 1, back().second));
00100       return *this;
00101     }
00102 
00111     LineMaskStack &push(PrintMask line_mask) {
00112       push_back(std::make_pair(back().first, line_mask));
00113       return *this;
00114     }
00115 
00122     LineMaskStack &pop() {
00123       if (size() > 1)
00124         pop_back();
00125       return *this;
00126     }
00127 
00134     LineMaskStack &popLineMask() {
00135       if (size() > 1 && getNextDepth() == getDepth())
00136         pop_back();
00137       return *this;
00138     }
00139 
00146     int getDepth() const {
00147       return back().first;
00148     }
00149 
00157     int getLineMask() const {
00158       return back().second;
00159     }
00160 
00168     int getNextDepth() const {
00169       return (end() - 2)->first;
00170     }
00171 
00178     LineMaskStack &resetDepth() {
00179       while (size() > 1 && getNextDepth() == getDepth())
00180         pop_back();
00181       return *this;
00182     }
00183   };
00184 
00185 public:
00196   explicit Writer(std::streambuf *streambuf, PrintMask print_mask = static_cast<PrintMask>(LOG_MEMBERS), Flags flags = static_cast<Flags>(ENABLED));
00197 
00202   ~Writer();
00203 
00210   std::ostream &getStream() {
00211     return m_writerStream;
00212   }
00213 
00222   Writer &setFlags(int flags) {
00223     m_flags = (Flags) flags;
00224     return *this;
00225   }
00226 
00232   int getFlags() {
00233     return m_flags;
00234   }
00235 
00236   int getDepth() const {
00237     return m_lineMaskStack.getDepth();
00238   }
00239 
00240   Writer &restoreDepth(int depth) {
00241     while (m_lineMaskStack.getDepth() > depth)
00242       pop();
00243     return *this;
00244   }
00245 
00255   Writer &setPrintMask(PrintMask mask = 0) {
00256     m_printMask = mask;
00257     return *this;
00258   }
00259 
00269   Writer &setPrintMask(const char *mask_string);
00270 
00280   Writer &setLineMask(PrintMask line_mask) {
00281     m_lineMaskStack.push(line_mask);
00282 
00283     return *this;
00284   }
00285 
00294   Writer &m(PrintMask line_mask) {
00295     setLineMask(line_mask);
00296 
00297     return *this;
00298   }
00299 
00308   Writer &w(bool on, PrintMask line_mask) {
00309     setLineMask(on ? line_mask : 0x80000000);
00310 
00311     return *this;
00312   }
00313 
00323   Writer &t(PrintMask line_mask = 0) {
00324     setLineMask(line_mask | stk::LOG_TRACE);
00325 
00326     return *this;
00327   }
00328 
00334   PrintMask getPrintMask() {
00335     return m_printMask;
00336   }
00337 
00345   bool isEnabled() {
00346     return (m_flags & ENABLED) != 0;
00347   }
00348 
00356   bool isLoggable(PrintMask line_mask) {
00357     return line_mask == 0            // Always
00358       || ((line_mask & m_printMask & stk::LOG_TRACE)      // LOG_TRACE?
00359           ? isTracing()              // Yes, must be tracing
00360 //    : (line_mask & m_printMask) != 0);        // No, any matching bits
00361           : (line_mask & m_printMask) == line_mask);      // No, all matching bits
00362   }
00363 
00369   bool shouldPrint() {
00370     return shouldPrint(m_lineMaskStack.getLineMask());
00371   }
00372 
00380   bool shouldPrint(PrintMask line_mask) {
00381     return isEnabled() && isLoggable(line_mask);
00382   }
00383 
00392   bool shouldTrace(int line_mask) {
00393     return line_mask == 0            // Always
00394       || (line_mask & m_printMask) != 0;        // Any set
00395 //      || (line_mask & m_printMask) == line_mask;      // All set
00396   }
00397 
00403   Writer &dflush();
00404 
00413   Writer &dendl();
00414 
00421   Writer &push();
00422 
00429   Writer &pop();
00430 
00437   Writer &resetLineMask();
00438 
00444   Writer& operator<<(Writer& (*f)(Writer&));
00445 
00452   Writer& operator<<(std::ios_base& (*f)(std::ios_base&));
00453 
00460   Writer& operator<<(std::ostream& (*f)(std::ostream&));
00461 
00467   int incTraceDepth() {
00468     return ++m_traceDepth;
00469   }
00470 
00476   int decTraceDepth() {
00477     return --m_traceDepth;
00478   }
00479 
00488   bool isTracing() {
00489     return m_traceDepth <= 0 ? false
00490       : (m_traceDepth == 1 || (m_traceDepth > 1 && (m_printMask & stk::LOG_TRACE_SUB_CALLS)));
00491   }
00492 
00500   bool isTraceable() {
00501     return isTracing() || (m_printMask & stk::LOG_TRACE) != 0; // Currently in a trace or tracing bit set
00502   }
00503 
00504 private:
00505   Flags        m_flags;    
00506   PrintMask      m_printMask;    
00507   LineMaskStack      m_lineMaskStack;  
00508   int        m_traceDepth;    
00509   std::ostream                  m_writerStream;
00510 };
00511 
00519 inline Writer &dendl(Writer &dout) {
00520   return dout.dendl();
00521 }
00522 
00531 inline Writer &dflush(Writer &dout) {
00532   return dout.dflush();
00533 }
00534 
00543 inline Writer &push(Writer &dout) {
00544   return dout.push();
00545 }
00546 
00555 inline Writer &pop(Writer &dout) {
00556   return dout.pop();
00557 }
00558 
00559 
00564 struct _setlinemask
00565 {
00571   _setlinemask(PrintMask line_mask)
00572     : m_lineMask(line_mask)
00573   {}
00574 
00575   PrintMask    m_lineMask;
00576 };
00577 
00584 inline _setlinemask setlinemask(PrintMask line_mask) {
00585   return _setlinemask(line_mask);
00586 }
00587 
00598 inline Writer &operator<<(Writer &dout, _setlinemask set_line_mask) {
00599   return dout.setLineMask(set_line_mask.m_lineMask);
00600 }
00601 
00610 inline Writer &resetlinemask(Writer &dout) {
00611   return dout.resetLineMask();
00612 }
00613 
00625 Writer &operator<<(Writer &dout, const char *c_str);
00626 Writer &operator<<(Writer &dout, const std::string &str);
00627 Writer &operator<<(Writer &dout, const void *ptr);
00628 Writer &operator<<(Writer &dout, const float &x);
00629 Writer &operator<<(Writer &dout, const double &x);
00630 Writer &operator<<(Writer &dout, const long double &x);
00631 Writer &operator<<(Writer &dout, const int &x);
00632 Writer &operator<<(Writer &dout, const unsigned int &x);
00633 Writer &operator<<(Writer &dout, const long &x);
00634 Writer &operator<<(Writer &dout, const unsigned long &x);
00635 Writer &operator<<(Writer &dout, const short &x);
00636 Writer &operator<<(Writer &dout, const unsigned short &x);
00637 Writer &operator<<(Writer &dout, const long long &x);
00638 Writer &operator<<(Writer &dout, const unsigned long long &x);
00645 template <class T>
00646 class c_ptr_
00647 {
00648 public:
00654   explicit c_ptr_(const T *t)
00655     : m_t(t)
00656   {}
00657 
00658 public:
00659   const T *  m_t;      
00660 };
00661 
00669 template <class T>
00670 c_ptr_<T> c_ptr(const T *t) {
00671   return c_ptr_<T>(t);
00672 }
00673 
00680 template <class T, typename R>
00681 class c_ptr_func_
00682 {
00683 public:
00692   explicit c_ptr_func_(const T *t, R (T::*pmf)() const)
00693     : m_t(t),
00694       m_pmf(pmf)
00695   {}
00696 
00697 public:
00698   const T *  m_t;      
00699   R (T::*m_pmf)() const;    
00700 };
00701 
00716 template <class T, typename R>
00717 c_ptr_func_<T, R> c_ptr_func(const T *t, R (T::*pmf)() const) {
00718   return c_ptr_func_<T, R>(t, pmf);
00719 }
00720 
00734 template <class T>
00735 Writer &operator<<(Writer &dout, const c_ptr_<T> &c) {
00736   dout << "(pointer " << (void *) c.m_t << "), ";
00737 
00738   if (c.m_t)
00739     dout << *c.m_t;
00740   else
00741     dout << "<not created>";
00742 
00743   return dout;
00744 }
00745 
00760 template <class T, typename R>
00761 Writer &operator<<(Writer &dout, const c_ptr_func_<T, R> &c) {
00762   if (c.m_t)
00763     dout << "(pointer), " << (c.m_t->*c.m_pmf)();
00764   else
00765     dout << "(pointer), <not created>";
00766 
00767   return dout;
00768 }
00769 
00773 
00774 } // namespace diag
00775 } // namespace stk
00776 
00777 #endif // STK_UTIL_DIAG_WRITER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends