simple_log_archive.hpp 5.0 KB

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