/
access.hpp
138 lines (121 loc) · 4.43 KB
/
access.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2014 Thomas Heller
// Copyright (c) 2014-2015 Anton Bikineev
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef HPX_SERIALIZATION_ACCESS_HPP
#define HPX_SERIALIZATION_ACCESS_HPP
#include <hpx/runtime/serialization/serialization_fwd.hpp>
#include <hpx/traits/polymorphic_traits.hpp>
#include <hpx/traits/has_serialize.hpp>
#include <hpx/util/decay.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/identity.hpp>
#include <string>
namespace hpx { namespace serialization
{
namespace detail
{
template <class Archive, class T> BOOST_FORCEINLINE
void serialize_force_adl(Archive& ar, T& t, unsigned)
{
serialize(ar, t, 0);
}
}
class access
{
template <class T>
class serialize_dispatcher
{
struct intrusive_polymorphic
{
// both following template functions are viable
// to call right overloaded function according to T constness
// and to prevent calling templated version of serialize function
static void call(hpx::serialization::input_archive& ar, T& t, unsigned)
{
t.serialize(ar, 0);
}
static void call(hpx::serialization::output_archive& ar,
const T& t, unsigned)
{
t.serialize(ar, 0);
}
};
struct non_intrusive
{
// this additional indirection level is needed to
// force ADL on the second phase of template lookup.
// call of serialize function directly from base_object
// finds only serialize-member function and doesn't
// perform ADL
template <class Archive>
static void call(Archive& ar, T& t, unsigned)
{
detail::serialize_force_adl(ar, t, 0);
}
};
struct empty
{
template <class Archive>
static void call(Archive& ar, T& t, unsigned)
{
}
};
struct intrusive_usual
{
template <class Archive>
static void call(Archive& ar, T& t, unsigned)
{
// cast it to let it be run for templated
// member functions
const_cast<typename util::decay<T>::type&>(
t).serialize(ar, 0);
}
};
public:
typedef typename boost::mpl::eval_if<
hpx::traits::is_intrusive_polymorphic<T>,
boost::mpl::identity<intrusive_polymorphic>,
boost::mpl::eval_if<
hpx::traits::has_serialize<T>,
boost::mpl::identity<intrusive_usual>,
boost::mpl::eval_if<
boost::is_empty<T>,
boost::mpl::identity<empty>,
boost::mpl::identity<non_intrusive>
>
>
>::type type;
};
public:
template <class Archive, class T>
static void serialize(Archive& ar, T& t, unsigned)
{
serialize_dispatcher<T>::type::call(ar, t, 0);
}
template <typename Archive, typename T> BOOST_FORCEINLINE
static void save_base_object(Archive & ar, const T & t, unsigned)
{
// explicitly specify virtual function
// of base class to avoid infinite recursion
t.T::save(ar, 0);
}
template <typename Archive, typename T> BOOST_FORCEINLINE
static void load_base_object(Archive & ar, T & t, unsigned)
{
// explicitly specify virtual function
// of base class to avoid infinite recursion
t.T::load(ar, 0);
}
template <typename T> BOOST_FORCEINLINE
static std::string get_name(const T* t)
{
return t->hpx_serialization_get_name();
}
};
}}
#endif