19 #ifndef HPP_UTIL_SERIALIZATION_HH 20 #define HPP_UTIL_SERIALIZATION_HH 22 #include <boost/version.hpp> 23 #include <boost/archive/binary_oarchive.hpp> 24 #include <boost/archive/text_oarchive.hpp> 25 #include <boost/archive/xml_oarchive.hpp> 26 #include <boost/archive/binary_iarchive.hpp> 27 #include <boost/archive/text_iarchive.hpp> 28 #include <boost/archive/xml_iarchive.hpp> 30 #include <boost/preprocessor/comma_if.hpp> 31 #include <boost/preprocessor/facilities/is_empty.hpp> 32 #include <boost/serialization/export.hpp> 33 #include <boost/serialization/shared_ptr.hpp> 34 #include <boost/serialization/nvp.hpp> 35 #include <boost/serialization/utility.hpp> 40 #define _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type,archive,arg) \ 41 template void type load<archive##_iarchive>(archive##_iarchive& ar, \ 42 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 43 const unsigned int ver); \ 44 template void type save<archive##_oarchive>(archive##_oarchive& ar, \ 45 BOOST_PP_IF(BOOST_PP_IS_EMPTY(arg),,const) arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 46 const unsigned int ver) BOOST_PP_IF(BOOST_PP_IS_EMPTY(arg),const,) 48 #define _HPP_SERIALIZATION_IMPLEMENT(type,archive,arg) \ 49 template void type serialize<archive##_iarchive>(archive##_iarchive& ar, \ 50 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 51 const unsigned int ver); \ 52 template void type serialize<archive##_oarchive>(archive##_oarchive& ar, \ 53 arg BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(arg))) \ 54 const unsigned int ver) 56 #define HPP_SERIALIZATION_SPLIT_IMPLEMENT(type) \ 57 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::,boost::archive::xml,); \ 58 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::,boost::archive::text,); \ 59 _HPP_SERIALIZATION_SPLIT_IMPLEMENT(type::,boost::archive::binary,) 61 #define HPP_SERIALIZATION_IMPLEMENT(type) \ 62 _HPP_SERIALIZATION_IMPLEMENT(type::,boost::archive::xml,); \ 63 _HPP_SERIALIZATION_IMPLEMENT(type::,boost::archive::text,); \ 64 _HPP_SERIALIZATION_IMPLEMENT(type::,boost::archive::binary,) 66 #define HPP_SERIALIZATION_FREE_IMPLEMENT(type) \ 67 namespace boost { namespace serialization { \ 68 _HPP_SERIALIZATION_IMPLEMENT(,archive::xml,type& t); \ 69 _HPP_SERIALIZATION_IMPLEMENT(,archive::text,type& t); \ 70 _HPP_SERIALIZATION_IMPLEMENT(,archive::binary,type& t); \ 73 #define HPP_SERIALIZATION_SPLIT_FREE_IMPLEMENT(type) \ 74 namespace boost { namespace serialization { \ 75 template<class Archive> \ 76 void serialize(Archive & ar, type& t, const unsigned int version) { \ 77 split_free(ar, t, version); \ 79 _HPP_SERIALIZATION_IMPLEMENT(,archive::xml,type& t); \ 80 _HPP_SERIALIZATION_IMPLEMENT(,archive::text,type& t); \ 81 _HPP_SERIALIZATION_IMPLEMENT(,archive::binary,type& t); \ 85 namespace serialization {
86 using boost::serialization::make_nvp;
87 using boost::serialization::guid;
88 using boost::serialization::guid_defined;
104 { static_assert(guid_defined<T>::value,
"You must use BOOST_CLASS_EXPORT_KEY on this class first."); }
111 std::map<std::string, holder_base*> ptrs_;
114 bool contains(
const std::string& k)
const {
return ptrs_.count(k); }
116 bool containsOfType(
const std::string& k)
const {
return (get<T>(k,
false)) != NULL; }
121 holder_base*
get(
const std::string& k,
bool throwIfNotFound =
false)
const {
122 auto _ptr = ptrs_.find(k);
123 if (_ptr == ptrs_.end()) {
124 if (!throwIfNotFound)
return NULL;
125 throw std::invalid_argument(
"Pointer with name " + k +
" not found.");
127 else return _ptr->second;
130 T*
get(
const std::string& k,
bool throwIfNotFound =
false)
const {
132 if (hb == NULL)
return NULL;
134 if ((h =
dynamic_cast<holder<T>*
>(hb)) == NULL) {
135 if (!throwIfNotFound)
return NULL;
136 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " 137 + hb->
classid +
" but not of requested type " + guid<T>() +
".");
142 template<
typename Base,
typename Child>
144 static_assert(guid_defined<Child>::value,
"You must use BOOST_CLASS_EXPORT_KEY on this class first.");
147 template<
typename Base,
typename Child>
148 Child*
getChildClass(
const std::string& k,
bool throwIfNotFound =
false)
const {
150 if (hb == NULL)
return NULL;
153 if (!throwIfNotFound)
return NULL;
154 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " 155 + hb->
classid +
" but not of requested type " + guid<Child>() +
".");
159 if (!throwIfNotFound)
return NULL;
160 throw std::invalid_argument(
"Pointer with name " + k +
" found of type " 161 + hb->
classid +
" but not of requested type " + guid<Child>() +
".");
167 for (
auto it : ptrs_)
delete it.second;
171 template<
typename Archive, std::enable_if_t<Archive::is_saving::value,
int> = 42>
174 auto size (ptrs_.size());
175 ar << make_nvp(
"nrequires", size);
176 typedef std::pair<std::string,std::string> string_pair;
177 for (
auto it : ptrs_) {
178 string_pair requires(it.first, it.second->classid);
179 ar << make_nvp(
"requires", requires);
182 template<
typename Archive, std::enable_if_t<!Archive::is_saving::value,
int> = 42>
185 decltype(ptrs_.size()) size;
186 ar >> make_nvp(
"nrequires", size);
187 typedef std::pair<std::string,std::string> string_pair;
189 for (decltype(size) i = 0; i < size; ++i) {
190 ar >> make_nvp(
"requires", pair);
192 if (pair.second != hb->
classid)
193 throw std::invalid_argument(
"Required pointer with name " + pair.first +
" found of type " 194 + hb->
classid +
" but not of required type " + pair.second +
".");
199 template<
typename archive_base,
typename... parent_classes>
205 initialize_tpl<archive_base>(*this);
208 using archive_base::archive_base;
211 template<
typename Archive>
213 template<
typename Archive>
227 #endif // HPP_UTIL_SERIALIZATION_HH bool contains(const std::string &k) const
Definition: serialization.hh:114
holder(T *t, const char *classid)
Definition: serialization.hh:102
Definition: serialization.hh:90
archive_tpl< boost::archive::binary_iarchive > binary_iarchive
Definition: serialization.hh:216
Definition: serialization.hh:99
Definition: assertion.hh:22
virtual ~archive_ptr_holder()
Definition: serialization.hh:166
void insertChildClass(const std::string &k, Child *ptr)
Definition: serialization.hh:143
archive_tpl< boost::archive::xml_oarchive > xml_oarchive
Definition: serialization.hh:220
void insert(const std::string &k, holder_base *ptr)
Definition: serialization.hh:118
Definition: serialization.hh:200
Child * getChildClass(const std::string &k, bool throwIfNotFound=false) const
Definition: serialization.hh:148
holder(T *t)
Definition: serialization.hh:103
T * t
Definition: serialization.hh:101
archive_tpl< boost::archive::xml_iarchive > xml_iarchive
Definition: serialization.hh:219
archive_tpl< boost::archive::binary_oarchive > binary_oarchive
Definition: serialization.hh:217
archive_ptr_holder & cast(Archive &ar)
Definition: serialization.hh:212
void insert(const std::string &k, T *ptr)
Definition: serialization.hh:120
const char * classid
Definition: serialization.hh:92
virtual ~holder_base()=default
holder_base(const char *classid)
Definition: serialization.hh:96
void initialize()
Definition: serialization.hh:203
bool containsOfType(const std::string &k) const
Definition: serialization.hh:116
archive_tpl< boost::archive::text_oarchive > text_oarchive
Definition: serialization.hh:223
archive_tpl< boost::archive::text_iarchive > text_iarchive
Definition: serialization.hh:222
void initialize_tpl(Archive &ar)
Definition: serialization.hh:172
Definition: serialization.hh:109