1 /* Copyright 2017-2021 PaGMO development team
2 
3 This file is part of the PaGMO library.
4 
5 The PaGMO library is free software; you can redistribute it and/or modify
6 it under the terms of either:
7 
8   * the GNU Lesser General Public License as published by the Free
9     Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11 
12 or
13 
14   * the GNU General Public License as published by the Free Software
15     Foundation; either version 3 of the License, or (at your option) any
16     later version.
17 
18 or both in parallel, as here.
19 
20 The PaGMO library is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 for more details.
24 
25 You should have received copies of the GNU General Public License and the
26 GNU Lesser General Public License along with the PaGMO library.  If not,
27 see https://www.gnu.org/licenses/. */
28 
29 #ifndef PAGMO_S11N_HPP
30 #define PAGMO_S11N_HPP
31 
32 #include <cstddef>
33 #include <locale>
34 #include <random>
35 #include <sstream>
36 #include <string>
37 #include <tuple>
38 
39 #include <boost/serialization/access.hpp>
40 #include <boost/serialization/base_object.hpp>
41 #include <boost/serialization/export.hpp>
42 #include <boost/serialization/serialization.hpp>
43 #include <boost/serialization/split_free.hpp>
44 #include <boost/serialization/split_member.hpp>
45 #include <boost/serialization/string.hpp>
46 #include <boost/serialization/tracking.hpp>
47 #include <boost/serialization/unique_ptr.hpp>
48 #include <boost/serialization/utility.hpp>
49 #include <boost/serialization/vector.hpp>
50 #include <boost/serialization/version.hpp>
51 
52 // Include the archives.
53 #include <boost/archive/binary_iarchive.hpp>
54 #include <boost/archive/binary_oarchive.hpp>
55 #include <boost/archive/text_iarchive.hpp>
56 #include <boost/archive/text_oarchive.hpp>
57 
58 #include <pagmo/detail/s11n_wrappers.hpp>
59 
60 namespace pagmo
61 {
62 
63 namespace detail
64 {
65 
66 // Implementation of tuple serialization.
67 template <std::size_t N>
68 struct tuple_s11n {
69     template <class Archive, typename... Args>
serializepagmo::detail::tuple_s11n70     static void serialize(Archive &ar, std::tuple<Args...> &t, unsigned version)
71     {
72         ar &std::get<N - 1u>(t);
73         tuple_s11n<N - 1u>::serialize(ar, t, version);
74     }
75 };
76 
77 template <>
78 struct tuple_s11n<0> {
79     template <class Archive, typename... Args>
serializepagmo::detail::tuple_s11n80     static void serialize(Archive &, std::tuple<Args...> &, unsigned)
81     {
82     }
83 };
84 
85 } // namespace detail
86 
87 } // namespace pagmo
88 
89 namespace boost
90 {
91 
92 namespace serialization
93 {
94 
95 // Implement serialization for std::tuple.
96 template <class Archive, typename... Args>
serialize(Archive & ar,std::tuple<Args...> & t,unsigned version)97 inline void serialize(Archive &ar, std::tuple<Args...> &t, unsigned version)
98 {
99     pagmo::detail::tuple_s11n<sizeof...(Args)>::serialize(ar, t, version);
100 }
101 
102 // Implement serialization for the Mersenne twister engine.
103 template <class Archive, class UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a,
104           std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
save(Archive & ar,std::mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f> const & e,unsigned)105 inline void save(Archive &ar, std::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f> const &e,
106                  unsigned)
107 {
108     std::ostringstream oss;
109     // Use the "C" locale.
110     oss.imbue(std::locale::classic());
111     oss << e;
112     ar << oss.str();
113 }
114 
115 template <class Archive, class UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a,
116           std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
load(Archive & ar,std::mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f> & e,unsigned)117 inline void load(Archive &ar, std::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f> &e,
118                  unsigned)
119 {
120     std::istringstream iss;
121     // Use the "C" locale.
122     iss.imbue(std::locale::classic());
123     std::string tmp;
124     ar >> tmp;
125     iss.str(tmp);
126     iss >> e;
127 }
128 
129 template <class Archive, class UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a,
130           std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
serialize(Archive & ar,std::mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f> & e,unsigned version)131 inline void serialize(Archive &ar, std::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f> &e,
132                       unsigned version)
133 {
134     split_free(ar, e, version);
135 }
136 
137 } // namespace serialization
138 
139 } // namespace boost
140 
141 #endif
142