From 700cde2d499742160deb361f42b7e861ae1db8ed Mon Sep 17 00:00:00 2001 From: Claudius 'keldu' Holeksa Date: Mon, 29 Jul 2024 14:18:30 +0200 Subject: Renaming to new standard --- c++/distance/meter.h | 20 -------- c++/distance/meter.hpp | 20 ++++++++ c++/time/second.h | 15 ------ c++/time/second.hpp | 15 ++++++ c++/unit.h | 49 ------------------ c++/unit.hpp | 49 ++++++++++++++++++ c++/unit.tmpl.h | 53 -------------------- c++/unit.tmpl.hpp | 53 ++++++++++++++++++++ c++/unit_cast.h | 15 ------ c++/unit_cast.hpp | 15 ++++++ c++/unit_print.h | 55 -------------------- c++/unit_print.hpp | 55 ++++++++++++++++++++ c++/unit_reduction.h | 133 ------------------------------------------------- c++/unit_reduction.hpp | 133 +++++++++++++++++++++++++++++++++++++++++++++++++ examples/basic.cpp | 55 ++++++++++++++++++++ 15 files changed, 395 insertions(+), 340 deletions(-) delete mode 100644 c++/distance/meter.h create mode 100644 c++/distance/meter.hpp delete mode 100644 c++/time/second.h create mode 100644 c++/time/second.hpp delete mode 100644 c++/unit.h create mode 100644 c++/unit.hpp delete mode 100644 c++/unit.tmpl.h create mode 100644 c++/unit.tmpl.hpp delete mode 100644 c++/unit_cast.h create mode 100644 c++/unit_cast.hpp delete mode 100644 c++/unit_print.h create mode 100644 c++/unit_print.hpp delete mode 100644 c++/unit_reduction.h create mode 100644 c++/unit_reduction.hpp create mode 100644 examples/basic.cpp diff --git a/c++/distance/meter.h b/c++/distance/meter.h deleted file mode 100644 index 0d9fb3b..0000000 --- a/c++/distance/meter.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../unit.h" - -#include - -namespace kel { -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/c++/distance/meter.hpp b/c++/distance/meter.hpp new file mode 100644 index 0000000..0d9fb3b --- /dev/null +++ b/c++/distance/meter.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "../unit.h" + +#include + +namespace kel { +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/c++/time/second.h b/c++/time/second.h deleted file mode 100644 index 6dca456..0000000 --- a/c++/time/second.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../unit.h" - -namespace kel { -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/c++/time/second.hpp b/c++/time/second.hpp new file mode 100644 index 0000000..6dca456 --- /dev/null +++ b/c++/time/second.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "../unit.h" + +namespace kel { +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/c++/unit.h b/c++/unit.h deleted file mode 100644 index a8e8320..0000000 --- a/c++/unit.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "unit_reduction.h" - -namespace kel { -template -struct unit_component {}; - -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/c++/unit.hpp b/c++/unit.hpp new file mode 100644 index 0000000..a8e8320 --- /dev/null +++ b/c++/unit.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "unit_reduction.h" + +namespace kel { +template +struct unit_component {}; + +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/c++/unit.tmpl.h b/c++/unit.tmpl.h deleted file mode 100644 index 5eec43d..0000000 --- a/c++/unit.tmpl.h +++ /dev/null @@ -1,53 +0,0 @@ -#include - -namespace kel { - -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/c++/unit.tmpl.hpp b/c++/unit.tmpl.hpp new file mode 100644 index 0000000..5eec43d --- /dev/null +++ b/c++/unit.tmpl.hpp @@ -0,0 +1,53 @@ +#include + +namespace kel { + +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/c++/unit_cast.h b/c++/unit_cast.h deleted file mode 100644 index 8dc2689..0000000 --- a/c++/unit_cast.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -namespace kel { -template -class unit_convert { - static_assert(always_false, "Units can't be converted to each other"); -}; - -template -class unit_convert { - static constexpr factor = static_cast(1); -}; -} diff --git a/c++/unit_cast.hpp b/c++/unit_cast.hpp new file mode 100644 index 0000000..8dc2689 --- /dev/null +++ b/c++/unit_cast.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace kel { +template +class unit_convert { + static_assert(always_false, "Units can't be converted to each other"); +}; + +template +class unit_convert { + static constexpr factor = static_cast(1); +}; +} diff --git a/c++/unit_print.h b/c++/unit_print.h deleted file mode 100644 index 4d9187b..0000000 --- a/c++/unit_print.h +++ /dev/null @@ -1,55 +0,0 @@ -#include "./unit.h" - -#include - - -namespace std { -template -inline ostream& operator<<(ostream& o, const kel::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 kel::unit& unit); - -template -inline ostream& operator<<(ostream& o, const kel::unit...>& unit){ - o << unit.data(); - if constexpr (sizeof...(UnitT) > 0) { - auto& o_ret = o << ' '<<'['; - return kel::unit_print_impl...>::print(o_ret); - } - return o; -} -} diff --git a/c++/unit_print.hpp b/c++/unit_print.hpp new file mode 100644 index 0000000..4d9187b --- /dev/null +++ b/c++/unit_print.hpp @@ -0,0 +1,55 @@ +#include "./unit.h" + +#include + + +namespace std { +template +inline ostream& operator<<(ostream& o, const kel::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 kel::unit& unit); + +template +inline ostream& operator<<(ostream& o, const kel::unit...>& unit){ + o << unit.data(); + if constexpr (sizeof...(UnitT) > 0) { + auto& o_ret = o << ' '<<'['; + return kel::unit_print_impl...>::print(o_ret); + } + return o; +} +} diff --git a/c++/unit_reduction.h b/c++/unit_reduction.h deleted file mode 100644 index df02a4d..0000000 --- a/c++/unit_reduction.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -#include -#include - -namespace kel { -template -constexpr bool is_always_false = false; - -template -struct unit_component; - -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_component...> { - using reduced_type = typename unit_matching, unit_component...>, 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_component...>, unit_redux_list...>> { -public: - static constexpr bool is_same = std::is_same_v; - - using match_reduce_type = typename std::conditional, unit_component>::type; - using match_reduce_unit_redux_list = typename std::conditional...>, unit_redux_list..., unit_component>>::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_component; - 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_component...>, 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_component...>::type; -}; -} 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 +#include + +namespace kel { +template +constexpr bool is_always_false = false; + +template +struct unit_component; + +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_component...> { + using reduced_type = typename unit_matching, unit_component...>, 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_component...>, unit_redux_list...>> { +public: + static constexpr bool is_same = std::is_same_v; + + using match_reduce_type = typename std::conditional, unit_component>::type; + using match_reduce_unit_redux_list = typename std::conditional...>, unit_redux_list..., unit_component>>::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_component; + 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_component...>, 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_component...>::type; +}; +} diff --git a/examples/basic.cpp b/examples/basic.cpp new file mode 100644 index 0000000..d322ac7 --- /dev/null +++ b/examples/basic.cpp @@ -0,0 +1,55 @@ +#include "../c++/kelunit/distance/meter.hpp" +#include "../c++/kelunit/time/second.hpp" + +#include "../c++/kelunit/unit_print.hpp" + +#include + +int main(){ + /** + * The definition is a bit convoluted, so I leave it in the hands of the headers themselves and define a convenience alias for the user. + * meter e.g. is defined by + * + * namespace unit_type { + * struct meter {}; + * } + * template + * using meter = unit>; + * + * which then can be used as follows + */ + using scalar = kel::scalar; + using meter = kel::meter; + using square_meter = kel::square_meter; + using second = kel::second; + + meter a = 6.f; + + meter b = 3.f; + + second s = 10.f; + + // Since it is not compileable I cannot show it, but c + s would throw a compilation error. + meter c = a+b; + meter d = a-b; + + // Auto deduced type. Based on the template parameters automatically stitches together a valid unit + auto mps = b / s; + + // Technically auto deduced, but predefined for convenience. + square_meter e = a*b; + // + scalar f = a/b; + + std::cout<<"Values:\n"; + std::cout<<"a: "<