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