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