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
45namespace boost {
46namespace serialization {
47///////////////////////////////////////////////////////////////////////
48// define a special type_info that doesn't depend on rtti which is not
49// available in all situations.
50
51namespace 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
55class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 :
56 public extended_type_info
57{
58protected:
59 BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key);
60 BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0();
61public:
62 virtual BOOST_SERIALIZATION_DECL bool
63 is_less_than(const boost::serialization::extended_type_info &rhs) const ;
64 virtual BOOST_SERIALIZATION_DECL bool
65 is_equal(const boost::serialization::extended_type_info &rhs) const ;
66};
67
68} // no_rtti_system
69
70template<class T>
71class 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 {
78 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 };
90 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 };
100public:
101 extended_type_info_no_rtti() :
102 no_rtti_system::extended_type_info_no_rtti_0(get_key())
103 {
104 key_register();
105 }
106 ~extended_type_info_no_rtti(){
107 key_unregister();
108 }
109 const extended_type_info *
110 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 polymporphic 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(key: derived_key);
120 }
121 const char * get_key() const{
122 return action<guid_defined< T >::value >::invoke();
123 }
124 virtual const char * get_debug_info() const{
125 return action<guid_defined< T >::value >::invoke();
126 }
127 virtual void * construct(unsigned int count, ...) const{
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 }
148 virtual void destroy(void const * const p) const{
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

source code of boost/boost/serialization/extended_type_info_no_rtti.hpp