Last active
December 17, 2015 09:48
-
-
Save motonacciu/5589534 to your computer and use it in GitHub Desktop.
get_size predicate returns the size in bytes of the object being serialized
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <tuple> | |
| #include <numeric> | |
| #include <vector> | |
| #include <string> | |
| namespace detail { | |
| template <class T> | |
| struct get_size_helper; | |
| /** | |
| * Specialzation for generic std::vector<T>, a vector is represented | |
| * in the stream by storing the number of elements (v.size()) followed | |
| * by the serialized elements (notice that we can have nested structures | |
| */ | |
| template <class T> | |
| struct get_size_helper<std::vector<T>> { | |
| static size_t value(const std::vector<T>& obj) { | |
| return std::accumulate(obj.begin(), obj.end(), sizeof(size_t), | |
| [](const size_t& acc, const T& cur) { return acc+get_size(cur); }); | |
| } | |
| }; | |
| /** | |
| * Specialization for an std::string. Similarly to the vector, we store | |
| * the number of elements of the string (str.length()), followed by the | |
| * chars. In this case we are sure the elements of the string are bytes | |
| * therefore we can compute the size without recurring | |
| */ | |
| template <> | |
| struct get_size_helper<std::string> { | |
| static size_t value(const std::string& obj) { | |
| return sizeof(size_t) + obj.length()*sizeof(uint8_t); | |
| } | |
| }; | |
| template <class tuple_type> | |
| inline size_t get_tuple_size(const tuple_type& obj, int_<0>) { | |
| constexpr size_t idx = std::tuple_size<tuple_type>::value-1; | |
| return get_size(std::get<idx>(obj)); | |
| } | |
| template <class tuple_type, size_t pos> | |
| inline size_t get_tuple_size(const tuple_type& obj, int_<pos>) { | |
| constexpr size_t idx = std::tuple_size<tuple_type>::value-pos-1; | |
| size_t acc = get_size(std::get<idx>(obj)); | |
| return acc+get_tuple_size(obj, int_<pos-1>()); | |
| } | |
| /** | |
| * specialization for std::tuple<T...>. In this case we don't need to | |
| * store the number of elements since this information is explicit | |
| * with the type itself. Therefore we simply serialize the elements | |
| * of the tuple | |
| */ | |
| template <class ...T> | |
| struct get_size_helper<std::tuple<T...>> { | |
| static size_t value(const std::tuple<T...>& obj) { | |
| return get_tuple_size(obj, int_<sizeof...(T)-1>()); | |
| } | |
| }; | |
| /** | |
| * Specialization for any remaining type, simply use the value of | |
| * sizeof() | |
| */ | |
| template <class T> | |
| struct get_size_helper { | |
| static size_t value(const T& obj) { return sizeof(T); } | |
| }; | |
| } // end detail namespace | |
| template <class T> | |
| inline size_t get_size(const T& obj) { | |
| return detail::get_size_helper<T>::value(obj); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment