Any++
Loading...
Searching...
No Matches
21_Tree_any_borrow_as.cpp

factory, serialization and crosscast example

// https://github.com/jll63/yomm2/blob/master/examples/accept_no_visitors.cpp
#include <catch2/catch_test_macros.hpp>
#include <iostream>
#include <print>
#include <string>
using std::string;
using namespace anyxx;
namespace _21_Tree_any_borrow_as {
ANY(node, (ANY_FN(int, value, (), const)), )
ANY(serializeable, (ANY_FN(void, serialize, (std::ostream&), const)), )
template <is_proxy Proxy>
std::ostream& operator<<(std::ostream& s,
any_serializeable<Proxy> const& any) {
any.serialize(s);
return s;
}
ANY_SINGLETON_DECLARE(, deserialize_factory,
any_serializeable<unique> deserialize(std::istream& archive) {
std::string type;
archive >> type;
return deserialize_factory.construct<anyxx::unique>(type, archive);
}
any_node<unique> deserialize_any_node(std::istream& archive) {
return move_to<any_node<unique>>(deserialize(archive));
}
template <typename T>
auto register_deserialize_binary(std::string const& key) {
return deserialize_factory.register_(key, [](std::istream& archive) {
return T{deserialize_any_node(archive), deserialize_any_node(archive)};
});
}
void serialize_binary(auto const& self, std::string_view key,
std::ostream& archive) {
archive << key << " "
<< *borrow_as<any_serializeable<cref>>(self.left)
<< *borrow_as<any_serializeable<cref>>(self.right);
}
struct Plus {
[[nodiscard]] int value() const { return left.value() + right.value(); }
void serialize(std::ostream& archive) const {
serialize_binary(*this, "Plus ", archive);
}
any_node<unique> left, right;
};
auto __ = register_deserialize_binary<Plus>("Plus");
struct Times {
[[nodiscard]] int value() const { return left.value() * right.value(); }
void serialize(std::ostream& archive) const {
serialize_binary(*this, "Times ", archive);
}
any_node<unique> left, right;
};
auto __ = register_deserialize_binary<Times>("Times");
struct Integer {
[[nodiscard]] int value() const { return int_; }
void serialize(std::ostream& archive) const {
archive << "Integer " << int_ << " ";
}
int int_ = 0;
};
auto __ = deserialize_factory.register_("Integer", [](std::istream& archive) {
Integer integer;
archive >> integer.int_;
return integer;
});
} // namespace _21_Tree_any_borrow_as
using namespace _21_Tree_any_borrow_as;
ANY_SINGLETON(_21_Tree_any_borrow_as, deserialize_factory)
ANY_REGISTER_MODEL(Plus, node);
ANY_REGISTER_MODEL(Plus, serializeable);
ANY_REGISTER_MODEL(Times, node);
ANY_REGISTER_MODEL(Times, serializeable);
ANY_REGISTER_MODEL(Integer, node);
ANY_REGISTER_MODEL(Integer, serializeable);
TEST_CASE("_21_Tree_any_borrow_as") {
using namespace anyxx;
using namespace _21_Tree_any_borrow_as;
std::stringstream archive{
"Plus Integer 1 Plus Times Integer 2 Integer 3 Integer 4 "};
auto expr = move_to<any_node<unique>>(deserialize(archive));
CHECK(expr.value() == 11);
std::stringstream serialized;
borrow_as<any_serializeable<cref>>(expr)->serialize(serialized);
std::println("{}", serialized.str());
auto expr2 = move_to<any_node<unique>>(deserialize(serialized));
CHECK(expr2.value() == 11);
}
C++ header only library for external polymorphism.
The core class template to control dispatch for external polymorphism.
Definition anyxx.hpp:2806
A class template to implement a factory for any objects.
Definition anyxx.hpp:3610
#define ANY_FN(ret, name, params, const_)
TRAIT function whose default behavior is to call an equally named member function of the model.
Definition anyxx.hpp:1019
#define ANY_REGISTER_MODEL(class_, interface_,...)
Register a model class for a specific any interface. Must be in global namespace.
Definition anyxx.hpp:4323
#define ANY_SINGLETON_DECLARE(export_, name,...)
Declare access to a singleton object in a header file.
Definition anyxx.hpp:4224
#define ANY_SINGLETON(namespace_, name,...)
Define a singleton object in a source file.
Definition anyxx.hpp:4235
#define ANY(n, l,...)
Simple ANY macro.
Definition anyxx.hpp:884
A key type for factory registration.
Definition anyxx.hpp:3597
Definition anyxx.hpp:1947