Writer.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 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 
00309   Writer &t(PrintMask line_mask = 0) {
00310     setLineMask(line_mask | stk::LOG_TRACE);
00311 
00312     return *this;
00313   }
00314 
00320   PrintMask getPrintMask() {
00321     return m_printMask;
00322   }
00323 
00331   bool isEnabled() {
00332     return (m_flags & ENABLED) != 0;
00333   }
00334 
00342   bool isLoggable(PrintMask line_mask) {
00343     return line_mask == 0           // Always
00344       || ((line_mask & m_printMask & stk::LOG_TRACE)      // LOG_TRACE?
00345     ? isTracing()             // Yes, must be tracing
00346 //    : (line_mask & m_printMask) != 0);        // No, any matching bits
00347     : (line_mask & m_printMask) == line_mask);      // No, all matching bits
00348   }
00349 
00355   bool shouldPrint() {
00356     return shouldPrint(m_lineMaskStack.getLineMask());
00357   }
00358 
00366   bool shouldPrint(PrintMask line_mask) {
00367     return isEnabled() && isLoggable(line_mask);
00368   }
00369 
00378   bool shouldTrace(int line_mask) {
00379     return line_mask == 0           // Always
00380       || (line_mask & m_printMask) != 0;        // Any set
00381 //      || (line_mask & m_printMask) == line_mask;      // All set
00382   }
00383 
00389   Writer &dflush();
00390 
00399   Writer &dendl();
00400 
00407   Writer &push();
00408 
00415   Writer &pop();
00416 
00423   Writer &resetLineMask();
00424 
00430   Writer& operator<<(Writer& (*f)(Writer&));
00431 
00438   Writer& operator<<(std::ios_base& (*f)(std::ios_base&));
00439 
00446   Writer& operator<<(std::ostream& (*f)(std::ostream&));
00447 
00453   int incTraceDepth() {
00454     return ++m_traceDepth;
00455   }
00456 
00462   int decTraceDepth() {
00463     return --m_traceDepth;
00464   }
00465 
00474   bool isTracing() {
00475     return m_traceDepth <= 0 ? false
00476       : (m_traceDepth == 1 || (m_traceDepth > 1 && (m_printMask & stk::LOG_TRACE_SUB_CALLS)));
00477   }
00478 
00486   bool isTraceable() {
00487     return isTracing() || (m_printMask & stk::LOG_TRACE) != 0; // Currently in a trace or tracing bit set
00488   }
00489 
00490 private:
00491   Flags       m_flags;    
00492   PrintMask     m_printMask;    
00493   LineMaskStack     m_lineMaskStack;  
00494   int       m_traceDepth;   
00495   std::ostream                  m_writerStream;
00496 };
00497 
00505 inline Writer &dendl(Writer &dout) {
00506   return dout.dendl();
00507 }
00508 
00517 inline Writer &dflush(Writer &dout) {
00518   return dout.dflush();
00519 }
00520 
00529 inline Writer &push(Writer &dout) {
00530   return dout.push();
00531 }
00532 
00541 inline Writer &pop(Writer &dout) {
00542   return dout.pop();
00543 }
00544 
00545 
00550 struct _setlinemask
00551 {
00557   _setlinemask(PrintMask line_mask)
00558     : m_lineMask(line_mask)
00559   {}
00560 
00561   PrintMask   m_lineMask;
00562 };
00563 
00570 inline _setlinemask setlinemask(PrintMask line_mask) {
00571   return _setlinemask(line_mask);
00572 }
00573 
00584 inline Writer &operator<<(Writer &dout, _setlinemask set_line_mask) {
00585   return dout.setLineMask(set_line_mask.m_lineMask);
00586 }
00587 
00596 inline Writer &resetlinemask(Writer &dout) {
00597   return dout.resetLineMask();
00598 }
00599 
00611 Writer &operator<<(Writer &dout, const char *c_str);
00612 Writer &operator<<(Writer &dout, const std::string &str);
00613 Writer &operator<<(Writer &dout, const void *ptr);
00614 Writer &operator<<(Writer &dout, const float &x);
00615 Writer &operator<<(Writer &dout, const double &x);
00616 Writer &operator<<(Writer &dout, const long double &x);
00617 Writer &operator<<(Writer &dout, const int &x);
00618 Writer &operator<<(Writer &dout, const unsigned int &x);
00619 Writer &operator<<(Writer &dout, const long &x);
00620 Writer &operator<<(Writer &dout, const unsigned long &x);
00621 Writer &operator<<(Writer &dout, const short &x);
00622 Writer &operator<<(Writer &dout, const unsigned short &x);
00623 Writer &operator<<(Writer &dout, const long long &x);
00624 Writer &operator<<(Writer &dout, const unsigned long long &x);
00631 template <class T>
00632 class c_ptr_
00633 {
00634 public:
00640   explicit c_ptr_(const T *t)
00641     : m_t(t)
00642   {}
00643 
00644 public:
00645   const T * m_t;      
00646 };
00647 
00655 template <class T>
00656 c_ptr_<T> c_ptr(const T *t) {
00657   return c_ptr_<T>(t);
00658 }
00659 
00666 template <class T, typename R>
00667 class c_ptr_func_
00668 {
00669 public:
00678   explicit c_ptr_func_(const T *t, R (T::*pmf)() const)
00679     : m_t(t),
00680       m_pmf(pmf)
00681   {}
00682 
00683 public:
00684   const T * m_t;      
00685   R (T::*m_pmf)() const;    
00686 };
00687 
00702 template <class T, typename R>
00703 c_ptr_func_<T, R> c_ptr_func(const T *t, R (T::*pmf)() const) {
00704   return c_ptr_func_<T, R>(t, pmf);
00705 }
00706 
00720 template <class T>
00721 Writer &operator<<(Writer &dout, const c_ptr_<T> &c) {
00722   dout << "(pointer " << (void *) c.m_t << "), ";
00723 
00724   if (c.m_t)
00725     dout << *c.m_t;
00726   else
00727     dout << "<not created>";
00728 
00729   return dout;
00730 }
00731 
00746 template <class T, typename R>
00747 Writer &operator<<(Writer &dout, const c_ptr_func_<T, R> &c) {
00748   if (c.m_t)
00749     dout << "(pointer), " << (c.m_t->*c.m_pmf)();
00750   else
00751     dout << "(pointer), <not created>";
00752 
00753   return dout;
00754 }
00755 
00759 
00760 } // namespace diag
00761 } // namespace stk
00762 
00763 #endif // STK_UTIL_DIAG_WRITER_HPP

Generated on Tue Jul 13 09:27:32 2010 for Sierra Toolkit by  doxygen 1.4.7