Program Example Traversal
The full code for this magistrate example can be found here: examples/checkpoint_example_traversal.cc
Example source code:
#include <checkpoint/checkpoint.h> #include <cstdio> #include <string> namespace checkpoint { namespace intrusive { namespace examples { struct TestObject { TestObject() = default; struct MakeTag { }; explicit TestObject(MakeTag) { for (int i = 0; i < 10; i++) { vec1.push_back(i); vec2.push_back(i * 29.34); vec3.push_back("hello: " + std::to_string(vec2.back())); } } template <typename Serializer> void serialize(Serializer& s) { s | a | b | vec1 | vec2 | vec3; } private: int a = 29; int b = 36; std::vector<int> vec1; std::vector<double> vec2; std::vector<std::string> vec3; }; }}} // end namespace checkpoint::intrusive::examples struct PrintBytesTraverse : magistrate::BaseSerializer { PrintBytesTraverse() : magistrate::BaseSerializer(magistrate::eSerializationMode::None) { } void contiguousBytes(void*, std::size_t size, std::size_t num_elms) { printf("PrintBytesTraverse: size=%zu, num_elms=%zu\n", size, num_elms); } }; template <typename U> struct ToString { static std::string apply(U& u) { return std::to_string(u); } }; template <> struct ToString<std::string> { static std::string apply(std::string& u) { return u; } }; template <typename SerializerT, typename T> struct CustomDispatch { static void serializeIntrusive(SerializerT& s, T& t) { t.serialize(s); } static void serializeNonIntrusive(SerializerT& s, T& t) { serialize(s, t); } }; // std::vector specialization for dispatcher, vector is always non-intrusive so // skip that overload template <typename SerializerT, typename U> struct CustomDispatch<SerializerT, std::vector<U>> { static void serializeNonIntrusive(SerializerT&, std::vector<U>& t) { // Do something special here: e.g., an RDMA for the vector during packing printf("Traversing vector: size=%zu\n", t.size()); for (std::size_t i = 0; i < t.size(); i++) { printf("\t vector[%zu]=%s", i, ToString<U>::apply(t[i]).c_str()); } printf("\n"); } }; struct TypedTraverse : magistrate::BaseSerializer { template <typename U, typename V> using DispatcherType = CustomDispatch<U, V>; TypedTraverse() : magistrate::BaseSerializer(magistrate::eSerializationMode::None) { } template <typename SerializerT, typename T> void contiguousTyped(SerializerT&, T*, std::size_t num_elms) { printf("TypedTraverse: type is %s, num=%zu\n", typeid(T).name(), num_elms); } }; int main(int, char**) { using namespace magistrate::intrusive::examples; TestObject my_obj(TestObject::MakeTag{}); // Traverse my_obj with a custom traverser that prints the bytes magistrate::dispatch::Traverse::with<TestObject, PrintBytesTraverse>(my_obj); // Traverse my_obj with a custom traverser and dispatcher that prints the // types and lens magistrate::dispatch::Traverse::with<TestObject, TypedTraverse>(my_obj); return 0; }