Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/serialization/export.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 9.7 KB
Line 
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) && (_MSC_VER >= 1020)
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// implementation of class export functionality.  This is an alternative to
20// "forward declaration" method to provoke instantiation of derived classes
21// that are to be serialized through pointers.
22
23#include <utility>
24
25#include <boost/config.hpp>
26
27// if no archive headers have been included this is a no op
28// this is to permit BOOST_EXPORT etc to be included in a
29// file declaration header
30#if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP)
31#define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)
32
33#else
34#include <boost/static_assert.hpp>
35#include <boost/preprocessor/stringize.hpp>
36#include <boost/mpl/eval_if.hpp>
37#include <boost/mpl/or.hpp>
38#include <boost/mpl/empty.hpp>
39#include <boost/mpl/front.hpp>
40#include <boost/mpl/pop_front.hpp>
41#include <boost/mpl/void.hpp>
42#include <boost/mpl/identity.hpp>
43
44#include <boost/archive/detail/known_archive_types.hpp>
45#include <boost/serialization/force_include.hpp>
46#include <boost/serialization/type_info_implementation.hpp>
47#include <boost/serialization/is_abstract.hpp>
48
49namespace boost {
50namespace archive {
51namespace detail {
52
53// forward template declarations
54class basic_pointer_iserializer;
55template<class Archive, class T>
56BOOST_DLLEXPORT const basic_pointer_iserializer &
57instantiate_pointer_iserializer(Archive * ar, T *) BOOST_USED;
58
59class basic_pointer_oserializer;
60template<class Archive, class T>
61BOOST_DLLEXPORT const basic_pointer_oserializer &
62instantiate_pointer_oserializer(Archive * ar, T *) BOOST_USED;
63
64namespace export_impl
65{
66    struct nothing{
67        static void instantiate(){}
68    };
69
70    template<class Archive, class T>
71    struct archive {
72        struct i {
73            static void invoke(){
74                instantiate_pointer_iserializer(
75                    static_cast<Archive *>(NULL),
76                    static_cast<T *>(NULL)
77                );
78            }
79        };
80        struct o {
81            static void invoke(){
82                instantiate_pointer_oserializer(
83                    static_cast<Archive *>(NULL),
84                    static_cast<T *>(NULL)
85                );
86            }
87        };
88        static void instantiate(){
89            #if defined(__GNUC__) && (__GNUC__ >= 3)
90            BOOST_STATIC_ASSERT(
91                Archive::is_loading::value || Archive::is_saving::value
92            );
93            #endif
94            typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
95                BOOST_DEDUCED_TYPENAME Archive::is_saving,
96                mpl::identity<o>,
97            // else
98            BOOST_DEDUCED_TYPENAME mpl::eval_if<
99                BOOST_DEDUCED_TYPENAME Archive::is_loading,
100                mpl::identity<i>,
101            // else
102                mpl::identity<nothing>
103            > >::type typex;
104            typex::invoke();
105        }
106    };
107
108    template<class ASeq, class T>
109    struct for_each_archive {
110    private:
111        typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<ASeq>::type tail;
112        typedef BOOST_DEDUCED_TYPENAME mpl::front<ASeq>::type head;
113    public:
114        static void instantiate(){
115            archive<head, T>::instantiate();
116            typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
117                mpl::empty<tail>,
118                mpl::identity<nothing>,
119                mpl::identity<for_each_archive<tail, T> >
120            >::type typex;
121            typex::instantiate();
122        }
123    };
124
125} // namespace export_impl
126
127// strictly conforming
128template<class T, class ASeq>
129struct export_generator {
130    export_generator(){
131        export_impl::for_each_archive<ASeq, T>::instantiate();
132    }
133    static const export_generator instance;
134};
135
136template<class T, class ASeq>
137const export_generator<T, ASeq>
138    export_generator<T, ASeq>::instance;
139
140// instantiation of this template creates a static object.
141template<class T>
142struct guid_initializer {
143    typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type eti_type;
144    static void export_register(const char *key){
145        eti_type::export_register(key);
146    }
147    static const guid_initializer instance;
148    guid_initializer(const char *key = 0) BOOST_USED ;
149};
150
151template<class T>
152guid_initializer<T>::guid_initializer(const char *key){
153    if(0 != key)
154        export_register(key);
155}
156
157template<class T>
158const guid_initializer<T> guid_initializer<T>::instance;
159
160// only gcc seems to be able to explicitly instantiate a static instance.
161// but all can instantiate a function that refers to a static instance
162
163// the following optimization - inhibiting explicit instantiation for abstract
164// classes breaks msvc compliles
165template<class T, class ASeq>
166struct export_instance {
167    struct abstract {
168        static const export_generator<T, ASeq> *
169        invoke(){
170            return 0;
171        }
172    };
173    struct not_abstract {
174        static const export_generator<T, ASeq> *
175        invoke(){
176            return & export_generator<T, ASeq>::instance;
177        }
178    };
179};
180
181template<class T, class ASeq>
182BOOST_DLLEXPORT
183std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
184export_instance_invoke() {
185    typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
186        serialization::is_abstract<T>,
187        mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::abstract>,
188        mpl::identity<BOOST_DEDUCED_TYPENAME export_instance<T, ASeq>::not_abstract>
189    >::type typex;
190    return std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>(
191        typex::invoke(),
192        & guid_initializer<T>::instance
193    );
194}
195
196template<class T, class ASeq>
197struct export_archives {
198    struct empty_archive_list {
199        static BOOST_DLLEXPORT
200        std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
201        invoke(){
202            return std::pair<const export_generator<T, ASeq> *,
203                             const guid_initializer<T> *>(0, 0);
204        }
205    };
206    struct non_empty_archive_list {
207        static BOOST_DLLEXPORT
208        std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
209        invoke(){
210            return export_instance_invoke<T, ASeq>();
211        }
212    };
213};
214
215template<class T, class ASeq>
216BOOST_DLLEXPORT
217std::pair<const export_generator<T, ASeq> *, const guid_initializer<T> *>
218export_archives_invoke(T &, ASeq &){
219    typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
220        mpl::empty<ASeq>,
221        mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::empty_archive_list>,
222        mpl::identity<BOOST_DEDUCED_TYPENAME export_archives<T, ASeq>::non_empty_archive_list>
223    >::type typex;
224    return typex::invoke();
225}
226
227} // namespace detail
228} // namespace archive
229} // namespace boost
230
231#define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)         \
232    namespace boost {                                            \
233    namespace archive {                                          \
234    namespace detail {                                           \
235    template<>                                                   \
236    const guid_initializer< T >                                  \
237        guid_initializer< T >::instance(K);                      \
238    template                                                     \
239    BOOST_DLLEXPORT                                              \
240    std::pair<const export_generator<T, ASEQ> *, const guid_initializer< T > *> \
241    export_archives_invoke<T, ASEQ>(T &, ASEQ &);                \
242    } } }                                                        \
243    /**/
244
245#endif
246
247// check for unnecessary export.  T isn't polymorphic so there is no
248// need to export it.
249#define BOOST_CLASS_EXPORT_CHECK(T)                              \
250    BOOST_STATIC_WARNING(                                        \
251        boost::serialization::type_info_implementation< T >      \
252            ::type::is_polymorphic::value                        \
253    );                                                           \
254    /**/
255
256// the default list of archives types for which code id generated
257#define BOOST_CLASS_EXPORT_GUID(T, K)                            \
258    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(                        \
259        T,                                                       \
260        K,                                                       \
261        boost::archive::detail::known_archive_types::type        \
262    )                                                            \
263    /**/
264
265// the default exportable class identifier is the class name
266#define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ)                 \
267    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, BOOST_PP_STRINGIZE(T), A)
268
269// the default exportable class identifier is the class name
270// the default list of archives types for which code id generated
271// are the originally included with this serialization system
272#define BOOST_CLASS_EXPORT(T)                                    \
273    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(                        \
274        T,                                                       \
275        BOOST_PP_STRINGIZE(T),                                   \
276        boost::archive::detail::known_archive_types::type        \
277    )                                                            \
278    /**/
279
280#endif // BOOST_SERIALIZATION_EXPORT_HPP
Note: See TracBrowser for help on using the repository browser.