#ifndef BOOST_SIMPLE_LOG_ARCHIVE_HPP #define BOOST_SIMPLE_LOG_ARCHIVE_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // simple_log_archive.hpp // (C) Copyright 2010 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org for updates, documentation, and revision history. #include #include // std::size_t #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::size_t; } // namespace std #endif #include #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////////////////// // log data to an output stream. This illustrates a simpler implemenation // of text output which is useful for getting a formatted display of // any serializable class. Intended to be useful as a debugging aid. class simple_log_archive { std::ostream & m_os; unsigned int m_depth; template struct save_enum_type { template static void invoke(Archive &ar, const T &t){ ar.m_os << static_cast(t); } }; template struct save_primitive { template static void invoke(Archive & ar, const T & t){ ar.m_os << t; } }; template struct save_only { template static void invoke(Archive & ar, const T & t){ // make sure call is routed through the highest interface that might // be specialized by the user. boost::serialization::serialize_adl( ar, const_cast(t), ::boost::serialization::version< T >::value ); } }; template void save(const T &t){ typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if, boost::mpl::identity >, //else BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< // if its primitive boost::mpl::equal_to< boost::serialization::implementation_level< T >, boost::mpl::int_ >, boost::mpl::identity >, // else boost::mpl::identity > > >::type typex; typex::invoke(*this, t); } #ifndef BOOST_NO_STD_WSTRING void save(const std::wstring &ws){ m_os << "wide string types not suported in log archive"; } #endif public: /////////////////////////////////////////////////// // Implement requirements for archive concept typedef boost::mpl::bool_ is_loading; typedef boost::mpl::bool_ is_saving; // this can be a no-op since we ignore pointer polymorphism template void register_type(const T * = NULL){} unsigned int get_library_version(){ return 0; } void save_binary(const void *address, std::size_t count){ m_os << "save_binary not implemented"; } // the << operators template simple_log_archive & operator<<(T const & t){ m_os << ' '; save(t); return * this; } template simple_log_archive & operator<<(T * const t){ m_os << " ->"; if(NULL == t) m_os << " null"; else *this << * t; return * this; } template simple_log_archive & operator<<(const T (&t)[N]){ return *this << boost::serialization::make_array( static_cast(&t[0]), N ); } template simple_log_archive & operator<<(const boost::serialization::nvp< T > & t){ m_os << '\n'; // start line with each named object // indent according to object depth for(unsigned int i = 0; i < m_depth; ++i) m_os << ' '; ++m_depth; m_os << t.name(); // output the name of the object * this << t.const_value(); --m_depth; return * this; } // the & operator template simple_log_archive & operator&(const T & t){ return * this << t; } /////////////////////////////////////////////// simple_log_archive(std::ostream & os) : m_os(os), m_depth(0) {} }; #endif // BOOST_SIMPLE_LOG_ARCHIVE_HPP