diff options
author | Claudius Holeksa <mail@keldu.de> | 2023-06-27 12:41:56 +0200 |
---|---|---|
committer | Claudius Holeksa <mail@keldu.de> | 2023-06-27 12:41:56 +0200 |
commit | 5688c721c610e2a8931d6ec6f84dee2d4d65c763 (patch) | |
tree | 3d38ec081061f2d6226a12af93ee092f27882d8c /src/codec | |
parent | 7668b8aceb42b5a46e1f9ca36d16dbfabe291748 (diff) |
c++,codec,core: Added Union to KelSimple and fixed the native data type.
Made some errors more clear as well
Diffstat (limited to 'src/codec')
-rw-r--r-- | src/codec/data.h | 14 | ||||
-rw-r--r-- | src/codec/simple.h | 81 |
2 files changed, 93 insertions, 2 deletions
diff --git a/src/codec/data.h b/src/codec/data.h index 9eb2bfc..397aed1 100644 --- a/src/codec/data.h +++ b/src/codec/data.h @@ -91,12 +91,22 @@ public: SAW_DEFAULT_MOVE(data); template<string_literal lit> + void set(data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native> val){ + value_ = std::move(val); + } + + template<string_literal lit> bool holds_alternative() const { - return std::holds_alternative<parameter_key_pack_index<lit, literals...>::value>(value_); + return (parameter_key_pack_index<lit, literals...>::value == value_.index()); } template<string_literal lit> - data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value>::type, encode::Native>& get(){ + data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get(){ + return std::get<parameter_key_pack_index<lit, literals...>::value>(value_); + } + + template<string_literal lit> + const data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get() const{ return std::get<parameter_key_pack_index<lit, literals...>::value>(value_); } }; diff --git a/src/codec/simple.h b/src/codec/simple.h index 8712c6d..8760754 100644 --- a/src/codec/simple.h +++ b/src/codec/simple.h @@ -82,6 +82,9 @@ struct kelsimple_encode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; { auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<Literal>(), to); + if(eov.is_error()){ + return eov; + } } if constexpr ((i+1) < sizeof...(T)){ auto eov = encode_member<i+1>(from, to); @@ -97,6 +100,41 @@ struct kelsimple_encode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { } }; +template<typename... T, string_literal... Lits, typename FromEnc> +struct kelsimple_encode<schema::Union<schema::Member<T,Lits>...>,FromEnc> { + template<std::size_t i> + static error_or<void> encode_member(const data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){ + using Type = typename parameter_pack_type<i,T...>::type; + constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; + if (from.template holds_alternative<Literal>()) { + { + auto eov = stream_value<schema::UInt64>::encode(static_cast<uint64_t>(i), to); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<Literal>(), to); + if(eov.is_error()){ + return eov; + } + } + } + + if constexpr ( (i+1) < sizeof...(T) ){ + auto eov = encode_member<i+1>(from, to); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + } + + static error_or<void> encode(const data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){ + return encode_member<0>(from, to); + } +}; + template<typename... T, typename FromEnc> struct kelsimple_encode<schema::Tuple<T...>, FromEnc> { template<std::size_t i> @@ -207,6 +245,9 @@ struct kelsimple_decode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; { auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<Literal>()); + if(eov.is_error()){ + return eov; + } } if constexpr ((i+1) < sizeof...(T)){ auto eov = decode_member<i+1>(from, to); @@ -222,6 +263,46 @@ struct kelsimple_decode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { } }; + +template<typename... T, string_literal... Lits, typename FromEnc> +struct kelsimple_decode<schema::Union<schema::Member<T,Lits>...>,FromEnc> { + template<uint64_t i> + static error_or<void> decode_member(buffer& from, data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& to, uint64_t val){ + using Type = typename parameter_pack_type<i,T...>::type; + constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; + + if( i == val ){ + to.template set<Literal>(data<Type, FromEnc>{}); + auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<Literal>()); + if(eov.is_error()){ + return eov; + } + return void_t{}; + } + + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member<i+1>(from, to, val); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + + } + static error_or<void> decode(buffer& from, data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& to){ + uint64_t val{}; + auto eov = stream_value<schema::UInt64>::decode(val, from); + if(eov.is_error()){ + return eov; + } + if ( val >= sizeof...(T) ){ + return make_error<err::invalid_state>(); + } + return decode_member<0>(from, to, val); + } + +}; + template<typename... T, typename FromEnc> struct kelsimple_decode<schema::Tuple<T...>,FromEnc> { template<std::size_t i> |