Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / serialization / export.hpp
1 #ifndef BOOST_SERIALIZATION_EXPORT_HPP
2 #define BOOST_SERIALIZATION_EXPORT_HPP
3
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER)
6 # pragma once
7 #endif
8
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // export.hpp: set traits of classes to be serialized
11
12 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
13 // Use, modification and distribution is subject to the Boost Software
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16
17 //  See http://www.boost.org for updates, documentation, and revision history.
18
19 // (C) Copyright 2006 David Abrahams - http://www.boost.org.
20 // implementation of class export functionality.  This is an alternative to
21 // "forward declaration" method to provoke instantiation of derived classes
22 // that are to be serialized through pointers.
23
24 #include <utility>
25 #include <cstddef> // NULL
26
27 #include <boost/config.hpp>
28 #include <boost/static_assert.hpp>
29 #include <boost/preprocessor/stringize.hpp>
30 #include <boost/type_traits/is_polymorphic.hpp>
31
32 #include <boost/mpl/assert.hpp>
33 #include <boost/mpl/and.hpp>
34 #include <boost/mpl/not.hpp>
35 #include <boost/mpl/bool.hpp>
36
37 #include <boost/serialization/extended_type_info.hpp> // for guid_defined only
38 #include <boost/serialization/static_warning.hpp>
39 #include <boost/serialization/assume_abstract.hpp>
40 #include <boost/serialization/force_include.hpp>
41 #include <boost/serialization/singleton.hpp>
42
43 #include <boost/archive/detail/register_archive.hpp>
44
45 #include <iostream>
46
47 namespace boost {
48 namespace archive {
49 namespace detail {
50
51 class basic_pointer_iserializer;
52 class basic_pointer_oserializer;
53
54 template<class Archive, class T>
55 class pointer_iserializer;
56 template<class Archive, class T>
57 class pointer_oserializer;
58
59 template <class Archive, class Serializable>
60 struct export_impl
61 {
62     static const basic_pointer_iserializer &
63     enable_load(mpl::true_){
64         return boost::serialization::singleton<
65             pointer_iserializer<Archive, Serializable> 
66         >::get_const_instance();
67     }
68
69     static const basic_pointer_oserializer &
70     enable_save(mpl::true_){
71         return boost::serialization::singleton<
72             pointer_oserializer<Archive, Serializable> 
73         >::get_const_instance();
74     }
75     inline static void enable_load(mpl::false_) {}
76     inline static void enable_save(mpl::false_) {}
77 };
78
79 // On many platforms, naming a specialization of this template is
80 // enough to cause its argument to be instantiated.
81 template <void(*)()>
82 struct instantiate_function {};
83
84 template <class Archive, class Serializable>
85 struct ptr_serialization_support
86 {
87 # if defined(BOOST_MSVC) || defined(__SUNPRO_CC)
88     virtual BOOST_DLLEXPORT void instantiate() BOOST_USED;
89 # elif defined(__BORLANDC__)   
90     static BOOST_DLLEXPORT void instantiate() BOOST_USED;
91     enum { x = sizeof(instantiate(),3) };
92 # else
93     static BOOST_DLLEXPORT void instantiate() BOOST_USED;
94     typedef instantiate_function<
95         &ptr_serialization_support::instantiate
96     > x;
97 # endif
98 };
99
100 template <class Archive, class Serializable>
101 BOOST_DLLEXPORT void 
102 ptr_serialization_support<Archive,Serializable>::instantiate()
103 {
104     export_impl<Archive,Serializable>::enable_save(
105         #if ! defined(__BORLANDC__)
106         typename 
107         #endif
108         Archive::is_saving()
109     );
110
111     export_impl<Archive,Serializable>::enable_load(
112         #if ! defined(__BORLANDC__)
113         typename 
114         #endif
115         Archive::is_loading()
116     );
117 }
118
119 // Note INTENTIONAL usage of anonymous namespace in header.
120 // This was made this way so that export.hpp could be included
121 // in other headers.  This is still under study.
122
123 namespace extra_detail {
124
125 template<class T>
126 struct guid_initializer
127 {
128     void export_guid(mpl::false_) const {
129         // generates the statically-initialized objects whose constructors
130         // register the information allowing serialization of T objects
131         // through pointers to their base classes.
132         instantiate_ptr_serialization((T*)0, 0, adl_tag());
133     }
134     void export_guid(mpl::true_) const {
135     }
136     guid_initializer const & export_guid() const {
137         BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value);
138         // note: exporting an abstract base class will have no effect
139         // and cannot be used to instantitiate serialization code
140         // (one might be using this in a DLL to instantiate code)
141         //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
142         export_guid(boost::serialization::is_abstract< T >());
143         return *this;
144     }
145 };
146
147 template<typename T>
148 struct init_guid;
149
150 } // anonymous
151 } // namespace detail
152 } // namespace archive
153 } // namespace boost
154
155 #define BOOST_CLASS_EXPORT_IMPLEMENT(T)                      \
156     namespace boost {                                        \
157     namespace archive {                                      \
158     namespace detail {                                       \
159     namespace extra_detail {                                 \
160     template<>                                               \
161     struct init_guid< T > {                                  \
162         static guid_initializer< T > const & g;              \
163     };                                                       \
164     guid_initializer< T > const & init_guid< T >::g =        \
165         ::boost::serialization::singleton<                   \
166             guid_initializer< T >                            \
167         >::get_mutable_instance().export_guid();             \
168     }}}}                                                     \
169 /**/
170
171 #define BOOST_CLASS_EXPORT_KEY2(T, K)          \
172 namespace boost {                              \
173 namespace serialization {                      \
174 template<>                                     \
175 struct guid_defined< T > : boost::mpl::true_ {}; \
176 template<>                                     \
177 inline const char * guid< T >(){                 \
178     return K;                                  \
179 }                                              \
180 } /* serialization */                          \
181 } /* boost */                                  \
182 /**/
183
184 #define BOOST_CLASS_EXPORT_KEY(T)                                      \
185     BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T))                                                                  \
186 /**/
187
188 #define BOOST_CLASS_EXPORT_GUID(T, K)                                  \
189 BOOST_CLASS_EXPORT_KEY2(T, K)                                          \
190 BOOST_CLASS_EXPORT_IMPLEMENT(T)                                        \
191 /**/
192
193 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
194
195 // CodeWarrior fails to construct static members of class templates
196 // when they are instantiated from within templates, so on that
197 // compiler we ask users to specifically register base/derived class
198 // relationships for exported classes.  On all other compilers, use of
199 // this macro is entirely optional.
200 # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived)             \
201 namespace {                                                                    \
202   static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) =        \
203   (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \
204   static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = (     \
205       ::boost::serialization::void_cast_register((Derived*)0,(Base*)0)         \
206     , 3);                                                                      \
207 }
208
209 #else
210
211 # define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived)
212
213 #endif 
214
215 // check for unnecessary export.  T isn't polymorphic so there is no
216 // need to export it.
217 #define BOOST_CLASS_EXPORT_CHECK(T)                              \
218     BOOST_STATIC_WARNING(                                        \
219         boost::is_polymorphic<U>::value                          \
220     );                                                           \
221     /**/
222
223 // the default exportable class identifier is the class name
224 // the default list of archives types for which code id generated
225 // are the originally included with this serialization system
226 #define BOOST_CLASS_EXPORT(T)                   \
227     BOOST_CLASS_EXPORT_GUID(                    \
228         T,                                      \
229         BOOST_PP_STRINGIZE(T)                   \
230     )                                           \
231     /**/
232
233 #endif // BOOST_SERIALIZATION_EXPORT_HPP
234