// time_t_wrapper.h: interface for the time_t_wrapper class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_TIME_T_WRAPPER_H__5ECB1ADD_9D17_41A3_8E21_5DF960B7646A__INCLUDED_) #define AFX_TIME_T_WRAPPER_H__5ECB1ADD_9D17_41A3_8E21_5DF960B7646A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include #include #include // forward declarations void time_t_to_stream( time_t val, std::ostream & out); void read_time_t_from_stream( time_t & val, std::istream &in); /* Note about Write to streams If write_details is true, when written to stream, it's written like this: x If write_details is false, when written to stream it's written normally (like a time_t) Note about Read from streams - recognizes both formats shown above, and processes as appropriately Defaults: if debug, write_details is true by default if release, write_details is false by default */ typedef enum { // behaves like a time_t; // // keeps a user-friendly string in itself, // so that at any time you can see the user-friendly string // (very useful for debugging) time_t_debug, // behaves like a time_t; // when written to stream, writes only time_t value (no user-friendly string) // when read from stream, ignores user-friendly msg. if necessary time_t_release, time_t_default = #ifndef NDEBUG // debug time_t_debug #else // release time_t_release #endif } time_t_wrapper_type; struct time_t_wrapper_top { static bool & write_details_val() { static bool val = #ifndef NDEBUG // debug true #else // release false #endif ; return val; } }; // struct time_t_wrapper_top // forward declaration template< time_t_wrapper_type wrapper_type> struct time_t_wrapper; template< time_t_wrapper_type wrapper_type> struct time_t_wrapper_base : private time_t_wrapper_top { protected: time_t_wrapper_base() : m_val( 0) {} time_t_wrapper_base( time_t val) : m_val( val) {} public: operator time_t() const { return m_val; } time_t_wrapper_base& operator=( time_t val) { m_val = val; do_refresh(); return *this; } time_t_wrapper_base& operator=( const time_t_wrapper_base & val) { m_val = val.m_val; do_refresh(); return *this; } // helpers for when you know // EXACTLY how you want to write a time_t_wrapper value time_t raw() const { return m_val; } std::string details() const { std::ostringstream out; out << 'T' << m_val << ' '; time_t_to_stream( m_val, out); return out.str(); } static bool & write_details() { return write_details_val(); } private: typedef time_t_wrapper< wrapper_type> derived; void do_refresh() { derived * pThis = ( derived *)this; pThis->refresh(); } public: // made public due to VC6 bug void do_write( std::ostream & out) const { derived * pThis = ( derived *)this; pThis->write( out); } void do_read( std::istream & in) { read_time_t_from_stream( m_val, in); derived * pThis = ( derived *)this; pThis->refresh(); } protected: time_t val() const { return m_val; } private: time_t m_val; }; template< time_t_wrapper_type wrapper_type> inline std::istream & operator>>( std::istream & in, time_t_wrapper< wrapper_type> & val) { val.do_read( in); return in; } template< time_t_wrapper_type wrapper_type> inline std::ostream & operator<<( std::ostream & out, const time_t_wrapper< wrapper_type> & val) { val.do_write( out); return out; } template< time_t_wrapper_type wrapper_type = time_t_default> struct time_t_wrapper; // debug version template<> struct time_t_wrapper< time_t_debug> : public time_t_wrapper_base< time_t_debug> { typedef time_t_wrapper_base< time_t_debug> base; time_t_wrapper() : base() { refresh(); } time_t_wrapper( time_t val) : base( val) { refresh(); } void refresh() { std::ostringstream out; time_t_to_stream( val(), out); m_as_string = out.str(); } void write( std::ostream & out) const { if ( write_details() ) out << 'T' << val() << ' ' << m_as_string; else // no details out << val(); } // user friendly std::string m_as_string; }; // release version struct time_t_wrapper< time_t_release> : public time_t_wrapper_base< time_t_release> { typedef time_t_wrapper_base< time_t_release> base; time_t_wrapper() : base() { refresh(); } time_t_wrapper( time_t val) : base( val) { refresh(); } void refresh() { // nothing to refresh } void write( std::ostream & out) const { if ( write_details() ) { out << 'T' << val() << ' '; time_t_to_stream( val(), out); } else { // no details out << val(); } } }; #endif // !defined(AFX_TIME_T_WRAPPER_H__5ECB1ADD_9D17_41A3_8E21_5DF960B7646A__INCLUDED_)