An advanced example for announce implementing serialization for a user-defined tree data type.
#include <cstdint>
#include <iostream>
#include "caf/all.hpp"
#include "caf/to_string.hpp"
using std::cout;
using std::endl;
namespace {
struct tree_node {
std::uint32_t value;
std::vector<tree_node> children;
explicit tree_node(std::uint32_t v = 0) : value(v) {
}
tree_node& add_child(std::uint32_t v = 0) {
children.emplace_back(v);
return *this;
}
tree_node(const tree_node&) = default;
void print() const {
cout << value;
if (children.empty() == false) {
cout << " { ";
auto begin = children.begin();
auto end = children.end();
for (auto i = begin; i != end; ++i) {
if (i != begin) {
cout << ", ";
}
i->print();
}
cout << " } ";
}
}
};
struct tree {
tree_node root;
void print() const {
cout << "tree::print: ";
root.print();
cout << endl;
}
};
bool operator==(const tree_node& lhs, const tree_node& rhs) {
return (lhs.value == rhs.value) && (lhs.children == rhs.children);
}
bool operator==(const tree& lhs, const tree& rhs) {
return lhs.root == rhs.root;
}
public:
}
protected:
void serialize(
const void* ptr,
serializer* sink)
const {
auto tree_ptr = reinterpret_cast<const tree*>(ptr);
serialize_node(tree_ptr->root, sink);
}
auto tree_ptr = reinterpret_cast<tree*>(ptr);
tree_ptr->root.children.clear();
deserialize_node(tree_ptr->root, source);
}
private:
void serialize_node(
const tree_node& node,
serializer* sink)
const {
for (const tree_node& subnode : node.children) {
serialize_node(subnode, sink);
}
}
void deserialize_node(tree_node& node,
deserializer* source)
const {
auto value = source->
read<std::uint32_t>();
node.value = value;
for (size_t i = 0; i < num_children; ++i) {
node.add_child();
deserialize_node(node.children.back(), source);
}
}
};
using tree_vector = std::vector<tree>;
auto set_next_behavior = [=] {
if (remaining > 1) testee(self, remaining - 1);
else self->quit();
};
self->become (
[=](const tree& tmsg) {
cout << "to_string(self->current_message()): "
<< to_string(self->current_message())
<< endl;
tmsg.print();
set_next_behavior();
},
[=](const tree_vector& trees) {
cout << "received " << trees.size() << " trees" << endl;
cout << "to_string: " << to_string(self->current_message()) << endl;
set_next_behavior();
}
);
}
}
int main() {
announce(
typeid(tree), std::unique_ptr<uniform_type_info>{
new tree_type_info});
announce<tree_vector>("tree_vector");
tree t0;
t0.root.add_child(10);
t0.root.children.back().add_child(11).add_child(12).add_child(13);
t0.root.add_child(20);
t0.root.children.back().add_child(21).add_child(22);
{
auto t =
spawn(testee, 2);
self->send(t, t0);
tree_vector tvec;
tvec.push_back(t0);
tvec.push_back(t0);
self->send(t, tvec);
}
return 0;
}