From c64c76e273084cfd5b8628fb268e803957fc3025 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Sat, 23 Mar 2024 17:48:09 +0100 Subject: codec, io_codec: forst and rpc work --- modules/codec/c++/forst.hpp | 68 ++++++++++++++++++++++++-- modules/codec/c++/forst.tmpl.hpp | 70 ++++++++++++++++++++++++++- modules/codec/c++/rpc.hpp | 94 ++++++++++++++++++++++++++++++------ modules/codec/c++/schema.hpp | 85 ++++++++++++++++++++++++++++++++ modules/codec/c++/schema_factory.hpp | 29 ++++++++++- modules/codec/tests/forst.cpp | 29 +++++++++++ modules/codec/tests/schema.cpp | 69 ++++++++++++++++++++++++++ 7 files changed, 423 insertions(+), 21 deletions(-) create mode 100644 modules/codec/tests/forst.cpp (limited to 'modules/codec') diff --git a/modules/codec/c++/forst.hpp b/modules/codec/c++/forst.hpp index 0e200cb..16f55c9 100644 --- a/modules/codec/c++/forst.hpp +++ b/modules/codec/c++/forst.hpp @@ -1,7 +1,10 @@ #pragma once +#include + #include "data.hpp" + namespace saw { namespace encode { struct KelForst {}; @@ -11,6 +14,7 @@ struct KelForst {}; #include "forst.tmpl.hpp" namespace saw { +template <> class data { private: own buff_; @@ -20,13 +24,71 @@ public: {} }; +template +class data, encode::KelForst> { +public: + using Schema = schema::Primitive; +private: + our buff_; + uint64_t displacement_; +public: + /** + * Constructor for root elements + */ + data(our buff): + buff_{std::move(buff)}, + displacement_{0u} + {} + + /** + * Constructor for child elements + */ + data(our buff, uint64_t dsp): + buff_{std::move(buff)}, + displacement_{dsp} + {} + + /** + * Get values + */ + typename native_data_type::type get(){ + return {}; + } + + /** + * Set values + */ + void set(typename native_data_type::type val){ + (void) val; + } +}; + template class data...>, encode::KelForst> { private: - own buff_; + /** + * Buffer holding the whole packet + */ + our buff_; + /** + * Displacement to show the starting point + */ + uint64_t displacement_; public: - data(own buff): - buff_{std::move(buff)} + /** + * Constructor for root elements + */ + data(our buff): + buff_{std::move(buff)}, + displacement_{0u} + {} + + /** + * Constructor for child elements + */ + data(our buff, uint64_t dsp): + buff_{std::move(buff)}, + displacement_{dsp} {} }; } diff --git a/modules/codec/c++/forst.tmpl.hpp b/modules/codec/c++/forst.tmpl.hpp index 30d18ef..bfcafae 100644 --- a/modules/codec/c++/forst.tmpl.hpp +++ b/modules/codec/c++/forst.tmpl.hpp @@ -1,7 +1,75 @@ namespace saw { namespace impl { -struct forst_decode { +/** + * This class provides + */ +template +struct forst_codec_info { + static_assert(always_false, "Not supported."); +}; + +template +struct forst_codec_info> { +private: +public: + static constexpr uint64_t layers = 0u; +}; + +template<> +struct forst_codec_info { +public: + static constexpr uint64_t layers = 1u; +}; + +template +struct forst_codec_info> { +public: + static constexpr uint64_t layers = 1u + forst_codec_info::layers; +}; + +template +struct forst_codec_info > { +public: + template + static uint64_t max_layers() constexpr noexcept { + if constexpr ( i < sizeof...(Members) ) { + using MT = typename parameter_pack_type::type; + + constexpr uint64_t layer_i = forst_codec_info::layers; + + constexpr uint64_t layer_next = max_layers(); + + constexpr uint64_t layer_val = layer_i > layer_next ? layer_i : layer_next; + + return layer_val; + } + return 0u; + } +public: + static constexpr uint64_t layers = max_layers<0>(); +}; + +template +struct forst_codec_info> { +public: + template + static uint64_t max_layers() constexpr noexcept { + if constexpr ( i < sizeof...(Members) ) { + using MT = typename parameter_pack_type::type; + + constexpr uint64_t layer_i = forst_codec_info::layers; + + constexpr uint64_t layer_next = max_layers(); + + constexpr uint64_t layer_val = layer_i > layer_next ? layer_i : layer_next; + + return layer_val; + } + return 0u; + } +public: + static constexpr uint64_t layers = max_layers<0>(); }; } } diff --git a/modules/codec/c++/rpc.hpp b/modules/codec/c++/rpc.hpp index 63ec014..9f59455 100644 --- a/modules/codec/c++/rpc.hpp +++ b/modules/codec/c++/rpc.hpp @@ -1,34 +1,98 @@ #pragma once namespace saw { + +/** + * + */ +template +class remote_data { +private: + id id_; +public: + remote_data(const id& id): + id_{id} + {} + + /** + * Wait until data arrives + */ + error_or> wait(wait_scope& wait); + + /** + * Asynchronously wait for a result + */ + conveyor> on_receive(); +}; + /** + * Client RPC reference structure */ template class rpc_client { - template - struct request { - private: - std::tuple...> ids_; - public: - error_or...>> wait(); - }; + /** + * request the data from the remote + */ + template + remote_data request_data(id data); - template - request request_data(id... data); + /** + * Determine type based on Name + */ + template + error_or< + id< + typename schema_member_type::type + > + > call(data_or_id inp); }; +/** + * Implementation of a remote server on the backend + */ template class rpc_server { +private: + interface iface_; +public: + rpc_server(interface iface): + iface_{std::move(iface)} + {} }; +/** + * Representation of a remote. + * Partially similar to a network address + */ template -class remote { - static_assert(always_false, "Type of remote not supported"); +class remote_address { + static_assert(always_false, "Type of remote not supported"); + + +}; + +/** + * Reference Backend structure + */ +template +class remote_context { + static_assert(always_false, "Type of backend not supported"); + + /** + * Resolves an address on the remote + */ + conveyor> resolve_address(); - template - rpc_client connect(); + /** + * Connect to a remote + */ + template + conveyor> connect(const remote_address& addr); - template - rpc_server listen(network& net); + /** + * Start listening + */ + template + rpc_server listen(); }; } diff --git a/modules/codec/c++/schema.hpp b/modules/codec/c++/schema.hpp index 37615c5..a992a84 100644 --- a/modules/codec/c++/schema.hpp +++ b/modules/codec/c++/schema.hpp @@ -135,6 +135,91 @@ struct Interface,Names>...> { // NOLINTEND } // namespace schema + +template +struct schema_has_member{ + static_assert( + always_false, + "Not supported schema case"); +}; + +/** + * Checks if identical type exists in schema structure + */ +template +struct schema_has_member> { +private: + template + static constexpr bool value_element() { + if constexpr ( i < sizeof...(Members) ){ + using MT = typename parameter_pack_type::type; + if constexpr ( std::is_same_v ) { + return true; + } else { + return value_element(); + } + } + return false; + } +public: + static constexpr bool value = value_element<0>(); +}; + +/** + * + */ +template +struct schema_has_key { + static_assert( + always_false, + "Not supported schema case"); +}; + +template +struct schema_has_key> { +private: + template + static constexpr bool value_element() { + if constexpr ( i < sizeof...(Members) ){ + using MT = typename parameter_pack_type::type; + + if constexpr ( Key == MT::KeyLiteral ) { + return true; + }else{ + return value_element(); + } + } + return false; + } +public: + static constexpr bool value = value_element<0>(); +}; + +template +struct schema_member_index { + static_assert( + always_false, + "Not supported schema case"); +}; + +template +struct schema_member_index...>> { + static constexpr uint64_t value = parameter_key_pack_index::value; +}; + +template +struct schema_member_type { + static_assert( + always_false, + "Not supported schema case"); +}; + +template +struct schema_member_type...>> { + + using type = typename parameter_pack_type...>>::value, MemberVals...>::type; +}; + template struct is_struct { constexpr static bool value = false; }; diff --git a/modules/codec/c++/schema_factory.hpp b/modules/codec/c++/schema_factory.hpp index 8896fdf..6b824f4 100644 --- a/modules/codec/c++/schema_factory.hpp +++ b/modules/codec/c++/schema_factory.hpp @@ -11,11 +11,35 @@ struct schema_factory { template struct schema_factory...>> { +private: +public: using Schema = schema::Struct...>; + + template + static constexpr bool has_key() noexcept { + return schema_has_key::value; + } + + template + static constexpr bool has_member() noexcept { + return schema_has_member, Schema>::value; + } + + template + constexpr auto add_maybe() const noexcept { + if constexpr (!has_key()) { + return schema_factory..., schema::Member>>{}; + } else if constexpr (has_member() ){ + return schema_factory...> >{}; + } else { + static_assert(always_false, "Struct already has the provided Key, but a mismatching Type"); + } + } template constexpr schema_factory...,schema::Member>> add() const noexcept { - return {}; + static_assert(!has_key(), "Can't add member. Name is already in use."); + return {}; } }; @@ -25,7 +49,8 @@ struct schema_factory...>> { template constexpr schema_factory...,schema::Member>> add() const noexcept { - return {}; + static_assert(!has_key(), "Can't add member. Name is already in use."); + return {}; } }; diff --git a/modules/codec/tests/forst.cpp b/modules/codec/tests/forst.cpp new file mode 100644 index 0000000..cb0442d --- /dev/null +++ b/modules/codec/tests/forst.cpp @@ -0,0 +1,29 @@ +#include +#include "../c++/data.hpp" +#include "../c++/forst.hpp" + +#include + +namespace { +namespace schema { +using namespace saw::schema; + +using TestStruct = Struct< + Member, + Member, + Member +>; + +using TestArray = Array< + TestStruct +>; + +SAW_TEST("Codec Forst Info"){ + using namespace saw; + + SAW_EXPECT(impl::forst_codec_info::layers == 0, "Layer info is wrong"); + SAW_EXPECT(impl::forst_codec_info::layers == 1, "Layer info is wrong"); + SAW_EXPECT(impl::forst_codec_info::layers == 2, "Layer info is wrong"); +} +} +} diff --git a/modules/codec/tests/schema.cpp b/modules/codec/tests/schema.cpp index 408a142..77d369d 100644 --- a/modules/codec/tests/schema.cpp +++ b/modules/codec/tests/schema.cpp @@ -3,6 +3,7 @@ #include #include "../c++/schema.hpp" #include "../c++/schema_hash.hpp" +#include "../c++/schema_factory.hpp" namespace { template @@ -70,4 +71,72 @@ SAW_TEST("Schema Hashes"){ schema_test_pair >::check(); } + +SAW_TEST("Schema Factory Compiles"){ + using namespace saw; + + auto factory = build_schema>(); + + auto str = factory + .add() + .add() + .add_maybe() + .add_maybe() + ; + + using FactorySchema = decltype(str)::Schema; + + using Schema = schema::Struct< + schema::Member, + schema::Member, + schema::Member + >; + + SAW_EXPECT(is_struct::value, "Expected a struct"); + + schema_hash_test_multi< + schema_test_pair, + schema_test_pair + >::check(); +} + +template +auto ensure_types_one(saw::schema_factory builder){ + return builder + .template add_maybe, "foo">() + .template add_maybe() + ; +} + +template +auto ensure_types_two(saw::schema_factory builder){ + return builder + .template add_maybe, "foo">() + .template add_maybe() + ; +} + +SAW_TEST("Schema Factory Multimethod"){ + using namespace saw; + auto builder = build_schema>(); + + /** + * This would basically be multiple components + */ + auto b2 = ensure_types_one(builder); + auto b3 = ensure_types_two(b2); + + using Schema = schema::Struct< + schema::Member, "foo">, + schema::Member, + schema::Member + >; + + schema_hash_test_multi< + schema_test_pair, + schema_test_pair + >::check(); + + +} } -- cgit v1.2.3