• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_SIMPLE_LOG_ARCHIVE_HPP
2 #define BOOST_SIMPLE_LOG_ARCHIVE_HPP
3 
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER)
6 # pragma once
7 #endif
8 
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // simple_log_archive.hpp
11 
12 // (C) Copyright 2010 Robert Ramey - http://www.rrsd.com .
13 // Use, modification and distribution is subject to the Boost Software
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16 
17 //  See http://www.boost.org for updates, documentation, and revision history.
18 
19 #include <ostream>
20 #include <cstddef> // std::size_t
21 
22 #include <boost/config.hpp>
23 #if defined(BOOST_NO_STDC_NAMESPACE)
24 namespace std{
25     using ::size_t;
26 } // namespace std
27 #endif
28 
29 #include <boost/type_traits/is_enum.hpp>
30 #include <boost/mpl/bool.hpp>
31 #include <boost/mpl/eval_if.hpp>
32 #include <boost/mpl/int.hpp>
33 #include <boost/mpl/equal_to.hpp>
34 #include <boost/serialization/nvp.hpp>
35 #include <boost/serialization/array.hpp>
36 #include <boost/serialization/string.hpp>
37 #include <boost/serialization/access.hpp>
38 
39 /////////////////////////////////////////////////////////////////////////
40 // log data to an output stream.  This illustrates a simpler implemenation
41 // of text output which is useful for getting a formatted display of
42 // any serializable class.  Intended to be useful as a debugging aid.
43 class simple_log_archive {
44     std::ostream & m_os;
45     unsigned int m_depth;
46 
47     template<class Archive>
48     struct save_enum_type {
49         template<class T>
invokesimple_log_archive::save_enum_type50         static void invoke(Archive &ar, const T &t){
51             ar.m_os << static_cast<int>(t);
52         }
53     };
54     template<class Archive>
55     struct save_primitive {
56         template<class T>
invokesimple_log_archive::save_primitive57         static void invoke(Archive & ar, const T & t){
58             ar.m_os << t;
59         }
60     };
61     template<class Archive>
62     struct save_only {
63         template<class T>
invokesimple_log_archive::save_only64         static void invoke(Archive & ar, const T & t){
65             // make sure call is routed through the highest interface that might
66             // be specialized by the user.
67             boost::serialization::serialize_adl(
68                 ar,
69                 const_cast<T &>(t),
70                 ::boost::serialization::version< T >::value
71             );
72         }
73     };
74     template<class T>
save(const T & t)75     void save(const T &t){
76         typedef
77             BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<boost::is_enum< T >,
78                 boost::mpl::identity<save_enum_type<simple_log_archive> >,
79             //else
80             BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
81                 // if its primitive
82                     boost::mpl::equal_to<
83                         boost::serialization::implementation_level< T >,
84                         boost::mpl::int_<boost::serialization::primitive_type>
85                     >,
86                     boost::mpl::identity<save_primitive<simple_log_archive> >,
87             // else
88                 boost::mpl::identity<save_only<simple_log_archive> >
89             > >::type typex;
90         typex::invoke(*this, t);
91     }
92     #ifndef BOOST_NO_STD_WSTRING
save(const std::wstring & ws)93     void save(const std::wstring &ws){
94         m_os << "wide string types not suported in log archive";
95     }
96     #endif
97 
98 public:
99     ///////////////////////////////////////////////////
100     // Implement requirements for archive concept
101 
102     typedef boost::mpl::bool_<false> is_loading;
103     typedef boost::mpl::bool_<true> is_saving;
104 
105     // this can be a no-op since we ignore pointer polymorphism
106     template<class T>
register_type(const T * =NULL)107     void register_type(const T * = NULL){}
108 
get_library_version()109     unsigned int get_library_version(){
110         return 0;
111     }
112 
113     void
save_binary(const void * address,std::size_t count)114     save_binary(const void *address, std::size_t count){
115         m_os << "save_binary not implemented";
116     }
117 
118     // the << operators
119     template<class T>
operator <<(T const & t)120     simple_log_archive & operator<<(T const & t){
121         m_os << ' ';
122         save(t);
123         return * this;
124     }
125     template<class T>
operator <<(T * const t)126     simple_log_archive & operator<<(T * const t){
127         m_os << " ->";
128         if(NULL == t)
129             m_os << " null";
130         else
131             *this << * t;
132         return * this;
133     }
134     template<class T, int N>
operator <<(const T (& t)[N])135     simple_log_archive & operator<<(const T (&t)[N]){
136         return *this << boost::serialization::make_array(
137             static_cast<const T *>(&t[0]),
138             N
139         );
140     }
141     template<class T>
operator <<(const boost::serialization::nvp<T> & t)142     simple_log_archive & operator<<(const boost::serialization::nvp< T > & t){
143         m_os << '\n'; // start line with each named object
144         // indent according to object depth
145         for(unsigned int i = 0; i < m_depth; ++i)
146             m_os << ' ';
147         ++m_depth;
148         m_os << t.name(); // output the name of the object
149         * this << t.const_value();
150         --m_depth;
151         return * this;
152     }
153 
154     // the & operator
155     template<class T>
operator &(const T & t)156     simple_log_archive & operator&(const T & t){
157             return * this << t;
158     }
159     ///////////////////////////////////////////////
160 
simple_log_archive(std::ostream & os)161     simple_log_archive(std::ostream & os) :
162         m_os(os),
163         m_depth(0)
164     {}
165 };
166 
167 #endif // BOOST_SIMPLE_LOG_ARCHIVE_HPP
168