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