summaryrefslogtreecommitdiff
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
parent89c37ae7d84beb08ed99539bee972c241075d45e (diff)
Implemented basic class and operations
-rw-r--r--modules/codec-unit/c++/unit.hpp12
-rw-r--r--modules/codec-unit/c++/unit.tmpl.hpp32
-rw-r--r--modules/codec-unit/c++/unit_transform.hpp102
-rw-r--r--modules/codec-unit/tests/codec-unit.cpp56
4 files changed, 181 insertions, 21 deletions
diff --git a/modules/codec-unit/c++/unit.hpp b/modules/codec-unit/c++/unit.hpp
index 986ca8f..0e7bf74 100644
--- a/modules/codec-unit/c++/unit.hpp
+++ b/modules/codec-unit/c++/unit.hpp
@@ -3,6 +3,8 @@
#include "unit_schema.hpp"
#include "unit_transform.hpp"
+#include <forstio/codec/data.hpp>
+
namespace saw {
template<typename BaseSchema, typename... Elements>
class data<schema::Unit<BaseSchema, Elements...>, encode::Native> {
@@ -19,7 +21,15 @@ public:
data<Schema, encode::Native> operator+(const data<Schema, encode::Native>& rhs) const;
data<Schema, encode::Native> operator-(const data<Schema, encode::Native>& rhs) const;
+
+ bool operator==(const data<Schema, encode::Native>& rhs) const;
+
+ template<typename UnitRhs>
+ data<typename unit_multiplication<Schema, UnitRhs>::Schema, encode::Native> operator*(const data<UnitRhs, encode::Native>& rhs) const;
+
+ template<typename UnitRhs>
+ data<typename unit_division<Schema, UnitRhs>::Schema, encode::Native> operator/(const data<UnitRhs, encode::Native>& rhs) const;
};
}
-#include "unit.tmpl.h"
+#include "unit.tmpl.hpp"
diff --git a/modules/codec-unit/c++/unit.tmpl.hpp b/modules/codec-unit/c++/unit.tmpl.hpp
index 7412199..08edc4f 100644
--- a/modules/codec-unit/c++/unit.tmpl.hpp
+++ b/modules/codec-unit/c++/unit.tmpl.hpp
@@ -3,17 +3,41 @@ namespace saw {
template<typename BaseSchema, typename... Elements>
data<schema::Unit<BaseSchema, Elements...>, encode::Native>
data<schema::Unit<BaseSchema, Elements...>, encode::Native>::operator+(const
-data<schema::Unit<BaseSchema, Elements...>, encode::Native>& rhs){
+data<schema::Unit<BaseSchema, Elements...>, encode::Native>& rhs) const {
auto add = dat_ + rhs.dat_;
- return {add};
+ return add;
}
template<typename BaseSchema, typename... Elements>
data<schema::Unit<BaseSchema, Elements...>, encode::Native>
data<schema::Unit<BaseSchema, Elements...>, encode::Native>::operator-(const
-data<schema::Unit<BaseSchema, Elements...>, encode::Native>& rhs){
+data<schema::Unit<BaseSchema, Elements...>, encode::Native>& rhs) const {
auto sub = dat_ - rhs.dat_;
- return {sub};
+ return sub;
+}
+
+template<typename BaseSchema, typename... Elements>
+bool
+data<schema::Unit<BaseSchema, Elements...>, encode::Native>::operator==(const data<Schema, encode::Native>& rhs) const {
+ return dat_ == rhs.dat_;
+}
+
+template<typename BaseSchema, typename... Elements>
+template<typename UnitRhs>
+data<typename unit_multiplication<schema::Unit<BaseSchema,Elements...>, UnitRhs>::Schema, encode::Native>
+data<schema::Unit<BaseSchema, Elements...>, encode::Native>::operator*(const
+data<UnitRhs, encode::Native>& rhs) const {
+ auto mult = dat_ * rhs.dat_;
+ return mult;
+}
+
+template<typename BaseSchema, typename... Elements>
+template<typename UnitRhs>
+data<typename unit_division<schema::Unit<BaseSchema,Elements...>, UnitRhs>::Schema, encode::Native>
+data<schema::Unit<BaseSchema, Elements...>, encode::Native>::operator/(const
+data<UnitRhs, encode::Native>& rhs) const {
+ auto div = dat_ / rhs.dat_;
+ return div;
}
}
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;
};
}
diff --git a/modules/codec-unit/tests/codec-unit.cpp b/modules/codec-unit/tests/codec-unit.cpp
index 0c88e9d..39e590d 100644
--- a/modules/codec-unit/tests/codec-unit.cpp
+++ b/modules/codec-unit/tests/codec-unit.cpp
@@ -2,15 +2,63 @@
#include <forstio/codec/schema.hpp>
+#include "../c++/unit.hpp"
+
namespace {
namespace sch {
using namespace saw::schema;
+
+struct FanMeterEle {};
+
+using FanMeter = Unit<
+ Int64,
+ UnitElement<FanMeterEle,1>
+>;
+
+using FanSquareMeter = Unit<
+ Int64,
+ UnitElement<FanMeterEle,2>
+>;
+}
+
+
+SAW_TEST("Codec Unit/Addition"){
+ using namespace saw;
+
+ data<sch::FanMeter> a{{5}}, b{{4}};
+
+ auto c = a + b;
+
+ SAW_EXPECT(c == data<sch::FanMeter>{9u}, "Expected result 9");
+}
+
+SAW_TEST("Codec Unit/Subtraction"){
+ using namespace saw;
+
+ data<sch::FanMeter> a{{5}}, b{{4}};
+
+ auto c = a - b;
+
+ SAW_EXPECT(c == data<sch::FanMeter>{1u}, "Expected result 1");
}
-/*
-SAW_TEST("Dummy Test"){
+SAW_TEST("Codec Unit/Multiplication"){
using namespace saw;
- SAW_EXPECT( false, "Dummy" );
+
+ data<sch::FanMeter> a{{5}}, b{{4}};
+
+ auto c = a * b;
+
+ SAW_EXPECT(c == data<sch::FanSquareMeter>{20u}, "Expected result 20");
+}
+
+SAW_TEST("Codec Unit/Division"){
+ using namespace saw;
+
+ data<sch::FanMeter> a{{20}}, b{{4}};
+
+ auto c = a / b;
+
+ SAW_EXPECT(c == data<sch::Scalar<sch::Int64>>{5u}, "Expected result 5");
}
-*/
}