Skip to content

Instantly share code, notes, and snippets.

@motonacciu
Last active December 17, 2015 09:48
Show Gist options
  • Select an option

  • Save motonacciu/5589534 to your computer and use it in GitHub Desktop.

Select an option

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
#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