From 6d0a8cec55069fc1561caab38cd540bd6403f1a5 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 13 Jun 2022 01:01:13 +0300 Subject: [PATCH] Add macro helper for generating structs --- libs/util/include/psemek/util/struct.hpp | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 libs/util/include/psemek/util/struct.hpp diff --git a/libs/util/include/psemek/util/struct.hpp b/libs/util/include/psemek/util/struct.hpp new file mode 100644 index 00000000..e2de7c62 --- /dev/null +++ b/libs/util/include/psemek/util/struct.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include + +#define psemek_declare_struct_detail_field(r, data, value) BOOST_PP_TUPLE_ELEM(0, value) BOOST_PP_TUPLE_ELEM(1, value); + +#define psemek_declare_struct_detail_for_each(r, data, value) f(x.BOOST_PP_TUPLE_ELEM(1, value) ); + +#define psemek_declare_struct_detail_print(r, data, index, value) \ + if (index > 0) s << ", "; \ + s << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, value)) << " = " << x.BOOST_PP_TUPLE_ELEM(1, value); + +#define psemek_declare_struct_impl(name, values) \ + struct name { \ + BOOST_PP_SEQ_FOR_EACH(psemek_declare_struct_detail_field, _, values) \ + }; \ + template \ + void for_each(name & x, F && f) { \ + BOOST_PP_SEQ_FOR_EACH(psemek_declare_struct_detail_for_each, _, values) \ + } \ + template \ + void for_each(name const & x, F && f) { \ + BOOST_PP_SEQ_FOR_EACH(psemek_declare_struct_detail_for_each, _, values) \ + } \ + template \ + Stream & operator << (Stream & s, name const & x) { \ + s << '{'; \ + BOOST_PP_SEQ_FOR_EACH_I(psemek_declare_struct_detail_print, _, values) \ + s << '}'; \ + return s; \ + } \ + template \ + void write(Stream & s, name const & x) { \ + for_each(x, [&](auto const & v){ write(s, v); }); \ + } \ + template \ + void read(Stream & s, name & x) { \ + for_each(x, [&](auto & v){ read(s, v); }); \ + } + +#define psemek_declare_struct(name, values) psemek_declare_struct_impl(name, BOOST_PP_VARIADIC_SEQ_TO_SEQ(values))