Line data Source code
1 :
2 : /* Copyright (c) 2012, Daniel Nachbaur <daniel.nachbaur@gmail.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 3.0 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef LUNCHBOX_ANYSERIALIZATION_H
19 : #define LUNCHBOX_ANYSERIALIZATION_H
20 :
21 : #include <lunchbox/any.h>
22 : #include <lunchbox/types.h>
23 : #include <servus/uint128_t.h>
24 :
25 : #include <boost/mpl/for_each.hpp>
26 : #include <boost/mpl/list.hpp>
27 :
28 : #include <boost/serialization/export.hpp>
29 : #include <boost/serialization/extended_type_info.hpp>
30 :
31 : /**
32 : * Declares the given class to be serializable within a lunchbox::Any.
33 : * User is supposed to use this macro on global scope and in the compilation
34 : * unit where this class is to be serialized.
35 : */
36 : #define SERIALIZABLEANY(CLASS) BOOST_CLASS_EXPORT(lunchbox::Any::holder<CLASS>)
37 :
38 : namespace lunchbox
39 : {
40 : /** List of supported POD types for lunchbox::Any serialization. */
41 : typedef boost::mpl::list<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
42 : int64_t, uint64_t, float, double, bool, std::string,
43 : servus::uint128_t>
44 : podTypes;
45 :
46 : /** @cond IGNORE */
47 : /**
48 : * @internal
49 : * Utility struct for registering types for lunchbox::Any from a type list.
50 : */
51 : template <class Archive>
52 : struct registerWrapper
53 : {
54 56 : explicit registerWrapper(Archive& ar)
55 56 : : ar_(ar)
56 : {
57 56 : }
58 : Archive& ar_;
59 :
60 : template <typename T>
61 728 : void operator()(T)
62 : {
63 728 : ar_.template register_type<Any::holder<T> >();
64 728 : }
65 : };
66 : /** @endcond */
67 :
68 : /**
69 : * Registers the types from the given type list for serializing it inside a
70 : * lunchbox::Any through the given archive.
71 : */
72 : template <class TypeList, class Archive>
73 56 : void registerTypelist(Archive& ar)
74 : {
75 56 : boost::mpl::for_each<TypeList>(registerWrapper<Archive>(ar));
76 56 : }
77 :
78 : /**
79 : * Serializes the given object which can be a lunchbox::Any through the given
80 : * archive type to/from the given stream.
81 : */
82 : template <class Archive, class Object, class Stream>
83 : void serializeAny(Object& object, Stream& stream)
84 : {
85 : Archive ar(stream);
86 : registerTypelist<podTypes>(ar);
87 : ar& object;
88 : }
89 :
90 : /**
91 : * Saves the given object which can be a lunchbox::Any through the given archive
92 : * type to/from the given stream.
93 : */
94 : template <class Archive, class Object, class Stream>
95 28 : void saveAny(Object& object, Stream& stream)
96 : {
97 56 : Archive ar(stream);
98 28 : registerTypelist<podTypes>(ar);
99 28 : ar << object;
100 28 : }
101 :
102 : /**
103 : * Loads the given object which can be a lunchbox::Any through the given archive
104 : * type to/from the given stream.
105 : */
106 : template <class Archive, class Object, class Stream>
107 28 : void loadAny(Object& object, Stream& stream)
108 : {
109 56 : Archive ar(stream);
110 28 : registerTypelist<podTypes>(ar);
111 28 : ar >> object;
112 28 : }
113 : }
114 :
115 : #endif
|