From 3be2ae868746f2fc09f69e667e18b838cef82be9 Mon Sep 17 00:00:00 2001 From: Claudius Holeksa Date: Fri, 19 May 2023 02:34:39 +0200 Subject: Initial commit with copying the unit lib --- src/kelunit/distance/meter.h | 20 +++++++ src/kelunit/time/second.h | 15 +++++ src/kelunit/unit.h | 49 ++++++++++++++++ src/kelunit/unit.tmpl.h | 53 +++++++++++++++++ src/kelunit/unit_print.h | 55 ++++++++++++++++++ src/kelunit/unit_reduction.h | 133 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 325 insertions(+) create mode 100644 src/kelunit/distance/meter.h create mode 100644 src/kelunit/time/second.h create mode 100644 src/kelunit/unit.h create mode 100644 src/kelunit/unit.tmpl.h create mode 100644 src/kelunit/unit_print.h create mode 100644 src/kelunit/unit_reduction.h (limited to 'src') diff --git a/src/kelunit/distance/meter.h b/src/kelunit/distance/meter.h new file mode 100644 index 0000000..57ca58e --- /dev/null +++ b/src/kelunit/distance/meter.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../unit.h" + +#include + +namespace kelun { +namespace unit_type { +struct meter{ + static constexpr std::string_view name = "meter"; + static constexpr std::string_view short_name = "m"; +}; +} + +template +using meter = unit>; + +template +using square_meter = unit>; +} diff --git a/src/kelunit/time/second.h b/src/kelunit/time/second.h new file mode 100644 index 0000000..07145ca --- /dev/null +++ b/src/kelunit/time/second.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../unit.h" + +namespace kelun { +namespace unit_type { +struct second{ + static constexpr std::string_view name = "second"; + static constexpr std::string_view short_name = "s"; +}; +} + +template +using second = unit>; +} diff --git a/src/kelunit/unit.h b/src/kelunit/unit.h new file mode 100644 index 0000000..4958eb9 --- /dev/null +++ b/src/kelunit/unit.h @@ -0,0 +1,49 @@ +#pragma once + +#include "./unit_reduction.h" + +namespace kelun { +template +struct unit_base {}; + +template +class unit; + +template +class unit...> { +public: + using value_type = StorageT; + + unit() = default; + + unit(const unit...>&) = default; + unit(unit...>&&) = default; + + unit...>& operator=(const unit...>&) = default; + unit...>& operator=(unit...>&&) = default; + + unit(const value_type&); + unit(value_type&&); + + unit...>& operator=(const value_type&); + unit...>& operator=(value_type&&); + + unit...> operator+(const unit...>& rhs); + unit...> operator-(const unit...>& rhs); + + template + typename unit_multiplication...>, unit>::type operator*(const unit& rhs); + + template + typename unit_multiplication...>, typename unit_invert::type>::type operator/(const unit& rhs); + + value_type data() const; +private: + value_type value; +}; + +template +using scalar = unit; +} + +#include "unit.tmpl.h" diff --git a/src/kelunit/unit.tmpl.h b/src/kelunit/unit.tmpl.h new file mode 100644 index 0000000..42b96ef --- /dev/null +++ b/src/kelunit/unit.tmpl.h @@ -0,0 +1,53 @@ +#include + +namespace kelun { + +template +unit...>::unit(const value_type& value_): + value{value_}{} + +template +unit...>::unit(value_type&& value_):value{std::move(value_)}{} + +template +unit...>& unit...>::operator=(const typename unit...>::value_type& value_){ + value = value_; + return *this; +} + +template +unit...>& unit...>::operator=(typename unit...>::value_type&& value_){ + value = std::move(value_); + return *this; +} + +template +unit...> unit...>::operator+(const unit...>& rhs){ + return value + rhs.value; +} + +template +unit...> unit...>::operator-(const unit...>& rhs){ + return value - rhs.value; +} + +template +template +typename unit_multiplication...>, unit>::type +unit...>::operator*(const unit& rhs){ + return value * rhs.data(); +} + +template +template +typename unit_multiplication...>, typename unit_invert::type>::type +unit...>::operator/(const unit& rhs){ + typename unit_invert::type rhs_inverted{static_cast(1)/rhs.data()}; + return value * rhs_inverted.data(); +} + +template +typename unit...>::value_type unit...>::data() const { + return value; +} +} diff --git a/src/kelunit/unit_print.h b/src/kelunit/unit_print.h new file mode 100644 index 0000000..0f3cb72 --- /dev/null +++ b/src/kelunit/unit_print.h @@ -0,0 +1,55 @@ +#include "./unit.h" + +#include + + +namespace std { +template +inline ostream& operator<<(ostream& o, const kelun::unit_base& ele){ + o< +struct unit_print_impl { + static_assert(is_always_false, "Template type not supported"); +}; + +template +struct unit_print_impl,unit_base...> { + static std::ostream& print(std::ostream& o){ + + unit_base element; + + std::ostream& o_ret = o << element; + + if constexpr (sizeof...(UnitTL) > 0){ + std::ostream& o_ret_next = o_ret << ' ' << '*' << ' '; + return unit_print_impl...>::print(o_ret_next); + } + + return o_ret<<']'; + } +}; +} + +namespace std { + +template +inline ostream& operator<<(ostream& o, const kelun::unit& unit); + +template +inline ostream& operator<<(ostream& o, const kelun::unit...>& unit){ + o << unit.data(); + if constexpr (sizeof...(UnitT) > 0) { + auto& o_ret = o << ' '<<'['; + return kelun::unit_print_impl...>::print(o_ret); + } + return o; +} +} diff --git a/src/kelunit/unit_reduction.h b/src/kelunit/unit_reduction.h new file mode 100644 index 0000000..d3299ff --- /dev/null +++ b/src/kelunit/unit_reduction.h @@ -0,0 +1,133 @@ +#pragma once + +#include +#include + +namespace kelun { +template +constexpr bool is_always_false = false; + +template +struct unit_base; + +template +class unit; + +namespace impl { + +template +class unit_matching; + +template +class unit_redux_list { + static_assert(sizeof...(T) == 0, "Template type not supported"); + + using reduced_typed = unit_redux_list<>; +}; + +template +struct unit_redux_list, unit_base...> { + using reduced_type = typename unit_matching, unit_base...>, unit_redux_list<>>::type; +}; + +template +class unit_matching_reduce { +public: + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_matching_reduce, unit_redux_list,unit_base...>, unit_redux_list...>> { +public: + static constexpr bool is_same = std::is_same_v; + + using match_reduce_type = typename std::conditional, unit_base>::type; + using match_reduce_unit_redux_list = typename std::conditional...>, unit_redux_list..., unit_base>>::type; + + using value_type = typename unit_matching_reduce...>, match_reduce_unit_redux_list>::value_type; + using unit_redux_list_type = typename unit_matching_reduce...>, match_reduce_unit_redux_list>::unit_redux_list_type; + + static constexpr int64_t value_num = unit_matching_reduce...>, match_reduce_unit_redux_list>::value_num; +}; + +template +class unit_matching_reduce, unit_redux_list<>, unit_redux_list...>> { +public: + using value_type = unit_base; + using unit_redux_list_type = unit_redux_list...>; + + static constexpr int64_t value_num = E; +}; + +template +class unit_matching { + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_matching,unit_redux_list...>> { +public: + using type = unit_redux_list...>; + +}; + +template +class unit_matching,unit_base...>, unit_redux_list...>> { +public: + using reduced_value_type = typename unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::value_type; + using reduced_unit_redux_list_type = typename unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::unit_redux_list_type; + + static constexpr int64_t reduced_value_num = unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::value_num; + using reduced_result_unit_redux_list = typename std::conditional...>, unit_redux_list...,reduced_value_type>>::type; + + using type = typename unit_matching::type; +}; + +template +class unit_matching_add_storage { +public: + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_matching_add_storage...>, StorageT> { +public: + using type = unit...>; +}; + +} + +template +class unit_reduction { + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_reduction...> { +public: + using list_type = typename impl::unit_matching...>, impl::unit_redux_list<>>::type; + using type = typename impl::unit_matching_add_storage::type; +}; + +template +class unit_invert { + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_invert...> { +public: + using type = unit...>; +}; + +template +class unit_multiplication{ + static_assert(is_always_false, "Template type not supported"); +}; + +template +class unit_multiplication...>, unit...>> { +public: + using type = typename unit_reduction..., unit_base...>::type; +}; +} -- cgit v1.2.3