|
Sierra Toolkit Version of the Day
|
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