1 //  Copyright (c) 2007-2017 Hartmut Kaiser
2 //  Copyright (c)      2011 Bryce Lelbach
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 #if !defined(HPX_RUNTIME_ACTIONS_MANAGE_OBJECT_ACTION_JAN_26_2010_0141PM)
8 #define HPX_RUNTIME_ACTIONS_MANAGE_OBJECT_ACTION_JAN_26_2010_0141PM
9 
10 #include <hpx/config.hpp>
11 #include <hpx/runtime/actions/action_support.hpp>
12 #include <hpx/runtime/serialization/array.hpp>
13 #include <hpx/runtime/serialization/base_object.hpp>
14 #include <hpx/runtime/serialization/serialize_buffer.hpp>
15 #include <hpx/util/assert.hpp>
16 #include <hpx/util/reinitializable_static.hpp>
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21 
22 #include <hpx/config/warnings_prefix.hpp>
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 namespace hpx { namespace actions
26 {
27     ///////////////////////////////////////////////////////////////////////////
28     struct HPX_API_EXPORT manage_object_action_base
29     {
30         typedef void (*construct_function)(void*, std::size_t);
31         typedef void (*clone_function)(void*, void const*, std::size_t);
32         typedef void (*assign_function)(void*, void const*, std::size_t);
33         typedef void (*destruct_function)(void*);
34 
35         typedef serialization::output_archive oarchive_type;
36         typedef serialization::input_archive iarchive_type;
37 
38         typedef void (*serialize_save_function)(
39             std::uint8_t const*, std::size_t, oarchive_type&,
40             const unsigned int, std::uint8_t const*);
41         typedef void (*serialize_load_function)(
42             std::uint8_t*, std::size_t, iarchive_type&,
43             const unsigned int, std::uint8_t const*);
44 
45     private:
construct_hpx::actions::manage_object_action_base46         static void construct_(void*, std::size_t) {}
clone_hpx::actions::manage_object_action_base47         static void clone_(void* dest, void const* src, std::size_t size)
48         {
49             using namespace std;    // some systems have memcpy in std
50             memcpy(dest, src, size);
51         }
assign_hpx::actions::manage_object_action_base52         static void assign_(void* dest, void const* src, std::size_t size) //-V524
53         {
54             using namespace std;    // some systems have memcpy in std
55             memcpy(dest, src, size);
56         }
destruct_hpx::actions::manage_object_action_base57         static void destruct_(void*) {}
58 
save_hpx::actions::manage_object_action_base59         static void save_(std::uint8_t const* data, std::size_t size,
60             oarchive_type& ar, const unsigned int,
61             std::uint8_t const*)
62         {
63             ar << hpx::serialization::make_array(data, size);
64         }
load_hpx::actions::manage_object_action_base65         static void load_(std::uint8_t* data, std::size_t size,
66             iarchive_type& ar, const unsigned int,
67             std::uint8_t const*)
68         {
69             ar >> hpx::serialization::make_array(data, size);
70         }
71 
72     public:
manage_object_action_basehpx::actions::manage_object_action_base73         manage_object_action_base() {}
~manage_object_action_basehpx::actions::manage_object_action_base74         virtual ~manage_object_action_base() {}
75 
76         // support for construction, copying, destruction
constructhpx::actions::manage_object_action_base77         virtual construct_function construct() const
78         {
79             return &manage_object_action_base::construct_;
80         }
clonehpx::actions::manage_object_action_base81         virtual clone_function clone() const
82         {
83             return &manage_object_action_base::clone_;
84         }
assignhpx::actions::manage_object_action_base85         virtual assign_function assign() const
86         {
87             return &manage_object_action_base::assign_;
88         }
destructhpx::actions::manage_object_action_base89         virtual destruct_function destruct() const
90         {
91             return &manage_object_action_base::destruct_;
92         }
93 
94         struct tag {};
95 
96         virtual manage_object_action_base const& get_instance() const;
97 
98         // serialization support
save_functionhpx::actions::manage_object_action_base99         virtual serialize_save_function save_function() const
100         {
101             return &manage_object_action_base::save_;
102         }
load_functionhpx::actions::manage_object_action_base103         virtual serialize_load_function load_function() const
104         {
105             return &manage_object_action_base::load_;
106         }
107 
108     private:
109         // serialization support, just serialize the type
110         friend class hpx::serialization::access;
111 
112         template<class Archive>
serializehpx::actions::manage_object_action_base113         void serialize(Archive&, const unsigned int) {}
114 
115         HPX_SERIALIZATION_POLYMORPHIC(manage_object_action_base)
116     };
117 
118     ///////////////////////////////////////////////////////////////////////////
119     template <typename T, typename Config = void>
120     struct manage_object_action;
121 
122     template <typename T>
123     struct manage_object_action<T, void> : manage_object_action_base
124     {
manage_object_actionhpx::actions::manage_object_action125         manage_object_action() {}
~manage_object_actionhpx::actions::manage_object_action126         ~manage_object_action() {}
127 
128     private:
construct_hpx::actions::manage_object_action129         static void construct_(void* memory, std::size_t size)
130         {
131             HPX_ASSERT(size == sizeof(T));
132             new (memory) T;
133         }
clone_hpx::actions::manage_object_action134         static void clone_(void* dest, void const* src, std::size_t size)
135         {
136             HPX_ASSERT(size == sizeof(T));
137             new (dest) T (*reinterpret_cast<T const*>(src));
138         }
assign_hpx::actions::manage_object_action139         static void assign_(void* dest, void const* src, std::size_t size)
140         {
141             HPX_ASSERT(size == sizeof(T));
142             // do not overwrite ourselves
143             if (src != dest)
144                 *reinterpret_cast<T*>(dest) = *reinterpret_cast<T const*>(src);
145         }
destruct_hpx::actions::manage_object_action146         static void destruct_(void* memory)
147         {
148             reinterpret_cast<T*>(memory)->~T();
149         }
150 
save_hpx::actions::manage_object_action151         static void save_(std::uint8_t const* data, std::size_t /*size*/,
152             oarchive_type& ar, const unsigned int /*version*/,
153             std::uint8_t const* /*config*/)
154         {
155             ar << *reinterpret_cast<T const*>(data);
156         }
load_hpx::actions::manage_object_action157         static void load_(std::uint8_t* data, std::size_t /*size*/,
158             iarchive_type& ar, const unsigned int /*version*/,
159             std::uint8_t const* /*config*/)
160         {
161             ar >> *reinterpret_cast<T*>(data);
162         }
163 
164     private:
165         // support for construction, copying, destruction
constructhpx::actions::manage_object_action166         construct_function construct() const
167         {
168             return &manage_object_action::construct_;
169         }
clonehpx::actions::manage_object_action170         clone_function clone() const
171         {
172             return &manage_object_action::clone_;
173         }
assignhpx::actions::manage_object_action174         assign_function assign() const
175         {
176             return &manage_object_action::assign_;
177         }
destructhpx::actions::manage_object_action178         destruct_function destruct() const
179         {
180             return &manage_object_action::destruct_;
181         }
182 
183         // serialization support
save_functionhpx::actions::manage_object_action184         serialize_save_function save_function() const
185         {
186             return &manage_object_action::save_;
187         }
load_functionhpx::actions::manage_object_action188         serialize_load_function load_function() const
189         {
190             return &manage_object_action::load_;
191         }
192 
193     public:
194         struct tag {};
195 
get_instancehpx::actions::manage_object_action196         virtual manage_object_action_base const& get_instance() const
197         {
198             // ensure thread-safe initialization
199             util::reinitializable_static<manage_object_action, tag> instance;
200             return instance.get();
201         }
202 
203     private:
204         // serialization support, just serialize the type
205         friend class hpx::serialization::access;
206 
207         template<class Archive>
serializehpx::actions::manage_object_action208         void serialize(Archive& ar, const unsigned int)
209         {
210             ar & hpx::serialization::base_object<manage_object_action_base>(*this);
211         }
212 
213         HPX_SERIALIZATION_POLYMORPHIC_TEMPLATE(manage_object_action)
214     };
215 
216     ///////////////////////////////////////////////////////////////////////////
217     template <>
218     struct manage_object_action<std::uint8_t> : manage_object_action_base
219     {
manage_object_actionhpx::actions::manage_object_action220         manage_object_action() {}
221 
222     private:
223         // serialization support, just serialize the type
224         friend class hpx::serialization::access;
225 
226         template<class Archive>
serializehpx::actions::manage_object_action227         void serialize(Archive& ar, const unsigned int)
228         {
229             ar & hpx::serialization::base_object<manage_object_action_base>(*this);
230         }
231 
232         HPX_SERIALIZATION_POLYMORPHIC(manage_object_action)
233     };
234 
235     inline manage_object_action_base const&
get_instance() const236     manage_object_action_base::get_instance() const
237     {
238         // ensure thread-safe initialization
239         util::reinitializable_static<manage_object_action<std::uint8_t>,
240             manage_object_action_base::tag> instance;
241         return instance.get();
242     }
243 
244     ///////////////////////////////////////////////////////////////////////////
245     template <typename T, typename Config>
246     struct manage_object_action : manage_object_action<T>
247     {
manage_object_actionhpx::actions::manage_object_action248         manage_object_action() {}
~manage_object_actionhpx::actions::manage_object_action249         ~manage_object_action() {}
250 
251         typedef typename manage_object_action<T>::oarchive_type oarchive_type;
252         typedef typename manage_object_action<T>::iarchive_type iarchive_type;
253 
254         typedef typename manage_object_action<T>::serialize_save_function
255             serialize_save_function;
256         typedef typename manage_object_action<T>::serialize_load_function
257             serialize_load_function;
258 
259     private:
save_hpx::actions::manage_object_action260         static void save_(std::uint8_t const* data, std::size_t /*size*/,
261             oarchive_type& ar, const unsigned int version,
262             std::uint8_t const* config)
263         {
264             reinterpret_cast<T const*>(data)->save(ar, version,
265                 reinterpret_cast<Config const*>(config));
266         }
load_hpx::actions::manage_object_action267         static void load_(std::uint8_t* data, std::size_t /*size*/,
268             iarchive_type& ar, const unsigned int version,
269             std::uint8_t const* config)
270         {
271             reinterpret_cast<T*>(data)->load(ar, version,
272                 reinterpret_cast<Config const*>(config));
273         }
274 
275     private:
276         // serialization support
save_functionhpx::actions::manage_object_action277         serialize_save_function save_function() const
278         {
279             return &manage_object_action::save_;
280         }
load_functionhpx::actions::manage_object_action281         serialize_load_function load_function() const
282         {
283             return &manage_object_action::load_;
284         }
285 
286     public:
287         struct tag {};
288 
get_instancehpx::actions::manage_object_action289         manage_object_action_base const& get_instance() const
290         {
291             // ensure thread-safe initialization
292             util::reinitializable_static<manage_object_action, tag> instance;
293             return instance.get();
294         }
295 
296     private:
297         // serialization support, just serialize the type
298         friend class hpx::serialization::access;
299 
300         template<class Archive>
serializehpx::actions::manage_object_action301         void serialize(Archive& ar, const unsigned int)
302         {
303             ar & hpx::serialization::base_object<manage_object_action<T> >(*this);
304         }
305 
306         HPX_SERIALIZATION_POLYMORPHIC_TEMPLATE(manage_object_action);
307     };
308 }}
309 
310 #include <hpx/config/warnings_suffix.hpp>
311 
312 #endif
313 
314 
315