tracking.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #ifndef BOOST_SERIALIZATION_TRACKING_HPP
  2. #define BOOST_SERIALIZATION_TRACKING_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. // tracking.hpp:
  9. // (C) Copyright 2002 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 <boost/config.hpp>
  15. #include <boost/static_assert.hpp>
  16. #include <boost/mpl/eval_if.hpp>
  17. #include <boost/mpl/identity.hpp>
  18. #include <boost/mpl/int.hpp>
  19. #include <boost/mpl/equal_to.hpp>
  20. #include <boost/mpl/greater.hpp>
  21. #include <boost/mpl/integral_c_tag.hpp>
  22. #include <boost/type_traits/is_base_and_derived.hpp>
  23. #include <boost/type_traits/is_pointer.hpp>
  24. #include <boost/serialization/level.hpp>
  25. #include <boost/serialization/tracking_enum.hpp>
  26. #include <boost/serialization/type_info_implementation.hpp>
  27. namespace boost {
  28. namespace serialization {
  29. struct basic_traits;
  30. // default tracking level
  31. template<class T>
  32. struct tracking_level_impl {
  33. template<class U>
  34. struct traits_class_tracking {
  35. typedef typename U::tracking type;
  36. };
  37. typedef mpl::integral_c_tag tag;
  38. // note: at least one compiler complained w/o the full qualification
  39. // on basic traits below
  40. typedef
  41. typename mpl::eval_if<
  42. is_base_and_derived<boost::serialization::basic_traits, T>,
  43. traits_class_tracking< T >,
  44. //else
  45. typename mpl::eval_if<
  46. is_pointer< T >,
  47. // pointers are not tracked by default
  48. mpl::int_<track_never>,
  49. //else
  50. typename mpl::eval_if<
  51. // for primitives
  52. typename mpl::equal_to<
  53. implementation_level< T >,
  54. mpl::int_<primitive_type>
  55. >,
  56. // is never
  57. mpl::int_<track_never>,
  58. // otherwise its selective
  59. mpl::int_<track_selectively>
  60. > > >::type type;
  61. BOOST_STATIC_CONSTANT(int, value = type::value);
  62. };
  63. template<class T>
  64. struct tracking_level :
  65. public tracking_level_impl<const T>
  66. {
  67. };
  68. template<class T, enum tracking_type L>
  69. inline bool operator>=(tracking_level< T > t, enum tracking_type l)
  70. {
  71. return t.value >= (int)l;
  72. }
  73. } // namespace serialization
  74. } // namespace boost
  75. // The STATIC_ASSERT is prevents one from setting tracking for a primitive type.
  76. // This almost HAS to be an error. Doing this will effect serialization of all
  77. // char's in your program which is almost certainly what you don't want to do.
  78. // If you want to track all instances of a given primitive type, You'll have to
  79. // wrap it in your own type so its not a primitive anymore. Then it will compile
  80. // without problem.
  81. #define BOOST_CLASS_TRACKING(T, E) \
  82. namespace boost { \
  83. namespace serialization { \
  84. template<> \
  85. struct tracking_level< T > \
  86. { \
  87. typedef mpl::integral_c_tag tag; \
  88. typedef mpl::int_< E> type; \
  89. BOOST_STATIC_CONSTANT( \
  90. int, \
  91. value = tracking_level::type::value \
  92. ); \
  93. /* tracking for a class */ \
  94. BOOST_STATIC_ASSERT(( \
  95. mpl::greater< \
  96. /* that is a prmitive */ \
  97. implementation_level< T >, \
  98. mpl::int_<primitive_type> \
  99. >::value \
  100. )); \
  101. }; \
  102. }}
  103. #endif // BOOST_SERIALIZATION_TRACKING_HPP