diff options
author | Claudius 'keldu' Holeksa <mail@keldu.de> | 2024-09-05 12:51:35 +0200 |
---|---|---|
committer | Claudius 'keldu' Holeksa <mail@keldu.de> | 2024-09-05 12:51:35 +0200 |
commit | f27d397e9ab2d5c020b04dde4361fffa933f103c (patch) | |
tree | 624a0890ba2aed0130b5e58f60098d69e4e304fe /modules/codec-unit/c++/unit_transform.hpp | |
parent | 89c37ae7d84beb08ed99539bee972c241075d45e (diff) |
Implemented basic class and operations
Diffstat (limited to 'modules/codec-unit/c++/unit_transform.hpp')
-rw-r--r-- | modules/codec-unit/c++/unit_transform.hpp | 102 |
1 files changed, 90 insertions, 12 deletions
diff --git a/modules/codec-unit/c++/unit_transform.hpp b/modules/codec-unit/c++/unit_transform.hpp index 3cae3c5..2e1ace4 100644 --- a/modules/codec-unit/c++/unit_transform.hpp +++ b/modules/codec-unit/c++/unit_transform.hpp @@ -1,5 +1,7 @@ #pragma once +#include <forstio/common.hpp> + #include <type_traits> #include "unit_schema.hpp" @@ -13,40 +15,116 @@ template<typename... T> class unit_redux_list { static_assert(sizeof...(T) == 0u, "Template type not supported"); - using reduced_type = unit_redux_list<>; + using Type = unit_redux_list<>; +}; + +template<typename T0, int64_t E0, typename... TL, int64_t... EL> +struct unit_redux_list<schema::UnitElement<T0,E0>, schema::UnitElement<TL,EL>...> { + using Type = typename unit_matching<unit_redux_list<schema::UnitElement<T0,E0>, schema::UnitElement<TL,EL>...>, unit_redux_list<>>::TypeList; +}; + +template<typename T, typename U, typename V> +class unit_matching_reduce { +public: + static_assert(always_false<T,U,V>, "Template type not supported"); +}; + +/** + * Iterate over the left list to check against the left element. + */ +template<typename T, int64_t E, typename T0, int64_t E0, typename... TL, int64_t... EL, typename... TR, int64_t... ER> +class unit_matching_reduce<schema::UnitElement<T,E>, unit_redux_list<schema::UnitElement<T0,E0>,schema::UnitElement<TL,EL>...>, unit_redux_list<schema::UnitElement<TR,ER>...>> { +public: + static constexpr bool is_same = std::is_same_v<T,T0>; + + // Match T,E against T0,E0 + using ReducedType = typename std::conditional<is_same, schema::UnitElement<T,E+E0>, schema::UnitElement<T,E>>::type; + using ReducedTypeList = typename std::conditional<is_same, unit_redux_list<schema::UnitElement<TR,ER>...>, unit_redux_list<schema::UnitElement<TR,ER>..., schema::UnitElement<T0,E0>>>::type; + + using NextMatcher = unit_matching_reduce<ReducedType, unit_redux_list<schema::UnitElement<TL,EL>...>, ReducedTypeList>; + using Type = typename NextMatcher::Type; + using TypeList = typename NextMatcher::TypeList; + static constexpr int64_t Num = NextMatcher::Num; +}; + +/** + * Final step after going through the list. This contains the final match result. + * On the left is the accumulated type and on the right its's a list of non matching types + */ +template<typename T, int64_t E, typename... TR, int64_t... ER> +class unit_matching_reduce<schema::UnitElement<T,E>, unit_redux_list<>, unit_redux_list<schema::UnitElement<TR,ER>...>> { +public: + using Type = schema::UnitElement<T,E>; + using TypeList = unit_redux_list<schema::UnitElement<TR,ER>...>; + static constexpr int64_t Num = E; }; template<typename LR, typename RR> class unit_matching { - static_assert(is_always_false<LR,RR>, "Template type not supported"); + static_assert(always_false<LR,RR>, "Template type not supported"); }; template<typename... Ele> class unit_matching<unit_redux_list<>, unit_redux_list<Ele...>> { - using Type = unit_redux_list<Ele...>; +public: + using TypeList = unit_redux_list<Ele...>; }; template<typename Ele0, typename... EleL, typename... EleR> -class unit_matching<unit_redux_list<Ele0, ELeL...>, unit_redux_list<EleR...>> { - using Type = +class unit_matching<unit_redux_list<Ele0, EleL...>, unit_redux_list<EleR...>> { +public: + // static constexpr bool is_same = std::is_same_v<T,T0>; + + using MatchReducer = unit_matching_reduce<Ele0, unit_redux_list<EleL...>, unit_redux_list<>>; + + using ReducedType = typename MatchReducer::Type; + using ReducedTypeList = typename MatchReducer::TypeList; + static constexpr int64_t Num = MatchReducer::Num; + + using TypeRightList = typename std::conditional<Num == 0u, unit_redux_list<EleR...>, unit_redux_list<EleR..., ReducedType>>::type; + using TypeList = typename unit_matching<ReducedTypeList, TypeRightList>::TypeList; +}; + +template<typename BaseSchema, typename List> +class unit_add_base { + static_assert(always_false<BaseSchema,List>, "Template type not supported"); +}; + +template<typename BaseSchema, typename... Ele> +class unit_add_base<BaseSchema, unit_redux_list<Ele...>> { +public: + using Schema = schema::Unit<BaseSchema, Ele...>; }; } -template<typename... UE> +template<typename BaseSchema, typename... UE> struct unit_element_reduction { - using Schema = typename impl::unit_matching<impl::unit_redux_list<UE...>, impl::unit_redux_list<>>::Schema; + using TypeList = typename impl::unit_matching<impl::unit_redux_list<UE...>, impl::unit_redux_list<>>::TypeList; + using Schema = typename impl::unit_add_base<BaseSchema, TypeList>::Schema; }; template<typename U0, typename U1> struct unit_multiplication { - static_assert(is_always_false<U0,U1>, "Template type not supported"); + static_assert(always_false<U0,U1>, "Template type not supported"); +}; + +template<typename BaseSchema, typename... UnitT, int64_t... UnitE, typename... UnitRhsT, int64_t... UnitRhsE> +struct unit_multiplication< + schema::Unit<BaseSchema, schema::UnitElement<UnitT,UnitE>...>,schema::Unit<BaseSchema, schema::UnitElement<UnitRhsT,UnitRhsE>...> +> { + using Schema = typename unit_element_reduction<BaseSchema, schema::UnitElement<UnitT,UnitE>..., schema::UnitElement<UnitRhsT, UnitRhsE>...>::Schema; +}; + +template<typename U0, typename U1> +struct unit_division { + static_assert(always_false<U0,U1>, "Template type not supported"); }; -template<typename... UnitT, int64_t... UnitE, typename... UnitRhsT, int64_t... UnitRhsE> -class unit_multiplication< - schema::Unit<schema::UnitElement<UnitT,UnitE>...>,schema::Unit<schema::UnitElement<UnitRhsT,UnitRhsE>...> +template<typename BaseSchema, typename... UnitT, int64_t... UnitE, typename... UnitRhsT, int64_t... UnitRhsE> +struct unit_division< + schema::Unit<BaseSchema, schema::UnitElement<UnitT,UnitE>...>,schema::Unit<BaseSchema, schema::UnitElement<UnitRhsT,UnitRhsE>...> > { - using Schema = typename unit_reduction<schema::UnitElement<UnitT,UnitE>..., schema::UnitElement<UnitRhsT, UnitRhsE>...>::Schema; + using Schema = typename unit_element_reduction<BaseSchema, schema::UnitElement<UnitT,UnitE>..., schema::UnitElement<UnitRhsT, -UnitRhsE>...>::Schema; }; } |