extended_type_info_no_rtti.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP
  2. #define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP
  3. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  4. // MS compatible compilers support #pragma once
  5. #if defined(_MSC_VER)
  6. # pragma once
  7. #endif
  8. // extended_type_info_no_rtti.hpp: implementation for version that depends
  9. // on runtime typing (rtti - typeid) but uses a user specified string
  10. // as the portable class identifier.
  11. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  12. // Use, modification and distribution is subject to the Boost Software
  13. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. // See http://www.boost.org for updates, documentation, and revision history.
  16. #include <boost/assert.hpp>
  17. #include <boost/config.hpp>
  18. #include <boost/static_assert.hpp>
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/type_traits/is_polymorphic.hpp>
  21. #include <boost/type_traits/remove_const.hpp>
  22. #include <boost/serialization/static_warning.hpp>
  23. #include <boost/serialization/singleton.hpp>
  24. #include <boost/serialization/extended_type_info.hpp>
  25. #include <boost/serialization/factory.hpp>
  26. #include <boost/serialization/throw_exception.hpp>
  27. #include <boost/serialization/config.hpp>
  28. // hijack serialization access
  29. #include <boost/serialization/access.hpp>
  30. #include <boost/config/abi_prefix.hpp> // must be the last header
  31. #ifdef BOOST_MSVC
  32. # pragma warning(push)
  33. # pragma warning(disable : 4251 4231 4660 4275 4511 4512)
  34. #endif
  35. namespace boost {
  36. namespace serialization {
  37. ///////////////////////////////////////////////////////////////////////
  38. // define a special type_info that doesn't depend on rtti which is not
  39. // available in all situations.
  40. namespace no_rtti_system {
  41. // common base class to share type_info_key. This is used to
  42. // identify the method used to keep track of the extended type
  43. class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 :
  44. public extended_type_info
  45. {
  46. protected:
  47. BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key);
  48. BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0();
  49. public:
  50. virtual BOOST_SERIALIZATION_DECL bool
  51. is_less_than(const boost::serialization::extended_type_info &rhs) const ;
  52. virtual BOOST_SERIALIZATION_DECL bool
  53. is_equal(const boost::serialization::extended_type_info &rhs) const ;
  54. };
  55. } // no_rtti_system
  56. template<class T>
  57. class extended_type_info_no_rtti :
  58. public no_rtti_system::extended_type_info_no_rtti_0,
  59. public singleton<extended_type_info_no_rtti< T > >
  60. {
  61. template<bool tf>
  62. struct action {
  63. struct defined {
  64. static const char * invoke(){
  65. return guid< T >();
  66. }
  67. };
  68. struct undefined {
  69. // if your program traps here - you failed to
  70. // export a guid for this type. the no_rtti
  71. // system requires export for types serialized
  72. // as pointers.
  73. BOOST_STATIC_ASSERT(0 == sizeof(T));
  74. static const char * invoke();
  75. };
  76. static const char * invoke(){
  77. typedef
  78. typename boost::mpl::if_c<
  79. tf,
  80. defined,
  81. undefined
  82. >::type type;
  83. return type::invoke();
  84. }
  85. };
  86. public:
  87. extended_type_info_no_rtti() :
  88. no_rtti_system::extended_type_info_no_rtti_0(get_key())
  89. {
  90. key_register();
  91. }
  92. ~extended_type_info_no_rtti(){
  93. key_unregister();
  94. }
  95. const extended_type_info *
  96. get_derived_extended_type_info(const T & t) const {
  97. // find the type that corresponds to the most derived type.
  98. // this implementation doesn't depend on typeid() but assumes
  99. // that the specified type has a function of the following signature.
  100. // A common implemention of such a function is to define as a virtual
  101. // function. So if the is not a polymporphic type it's likely an error
  102. BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value);
  103. const char * derived_key = t.get_key();
  104. BOOST_ASSERT(NULL != derived_key);
  105. return boost::serialization::extended_type_info::find(derived_key);
  106. }
  107. const char * get_key() const{
  108. return action<guid_defined< T >::value >::invoke();
  109. }
  110. virtual const char * get_debug_info() const{
  111. return action<guid_defined< T >::value >::invoke();
  112. }
  113. virtual void * construct(unsigned int count, ...) const{
  114. // count up the arguments
  115. std::va_list ap;
  116. va_start(ap, count);
  117. switch(count){
  118. case 0:
  119. return factory<typename boost::remove_const< T >::type, 0>(ap);
  120. case 1:
  121. return factory<typename boost::remove_const< T >::type, 1>(ap);
  122. case 2:
  123. return factory<typename boost::remove_const< T >::type, 2>(ap);
  124. case 3:
  125. return factory<typename boost::remove_const< T >::type, 3>(ap);
  126. case 4:
  127. return factory<typename boost::remove_const< T >::type, 4>(ap);
  128. default:
  129. BOOST_ASSERT(false); // too many arguments
  130. // throw exception here?
  131. return NULL;
  132. }
  133. }
  134. virtual void destroy(void const * const p) const{
  135. boost::serialization::access::destroy(
  136. static_cast<T const *>(p)
  137. );
  138. //delete static_cast<T const * const>(p) ;
  139. }
  140. };
  141. } // namespace serialization
  142. } // namespace boost
  143. ///////////////////////////////////////////////////////////////////////////////
  144. // If no other implementation has been designated as default,
  145. // use this one. To use this implementation as the default, specify it
  146. // before any of the other headers.
  147. #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
  148. #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
  149. namespace boost {
  150. namespace serialization {
  151. template<class T>
  152. struct extended_type_info_impl {
  153. typedef typename
  154. boost::serialization::extended_type_info_no_rtti< T > type;
  155. };
  156. } // namespace serialization
  157. } // namespace boost
  158. #endif
  159. #ifdef BOOST_MSVC
  160. # pragma warning(pop)
  161. #endif
  162. #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
  163. #endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP