#pragma once #include "../base/base.hpp" #include "../std/map.hpp" #include "../std/set.hpp" #include "../std/unordered_map.hpp" #include "../std/vector.hpp" #include "../std/array.hpp" #include "../std/utility.hpp" /// @name std containers serialization /// TArchive should be an archive class in global namespace. //@{ template TArchive & operator << (TArchive & ar, pair const & t) { ar << t.first << t.second; return ar; } template TArchive & operator >> (TArchive & ar, pair & t) { ar >> t.first >> t.second; return ar; } template void save_like_map(TArchive & ar, TCont const & rMap) { uint32_t const count = static_cast(rMap.size()); ar << count; for (typename TCont::const_iterator i = rMap.begin(); i != rMap.end(); ++i) ar << i->first << i->second; } template void load_like_map(TArchive & ar, TCont & rMap) { rMap.clear(); uint32_t count; ar >> count; while (count > 0) { typename TCont::key_type t1; typename TCont::mapped_type t2; ar >> t1 >> t2; rMap.insert(make_pair(t1, t2)); --count; } } template void save_like_vector(TArchive & ar, TCont const & rCont) { uint32_t const count = static_cast(rCont.size()); ar << count; for (uint32_t i = 0; i < count; ++i) ar << rCont[i]; } template void load_like_vector(TArchive & ar, TCont & rCont) { rCont.clear(); uint32_t count; ar >> count; rCont.resize(count); for (uint32_t i = 0; i < count; ++i) ar >> rCont[i]; } template void save_like_set(TArchive & ar, TCont const & rSet) { uint32_t const count = static_cast(rSet.size()); ar << count; for (typename TCont::const_iterator it = rSet.begin(); it != rSet.end(); ++it) ar << *it; } template void load_like_set(TArchive & ar, TCont & rSet) { rSet.clear(); uint32_t count; ar >> count; for (uint32_t i = 0; i < count; ++i) { typename TCont::value_type val; ar >> val; rSet.insert(val); } } template TArchive & operator << (TArchive & ar, map const & rMap) { save_like_map(ar, rMap); return ar; } template TArchive & operator >> (TArchive & ar, map & rMap) { load_like_map(ar, rMap); return ar; } template TArchive & operator << (TArchive & ar, multimap const & rMap) { save_like_map(ar, rMap); return ar; } template TArchive & operator >> (TArchive & ar, multimap & rMap) { load_like_map(ar, rMap); return ar; } template TArchive & operator << (TArchive & ar, unordered_map const & rMap) { save_like_map(ar, rMap); return ar; } template TArchive & operator >> (TArchive & ar, unordered_map & rMap) { load_like_map(ar, rMap); return ar; } template TArchive & operator << (TArchive & ar, vector const & rVector) { save_like_vector(ar, rVector); return ar; } template TArchive & operator >> (TArchive & ar, vector & rVector) { load_like_vector(ar, rVector); return ar; } template TArchive & operator << (TArchive & ar, set const & rSet) { save_like_set(ar, rSet); return ar; } template TArchive & operator >> (TArchive & ar, set & rSet) { load_like_set(ar, rSet); return ar; } template TArchive & operator << (TArchive & ar, array const & rArray) { for (size_t i = 0; i < N; ++i) ar << rArray[i]; return ar; } template TArchive & operator >> (TArchive & ar, array & rArray) { for (size_t i = 0; i < N; ++i) ar >> rArray[i]; return ar; } //@} namespace serial { /// @name This functions invokes overriten do_load for type T with index in array. //@{ template void do_load(TArchive & ar, size_t ind, vector & rVector) { uint32_t count; ar >> count; rVector.resize(count); for (uint32_t i = 0; i < count; ++i) do_load(ar, ind, rVector[i]); } template void do_load(TArchive & ar, array & rArray) { for (size_t i = 0; i < N; ++i) do_load(ar, i, rArray[i]); } //@} namespace detail { template class save_element { TArchive & m_ar; public: save_element(TArchive & ar) : m_ar(ar) {} template void operator() (T const & t, int) { m_ar << t; } }; template class load_element { TArchive & m_ar; public: load_element(TArchive & ar) : m_ar(ar) {} template void operator() (T & t, int) { m_ar >> t; } }; } template void save_tuple(TArchive & ar, TTuple const & t) { detail::save_element doSave(ar); for_each_tuple(t, doSave); } template void load_tuple(TArchive & ar, TTuple & t) { detail::load_element doLoad(ar); for_each_tuple(t, doLoad); } }