summaryrefslogtreecommitdiff
path: root/c++/unit_reduction.hpp
diff options
context:
space:
mode:
authorClaudius 'keldu' Holeksa <mail@keldu.de>2024-07-29 14:18:30 +0200
committerClaudius 'keldu' Holeksa <mail@keldu.de>2024-07-29 14:18:30 +0200
commit700cde2d499742160deb361f42b7e861ae1db8ed (patch)
treeba796243a94578f9c2105080fa19040a341c4482 /c++/unit_reduction.hpp
parentfb7dd1c9185da30aed8645c084be0722e061a867 (diff)
Renaming to new standard
Diffstat (limited to 'c++/unit_reduction.hpp')
-rw-r--r--c++/unit_reduction.hpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/c++/unit_reduction.hpp b/c++/unit_reduction.hpp
new file mode 100644
index 0000000..df02a4d
--- /dev/null
+++ b/c++/unit_reduction.hpp
@@ -0,0 +1,133 @@
+#pragma once
+
+#include <cstdint>
+#include <type_traits>
+
+namespace kel {
+template<typename... T>
+constexpr bool is_always_false = false;
+
+template<typename UnitType, int64_t Exponent>
+struct unit_component;
+
+template<typename StorageT, typename... T>
+class unit;
+
+namespace impl {
+
+template<typename T, typename U>
+class unit_matching;
+
+template<typename... T>
+class unit_redux_list {
+ static_assert(sizeof...(T) == 0, "Template type not supported");
+
+ using reduced_typed = unit_redux_list<>;
+};
+
+template<typename T0, int64_t E0, typename... TL, int64_t... EL>
+struct unit_redux_list<unit_component<T0,E0>, unit_component<TL,EL>...> {
+ using reduced_type = typename unit_matching<unit_redux_list<unit_component<T0,E0>, unit_component<TL,EL>...>, unit_redux_list<>>::type;
+};
+
+template<typename T, typename U, typename V>
+class unit_matching_reduce {
+public:
+ static_assert(is_always_false<T, U, V>, "Template type not supported");
+};
+
+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<unit_component<T,E>, unit_redux_list<unit_component<T0,E0>,unit_component<TL,EL>...>, unit_redux_list<unit_component<TR,ER>...>> {
+public:
+ static constexpr bool is_same = std::is_same_v<T,T0>;
+
+ using match_reduce_type = typename std::conditional<is_same, unit_component<T,E+E0>, unit_component<T,E>>::type;
+ using match_reduce_unit_redux_list = typename std::conditional<is_same, unit_redux_list<unit_component<TR,ER>...>, unit_redux_list<unit_component<TR,ER>..., unit_component<T0,E0>>>::type;
+
+ using value_type = typename unit_matching_reduce<match_reduce_type, unit_redux_list<unit_component<TL,EL>...>, match_reduce_unit_redux_list>::value_type;
+ using unit_redux_list_type = typename unit_matching_reduce<match_reduce_type, unit_redux_list<unit_component<TL,EL>...>, match_reduce_unit_redux_list>::unit_redux_list_type;
+
+ static constexpr int64_t value_num = unit_matching_reduce<match_reduce_type, unit_redux_list<unit_component<TL,EL>...>, match_reduce_unit_redux_list>::value_num;
+};
+
+template<typename T, int64_t E, typename... TR, int64_t... ER>
+class unit_matching_reduce<unit_component<T,E>, unit_redux_list<>, unit_redux_list<unit_component<TR,ER>...>> {
+public:
+ using value_type = unit_component<T,E>;
+ using unit_redux_list_type = unit_redux_list<unit_component<TR,ER>...>;
+
+ static constexpr int64_t value_num = E;
+};
+
+template<typename T, typename U>
+class unit_matching {
+ static_assert(is_always_false<T, U>, "Template type not supported");
+};
+
+template<typename... T, int64_t... E>
+class unit_matching<unit_redux_list<>,unit_redux_list<unit_component<T,E>...>> {
+public:
+ using type = unit_redux_list<unit_component<T,E>...>;
+
+};
+
+template<typename T0, int64_t E0, typename... TL, int64_t... EL, typename... TR, int64_t... ER>
+class unit_matching<unit_redux_list<unit_component<T0,E0>,unit_component<TL,EL>...>, unit_redux_list<unit_component<TR,ER>...>> {
+public:
+ using reduced_value_type = typename unit_matching_reduce<unit_component<T0,E0>, unit_redux_list<unit_component<TL,EL>...>, unit_redux_list<>>::value_type;
+ using reduced_unit_redux_list_type = typename unit_matching_reduce<unit_component<T0,E0>, unit_redux_list<unit_component<TL,EL>...>, unit_redux_list<>>::unit_redux_list_type;
+
+ static constexpr int64_t reduced_value_num = unit_matching_reduce<unit_component<T0,E0>, unit_redux_list<unit_component<TL,EL>...>, unit_redux_list<>>::value_num;
+ using reduced_result_unit_redux_list = typename std::conditional<reduced_value_num == 0, unit_redux_list<unit_component<TR,ER>...>, unit_redux_list<unit_component<TR,ER>...,reduced_value_type>>::type;
+
+ using type = typename unit_matching<reduced_unit_redux_list_type, reduced_result_unit_redux_list>::type;
+};
+
+template<typename List, typename StorageT>
+class unit_matching_add_storage {
+public:
+ static_assert(is_always_false<List,StorageT>, "Template type not supported");
+};
+
+template<typename StorageT, typename... UnitTypes, int64_t... UnitExponents>
+class unit_matching_add_storage<unit_redux_list<unit_component<UnitTypes,UnitExponents>...>, StorageT> {
+public:
+ using type = unit<StorageT, unit_component<UnitTypes,UnitExponents>...>;
+};
+
+}
+
+template<typename StorageT, typename... T>
+class unit_reduction {
+ static_assert(is_always_false<StorageT,T...>, "Template type not supported");
+};
+
+template<typename StorageT, typename... UnitT, int64_t... UnitE>
+class unit_reduction<StorageT, unit_component<UnitT, UnitE>...> {
+public:
+ using list_type = typename impl::unit_matching<impl::unit_redux_list<unit_component<UnitT, UnitE>...>, impl::unit_redux_list<>>::type;
+ using type = typename impl::unit_matching_add_storage<list_type, StorageT>::type;
+};
+
+template<typename StorageT, typename... T>
+class unit_invert {
+ static_assert(is_always_false<StorageT, T...>, "Template type not supported");
+};
+
+template<typename StorageT, typename... UnitT, int64_t... UnitE>
+class unit_invert<StorageT, unit_component<UnitT, UnitE>...> {
+public:
+ using type = unit<StorageT, unit_component<UnitT, -UnitE>...>;
+};
+
+template<typename T, typename U>
+class unit_multiplication{
+ static_assert(is_always_false<T, U>, "Template type not supported");
+};
+
+template<typename StorageT, typename... UnitT, int64_t... UnitE, typename... UnitRhsT, int64_t... UnitRhsE>
+class unit_multiplication<unit<StorageT, unit_component<UnitT,UnitE>...>, unit<StorageT, unit_component<UnitRhsT, UnitRhsE>...>> {
+public:
+ using type = typename unit_reduction<StorageT, unit_component<UnitT,UnitE>..., unit_component<UnitRhsT, UnitRhsE>...>::type;
+};
+}