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