1 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
2 | |
3 | // (C) Copyright 2002-4 Pavel Vozenilek . |
4 | // Use, modification and distribution is subject to the Boost Software |
5 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | // Provides non-intrusive serialization for boost::optional. |
9 | |
10 | #ifndef BOOST_SERIALIZATION_OPTIONAL_HPP |
11 | #define BOOST_SERIALIZATION_OPTIONAL_HPP |
12 | |
13 | #if defined(_MSC_VER) |
14 | # pragma once |
15 | #endif |
16 | |
17 | #include <boost/config.hpp> |
18 | #include <boost/optional.hpp> |
19 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL |
20 | #include <optional> |
21 | #endif |
22 | |
23 | #include <boost/serialization/item_version_type.hpp> |
24 | #include <boost/serialization/library_version_type.hpp> |
25 | #include <boost/serialization/version.hpp> |
26 | #include <boost/serialization/split_free.hpp> |
27 | #include <boost/serialization/nvp.hpp> |
28 | #include <boost/type_traits/is_pointer.hpp> |
29 | #include <boost/serialization/detail/is_default_constructible.hpp> |
30 | |
31 | // function specializations must be defined in the appropriate |
32 | // namespace - boost::serialization |
33 | namespace boost { |
34 | namespace serialization { |
35 | namespace detail { |
36 | |
37 | // OT is of the form optional<T> |
38 | template<class Archive, class OT> |
39 | void save_impl( |
40 | Archive & ar, |
41 | const OT & ot |
42 | ){ |
43 | // It is an inherent limitation to the serialization of optional.hpp |
44 | // that the underlying type must be either a pointer or must have a |
45 | // default constructor. It's possible that this could change sometime |
46 | // in the future, but for now, one will have to work around it. This can |
47 | // be done by serialization the optional<T> as optional<T *> |
48 | #ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS |
49 | BOOST_STATIC_ASSERT( |
50 | boost::serialization::detail::is_default_constructible<typename OT::value_type>::value |
51 | || boost::is_pointer<typename OT::value_type>::value |
52 | ); |
53 | #endif |
54 | const bool tflag(ot); |
55 | ar << boost::serialization::make_nvp(n: "initialized" , v: tflag); |
56 | if (tflag){ |
57 | ar << boost::serialization::make_nvp("value" , *ot); |
58 | } |
59 | } |
60 | |
61 | // OT is of the form optional<T> |
62 | template<class Archive, class OT> |
63 | void load_impl( |
64 | Archive & ar, |
65 | OT & ot, |
66 | const unsigned int version |
67 | ){ |
68 | bool tflag; |
69 | ar >> boost::serialization::make_nvp(n: "initialized" , v&: tflag); |
70 | if(! tflag){ |
71 | ot.reset(); |
72 | return; |
73 | } |
74 | |
75 | if(0 == version){ |
76 | boost::serialization::item_version_type item_version(0); |
77 | boost::serialization::library_version_type library_version( |
78 | ar.get_library_version() |
79 | ); |
80 | if(boost::serialization::library_version_type(3) < library_version){ |
81 | ar >> BOOST_SERIALIZATION_NVP(item_version); |
82 | } |
83 | } |
84 | typename OT::value_type t; |
85 | ar >> boost::serialization::make_nvp("value" ,t); |
86 | ot = t; |
87 | } |
88 | |
89 | } // detail |
90 | |
91 | template<class Archive, class T> |
92 | void save( |
93 | Archive & ar, |
94 | const boost::optional< T > & ot, |
95 | const unsigned int /*version*/ |
96 | ){ |
97 | detail::save_impl(ar, ot); |
98 | } |
99 | |
100 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL |
101 | template<class Archive, class T> |
102 | void save( |
103 | Archive & ar, |
104 | const std::optional< T > & ot, |
105 | const unsigned int /*version*/ |
106 | ){ |
107 | detail::save_impl(ar, ot); |
108 | } |
109 | #endif |
110 | |
111 | template<class Archive, class T> |
112 | void load( |
113 | Archive & ar, |
114 | boost::optional< T > & ot, |
115 | const unsigned int version |
116 | ){ |
117 | detail::load_impl(ar, ot, version); |
118 | } |
119 | |
120 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL |
121 | template<class Archive, class T> |
122 | void load( |
123 | Archive & ar, |
124 | std::optional< T > & ot, |
125 | const unsigned int version |
126 | ){ |
127 | detail::load_impl(ar, ot, version); |
128 | } |
129 | #endif |
130 | |
131 | template<class Archive, class T> |
132 | void serialize( |
133 | Archive & ar, |
134 | boost::optional< T > & ot, |
135 | const unsigned int version |
136 | ){ |
137 | boost::serialization::split_free(ar, ot, version); |
138 | } |
139 | |
140 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL |
141 | template<class Archive, class T> |
142 | void serialize( |
143 | Archive & ar, |
144 | std::optional< T > & ot, |
145 | const unsigned int version |
146 | ){ |
147 | boost::serialization::split_free(ar, ot, version); |
148 | } |
149 | #endif |
150 | |
151 | template<class T> |
152 | struct version<boost::optional<T> >{ |
153 | BOOST_STATIC_CONSTANT(int, value = 1); |
154 | }; |
155 | |
156 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL |
157 | template<class T> |
158 | struct version<std::optional<T> >{ |
159 | BOOST_STATIC_CONSTANT(int, value = 1); |
160 | }; |
161 | #endif |
162 | |
163 | } // serialization |
164 | } // boost |
165 | |
166 | #endif // BOOST_SERIALIZATION_OPTIONAL_HPP |
167 | |