summaryrefslogtreecommitdiff
path: root/modules/codec-unit/c++/unit_transform.hpp
diff options
context:
space:
mode:
authorClaudius 'keldu' Holeksa <mail@keldu.de>2024-09-05 12:51:35 +0200
committerClaudius 'keldu' Holeksa <mail@keldu.de>2024-09-05 12:51:35 +0200
commitf27d397e9ab2d5c020b04dde4361fffa933f103c (patch)
tree624a0890ba2aed0130b5e58f60098d69e4e304fe /modules/codec-unit/c++/unit_transform.hpp
parent89c37ae7d84beb08ed99539bee972c241075d45e (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.hpp102
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;
};
}