--- /dev/null
+#ifndef FOR_EACH_IN_TUPLE_H
+#define FOR_EACH_IN_TUPLE_H
+
+
+#include <tuple>
+
+
+namespace detail
+{
+ template<int... Is>
+ struct seq { };
+
+ template<int N, int... Is>
+ struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
+
+ template<int... Is>
+ struct gen_seq<0, Is...> : seq<Is...> { };
+
+ template<typename T, typename F, int... Is>
+ void for_each(T&& t, F &f, seq<Is...>)
+ {
+ auto l = { (f(std::get<Is>(t)), 0)... };
+ (void)l;
+ }
+}
+
+template<typename... Ts, typename F>
+void for_each_in_tuple(std::tuple<Ts...> &t, F &f)
+{
+ detail::for_each(t, f, detail::gen_seq<sizeof...(Ts)>());
+}
+
+template<typename... Ts, typename F>
+void for_each_in_tuple(const std::tuple<Ts...> &t, F &f)
+{
+ detail::for_each(t, f, detail::gen_seq<sizeof...(Ts)>());
+}
+
+
+#endif // FOR_EACH_IN_TUPLE_H
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef SERIALIZATION_H
+#define SERIALIZATION_H
+
+
+#include <tuple>
+#include "for_each_in_tuple.h"
+
+
+namespace Serialization {
+namespace priv {
+
+struct FunctorSerialize
+{
+ FunctorSerialize(std::string &data) :
+ data_(data)
+ {
+ data_.resize(0);
+ }
+
+ template<typename T>
+ void operator () (const T& t)
+ {
+ static_assert(std::is_pod<T>::value, "Type is not support");
+
+ const char* ptr = reinterpret_cast<const char *>(&t);
+ std::copy(ptr, ptr + sizeof(T), std::back_inserter(data_));
+ }
+
+ void operator () (const std::string &str)
+ {
+ // pack size
+ size_t size = str.size();
+ operator () (size);
+
+ // pack data
+ std::copy(str.begin(), str.end(), std::back_inserter(data_));
+ }
+
+private:
+ std::string &data_;
+};
+
+
+struct FunctorDeserialize
+{
+ FunctorDeserialize(const std::string &data) :
+ data_(data) {}
+
+ template<typename T>
+ void operator () (T& t)
+ {
+ static_assert(std::is_pod<T>::value, "Type is not support");
+
+ if (data_.size() - pos_ < sizeof(T))
+ throw std::runtime_error("Cannot deserialize");
+
+ char* ptr = reinterpret_cast<char *>(&t);
+ std::copy(&data_[pos_], &data_[pos_ + sizeof(T)], ptr);
+ pos_ += sizeof(T);
+ }
+
+ void operator () (std::string &str)
+ {
+ // unpack size
+ size_t size;
+ operator () (size);
+
+ // unpack data
+ if (data_.size() - pos_ < size)
+ throw std::runtime_error("Cannot deserialize string");
+
+ str.resize(size);
+ std::copy(&data_[pos_], &data_[pos_ + size], &str[0]);
+ pos_ += size;
+ }
+
+ bool is_end()
+ {
+ return data_.size() == pos_;
+ }
+
+private:
+ size_t pos_ = 0;
+ const std::string &data_;
+};
+
+} // namespace priv
+
+
+
+/*
+ * Note:
+ * We use std::string like binary array
+ */
+
+template<typename... Ts>
+void tuple_to_string(const std::tuple<Ts...> &tup, std::string &out)
+{
+ priv::FunctorSerialize f_serialize(out);
+ for_each_in_tuple(tup, f_serialize);
+}
+
+template<typename... Ts>
+void tuple_from_string(std::tuple<Ts...> &tup, const std::string &in)
+{
+ priv::FunctorDeserialize f_deserialize(in);
+ for_each_in_tuple(tup, f_deserialize);
+
+ if (!f_deserialize.is_end())
+ throw std::runtime_error("Not expected data exist");
+}
+
+} // namespace Serialization
+
+
+#endif // SERIALIZATION_H