|
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) && (_MSC_VER >= 1020) |
|
14 # pragma once |
|
15 #endif |
|
16 |
|
17 #include <boost/config.hpp> |
|
18 |
|
19 #include <boost/optional.hpp> |
|
20 #include <boost/serialization/split_free.hpp> |
|
21 #include <boost/serialization/level.hpp> |
|
22 #include <boost/serialization/nvp.hpp> |
|
23 #include <boost/serialization/detail/stack_constructor.hpp> |
|
24 |
|
25 // function specializations must be defined in the appropriate |
|
26 // namespace - boost::serialization |
|
27 namespace boost { |
|
28 namespace serialization { |
|
29 |
|
30 template<class Archive, class T> |
|
31 void save( |
|
32 Archive & ar, |
|
33 const boost::optional<T> & t, |
|
34 const unsigned int /*version*/ |
|
35 ){ |
|
36 const bool tflag = t.is_initialized(); |
|
37 ar << boost::serialization::make_nvp("initialized", tflag); |
|
38 if (tflag){ |
|
39 if(3 < ar.get_library_version()){ |
|
40 const int v = version<T>::value; |
|
41 ar << make_nvp("item_version", v); |
|
42 } |
|
43 ar << boost::serialization::make_nvp("value", *t); |
|
44 } |
|
45 } |
|
46 |
|
47 template<class Archive, class T> |
|
48 void load( |
|
49 Archive & ar, |
|
50 boost::optional<T> & t, |
|
51 const unsigned int /*version*/ |
|
52 ){ |
|
53 bool tflag; |
|
54 ar >> boost::serialization::make_nvp("initialized", tflag); |
|
55 if (tflag){ |
|
56 unsigned int v; |
|
57 if(3 < ar.get_library_version()){ |
|
58 ar >> make_nvp("item_version", v); |
|
59 } |
|
60 detail::stack_construct<Archive, T> aux(ar, v); |
|
61 ar >> boost::serialization::make_nvp("value", aux.reference()); |
|
62 t.reset(aux.reference()); |
|
63 } |
|
64 else { |
|
65 t.reset(); |
|
66 } |
|
67 } |
|
68 |
|
69 template<class Archive, class T> |
|
70 void serialize( |
|
71 Archive & ar, |
|
72 boost::optional<T> & t, |
|
73 const unsigned int version |
|
74 ){ |
|
75 boost::serialization::split_free(ar, t, version); |
|
76 } |
|
77 |
|
78 // the following would be slightly more efficient. But it |
|
79 // would mean that archives created with programs that support |
|
80 // TPS wouldn't be readable by programs that don't support TPS. |
|
81 // Hence we decline to support this otherwise convenient optimization. |
|
82 //#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
83 #if 0 |
|
84 |
|
85 template <class T> |
|
86 struct implementation_level<optional<T> > |
|
87 { |
|
88 typedef mpl::integral_c_tag tag; |
|
89 typedef mpl::int_<boost::serialization::object_serializable> type; |
|
90 BOOST_STATIC_CONSTANT( |
|
91 int , |
|
92 value = boost::serialization::implementation_level::type::value |
|
93 ); |
|
94 }; |
|
95 |
|
96 template<class T> |
|
97 struct tracking_level<optional<T> > |
|
98 { |
|
99 typedef mpl::integral_c_tag tag; |
|
100 typedef mpl::int_<boost::serialization::track_never> type; |
|
101 BOOST_STATIC_CONSTANT( |
|
102 int , |
|
103 value = boost::serialization::tracking_level::type::value |
|
104 ); |
|
105 }; |
|
106 |
|
107 #endif |
|
108 |
|
109 } // serialization |
|
110 } // namespace boost |
|
111 |
|
112 #endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ |