30 #ifndef HPP_UTIL_SERIALIZATION_HH 31 #define HPP_UTIL_SERIALIZATION_HH 33 #include <boost/archive/binary_iarchive.hpp> 34 #include <boost/archive/binary_oarchive.hpp> 35 #include <boost/archive/text_iarchive.hpp> 36 #include <boost/archive/text_oarchive.hpp> 37 #include <boost/archive/xml_iarchive.hpp> 38 #include <boost/archive/xml_oarchive.hpp> 39 #include <boost/preprocessor/comma_if.hpp> 40 #include <boost/preprocessor/facilities/is_empty.hpp> 41 #include <boost/serialization/export.hpp> 42 #include <boost/serialization/nvp.hpp> 43 #include <boost/serialization/shared_ptr.hpp> 44 #include <boost/serialization/utility.hpp> 45 #include <boost/version.hpp> 49 #define _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type, archive, arg) \ 50 template void type load<archive##_iarchive>( \ 51 archive##_iarchive & ar, \ 52 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 53 const unsigned int ver); \ 54 template void type save<archive##_oarchive>( \ 55 archive##_oarchive & ar, \ 56 BOOST_PP_IF(BOOST_PP_IS_EMPTY(arg), , const) \ 57 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 58 const unsigned int ver) \ 59 BOOST_PP_IF(BOOST_PP_IS_EMPTY(arg), const, ) 61 #define _HPP_SERIALIZATION_IMPLEMENT(type, archive, arg) \ 62 template void type serialize<archive##_iarchive>( \ 63 archive##_iarchive & ar, \ 64 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 65 const unsigned int ver); \ 66 template void type serialize<archive##_oarchive>( \ 67 archive##_oarchive & ar, \ 68 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 69 const unsigned int ver) 71 #define HPP_SERIALIZATION_SPLIT_IMPLEMENT(type) \ 72 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::, boost::archive::xml, ); \ 73 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::, boost::archive::text, ); \ 74 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::, boost::archive::binary, ) 76 #define HPP_SERIALIZATION_IMPLEMENT(type) \ 77 _HPP_SERIALIZATION_IMPLEMENT(type::, boost::archive::xml, ); \ 78 _HPP_SERIALIZATION_IMPLEMENT(type::, boost::archive::text, ); \ 79 _HPP_SERIALIZATION_IMPLEMENT(type::, boost::archive::binary, ) 81 #define HPP_SERIALIZATION_FREE_IMPLEMENT(type) \ 83 namespace serialization { \ 84 _HPP_SERIALIZATION_IMPLEMENT(, archive::xml, type& t); \ 85 _HPP_SERIALIZATION_IMPLEMENT(, archive::text, type& t); \ 86 _HPP_SERIALIZATION_IMPLEMENT(, archive::binary, type& t); \ 90 #define HPP_SERIALIZATION_SPLIT_FREE_IMPLEMENT(type) \ 92 namespace serialization { \ 93 template <class Archive> \ 94 void serialize(Archive& ar, type& t, const unsigned int version) { \ 95 split_free(ar, t, version); \ 97 _HPP_SERIALIZATION_IMPLEMENT(, archive::xml, type& t); \ 98 _HPP_SERIALIZATION_IMPLEMENT(, archive::text, type& t); \ 99 _HPP_SERIALIZATION_IMPLEMENT(, archive::binary, type& t); \ 104 namespace serialization {
105 using boost::serialization::guid;
106 using boost::serialization::guid_defined;
107 using boost::serialization::make_nvp;
118 template <
typename T>
124 static_assert(guid_defined<T>::value,
125 "You must use BOOST_CLASS_EXPORT_KEY on this class first.");
128 template <
typename U>
135 std::map<std::string, holder_base*> ptrs_;
138 bool contains(
const std::string& k)
const {
return ptrs_.count(k); }
139 template <
typename T>
141 return (get<T>(k,
false)) != NULL;
145 template <
typename T>
146 void insert(
const std::string& k, T* ptr) {
149 holder_base*
get(
const std::string& k,
bool throwIfNotFound =
false)
const {
150 auto _ptr = ptrs_.find(k);
151 if (_ptr == ptrs_.end()) {
152 if (!throwIfNotFound)
return NULL;
153 throw std::invalid_argument(
"Pointer with name " + k +
" not found.");
157 template <
typename T>
158 T*
get(
const std::string& k,
bool throwIfNotFound =
false)
const {
160 if (hb == NULL)
return NULL;
162 if ((h =
dynamic_cast<holder<T>*
>(hb)) == NULL) {
163 if (!throwIfNotFound)
return NULL;
164 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " +
165 hb->
classid +
" but not of requested type " +
171 template <
typename Base,
typename Child>
173 static_assert(guid_defined<Child>::value,
174 "You must use BOOST_CLASS_EXPORT_KEY on this class first.");
177 template <
typename Base,
typename Child>
179 bool throwIfNotFound =
false)
const {
181 if (hb == NULL)
return NULL;
184 if (!throwIfNotFound)
return NULL;
185 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " +
186 hb->
classid +
" but not of requested type " +
187 guid<Child>() +
".");
191 if (!throwIfNotFound)
return NULL;
192 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " +
193 hb->
classid +
" but not of requested type " +
194 guid<Child>() +
".");
200 for (
auto it : ptrs_)
delete it.second;
204 template <
typename Archive,
205 std::enable_if_t<Archive::is_saving::value, int> = 42>
208 auto size(ptrs_.size());
209 ar << make_nvp(
"nrequires", size);
210 typedef std::pair<std::string, std::string> string_pair;
211 for (
auto it : ptrs_) {
212 string_pair requires(it.first, it.second->classid);
213 ar << make_nvp(
"requires", requires);
216 template <
typename Archive,
217 std::enable_if_t<!Archive::is_saving::value, int> = 42>
220 decltype(ptrs_.size()) size;
221 ar >> make_nvp(
"nrequires", size);
222 typedef std::pair<std::string, std::string> string_pair;
224 for (decltype(size) i = 0; i < size; ++i) {
225 ar >> make_nvp(
"requires", pair);
227 if (pair.second != hb->
classid)
228 throw std::invalid_argument(
229 "Required pointer with name " + pair.first +
" found of type " +
230 hb->
classid +
" but not of required type " + pair.second +
".");
235 template <
typename archive_base,
typename... parent_classes>
238 public parent_classes... {
240 inline void initialize() { initialize_tpl<archive_base>(*this); }
242 using archive_base::archive_base;
245 template <
typename Archive>
249 template <
typename Archive>
265 #endif // HPP_UTIL_SERIALIZATION_HH bool contains(const std::string &k) const
Definition: serialization.hh:138
holder(T *t, const char *classid)
Definition: serialization.hh:122
Definition: serialization.hh:109
archive_tpl< boost::archive::binary_iarchive > binary_iarchive
Definition: serialization.hh:254
Definition: serialization.hh:119
Definition: assertion.hh:45
virtual ~archive_ptr_holder()
Definition: serialization.hh:199
void insertChildClass(const std::string &k, Child *ptr)
Definition: serialization.hh:172
archive_tpl< boost::archive::xml_oarchive > xml_oarchive
Definition: serialization.hh:258
void insert(const std::string &k, holder_base *ptr)
Definition: serialization.hh:144
Definition: serialization.hh:236
Child * getChildClass(const std::string &k, bool throwIfNotFound=false) const
Definition: serialization.hh:178
holder(T *t)
Definition: serialization.hh:123
T * t
Definition: serialization.hh:121
archive_tpl< boost::archive::xml_iarchive > xml_iarchive
Definition: serialization.hh:257
archive_tpl< boost::archive::binary_oarchive > binary_oarchive
Definition: serialization.hh:255
archive_ptr_holder & cast(Archive &ar)
Definition: serialization.hh:246
void insert(const std::string &k, T *ptr)
Definition: serialization.hh:146
const char * classid
Definition: serialization.hh:111
virtual ~holder_base()=default
holder_base(const char *classid)
Definition: serialization.hh:115
void initialize()
Definition: serialization.hh:240
bool containsOfType(const std::string &k) const
Definition: serialization.hh:140
archive_tpl< boost::archive::text_oarchive > text_oarchive
Definition: serialization.hh:261
archive_tpl< boost::archive::text_iarchive > text_iarchive
Definition: serialization.hh:260
void initialize_tpl(Archive &ar)
Definition: serialization.hh:206
Definition: serialization.hh:134