summaryrefslogtreecommitdiff
path: root/c++
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-08-25 10:10:51 +0200
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-08-25 10:10:51 +0200
commit488653602d0636a1fa5ef6e64cabb9b903dce42a (patch)
treeb5d4bbffdf21017777f4c4d994b7b41a02e8fa5d /c++
parente3c73b2c8b33b43d53de6d2106b93a4343609e80 (diff)
Renamed src folder to c++
Diffstat (limited to 'c++')
-rw-r--r--c++/SConscript37
-rw-r--r--c++/distance/meter.h20
-rw-r--r--c++/time/second.h15
-rw-r--r--c++/unit.h49
-rw-r--r--c++/unit.tmpl.h53
-rw-r--r--c++/unit_cast.h15
-rw-r--r--c++/unit_print.h55
-rw-r--r--c++/unit_reduction.h133
8 files changed, 377 insertions, 0 deletions
diff --git a/c++/SConscript b/c++/SConscript
new file mode 100644
index 0000000..1ee0d39
--- /dev/null
+++ b/c++/SConscript
@@ -0,0 +1,37 @@
+#!/bin/false
+
+import os
+import os.path
+import glob
+
+
+Import('env')
+
+dir_path = Dir('.').abspath
+
+# Environment for base library
+core_env = env.Clone();
+
+core_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
+core_env.headers = sorted(glob.glob(dir_path + "/*.h"))
+core_env.distance_headers = sorted(glob.glob(dir_path + "/distance/*.h"))
+core_env.time_headers = sorted(glob.glob(dir_path + "/time/*.h"))
+
+env.sources += core_env.sources;
+env.headers += core_env.headers;
+
+## Shared lib
+objects_shared = []
+core_env.add_source_files(objects_shared, core_env.sources, shared=True);
+core_env.library_shared = core_env.SharedLibrary('#build/kel-unit', [objects_shared]);
+
+# Set Alias
+env.Alias('library_core', [core_env.library_shared]);
+
+env.targets += ['library_core'];
+
+# Install
+env.Install('$prefix/lib/', [core_env.library_shared]);
+env.Install('$prefix/include/kel/unit', [core_env.headers]);
+env.Install('$prefix/include/kel/unit/distance', [core_env.distance_headers]);
+env.Install('$prefix/include/kel/unit/time', [core_env.time_headers]);
diff --git a/c++/distance/meter.h b/c++/distance/meter.h
new file mode 100644
index 0000000..0d9fb3b
--- /dev/null
+++ b/c++/distance/meter.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "../unit.h"
+
+#include <string_view>
+
+namespace kel {
+namespace unit_type {
+struct meter{
+ static constexpr std::string_view name = "meter";
+ static constexpr std::string_view short_name = "m";
+};
+}
+
+template<typename S>
+using meter = unit<S,unit_component<unit_type::meter,1>>;
+
+template<typename S>
+using square_meter = unit<S,unit_component<unit_type::meter,2>>;
+}
diff --git a/c++/time/second.h b/c++/time/second.h
new file mode 100644
index 0000000..6dca456
--- /dev/null
+++ b/c++/time/second.h
@@ -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<typename S>
+using second = unit<S,unit_component<unit_type::second,1>>;
+}
diff --git a/c++/unit.h b/c++/unit.h
new file mode 100644
index 0000000..a8e8320
--- /dev/null
+++ b/c++/unit.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "unit_reduction.h"
+
+namespace kel {
+template<typename UnitType, int64_t Exponent>
+struct unit_component {};
+
+template<typename StorageT, typename... T>
+class unit;
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+class unit<StorageT, unit_component<UnitTypes, Exponents>...> {
+public:
+ using value_type = StorageT;
+
+ unit() = default;
+
+ unit(const unit<StorageT,unit_component<UnitTypes, Exponents>...>&) = default;
+ unit(unit<StorageT,unit_component<UnitTypes,Exponents>...>&&) = default;
+
+ unit<StorageT,unit_component<UnitTypes,Exponents>...>& operator=(const unit<StorageT,unit_component<UnitTypes,Exponents>...>&) = default;
+ unit<StorageT,unit_component<UnitTypes,Exponents>...>& operator=(unit<StorageT,unit_component<UnitTypes,Exponents>...>&&) = default;
+
+ unit(const value_type&);
+ unit(value_type&&);
+
+ unit<StorageT,unit_component<UnitTypes,Exponents>...>& operator=(const value_type&);
+ unit<StorageT,unit_component<UnitTypes,Exponents>...>& operator=(value_type&&);
+
+ unit<StorageT,unit_component<UnitTypes,Exponents>...> operator+(const unit<StorageT,unit_component<UnitTypes,Exponents>...>& rhs);
+ unit<StorageT,unit_component<UnitTypes,Exponents>...> operator-(const unit<StorageT,unit_component<UnitTypes,Exponents>...>& rhs);
+
+ template<typename... Trhs>
+ typename unit_multiplication<unit<StorageT,unit_component<UnitTypes,Exponents>...>, unit<StorageT,Trhs...>>::type operator*(const unit<StorageT, Trhs...>& rhs);
+
+ template<typename... Trhs>
+ typename unit_multiplication<unit<StorageT, unit_component<UnitTypes,Exponents>...>, typename unit_invert<StorageT,Trhs...>::type>::type operator/(const unit<StorageT, Trhs...>& rhs);
+
+ value_type data() const;
+private:
+ value_type value;
+};
+
+template<typename S>
+using scalar = unit<S>;
+}
+
+#include "unit.tmpl.h"
diff --git a/c++/unit.tmpl.h b/c++/unit.tmpl.h
new file mode 100644
index 0000000..d89e0c1
--- /dev/null
+++ b/c++/unit.tmpl.h
@@ -0,0 +1,53 @@
+#include <utility>
+
+namespace kelun {
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...>::unit(const value_type& value_):
+ value{value_}{}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...>::unit(value_type&& value_):value{std::move(value_)}{}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...>& unit<StorageT,unit_component<UnitTypes, Exponents>...>::operator=(const typename unit<StorageT,unit_component<UnitTypes, Exponents>...>::value_type& value_){
+ value = value_;
+ return *this;
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...>& unit<StorageT,unit_component<UnitTypes, Exponents>...>::operator=(typename unit<StorageT,unit_component<UnitTypes, Exponents>...>::value_type&& value_){
+ value = std::move(value_);
+ return *this;
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...> unit<StorageT,unit_component<UnitTypes, Exponents>...>::operator+(const unit<StorageT,unit_component<UnitTypes, Exponents>...>& rhs){
+ return value + rhs.value;
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+unit<StorageT,unit_component<UnitTypes, Exponents>...> unit<StorageT,unit_component<UnitTypes, Exponents>...>::operator-(const unit<StorageT,unit_component<UnitTypes, Exponents>...>& rhs){
+ return value - rhs.value;
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+template<typename... Trhs>
+typename unit_multiplication<unit<StorageT,unit_component<UnitTypes,Exponents>...>, unit<StorageT, Trhs...>>::type
+unit<StorageT,unit_component<UnitTypes, Exponents>...>::operator*(const unit<StorageT,Trhs...>& rhs){
+ return value * rhs.data();
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+template<typename... Trhs>
+typename unit_multiplication<unit<StorageT,unit_component<UnitTypes,Exponents>...>, typename unit_invert<StorageT,Trhs...>::type>::type
+unit<StorageT,unit_component<UnitTypes,Exponents>...>::operator/(const unit<StorageT, Trhs...>& rhs){
+ typename unit_invert<StorageT, Trhs...>::type rhs_inverted{static_cast<StorageT>(1)/rhs.data()};
+ return value * rhs_inverted.data();
+}
+
+template<typename StorageT, typename... UnitTypes, int64_t... Exponents>
+typename unit<StorageT,unit_component<UnitTypes, Exponents>...>::value_type unit<StorageT,unit_component<UnitTypes, Exponents>...>::data() const {
+ return value;
+}
+}
diff --git a/c++/unit_cast.h b/c++/unit_cast.h
new file mode 100644
index 0000000..8dc2689
--- /dev/null
+++ b/c++/unit_cast.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <forstio/core/common.h>
+
+namespace kel {
+template<typename S, typename From, typename To>
+class unit_convert {
+ static_assert(always_false<S, From, To>, "Units can't be converted to each other");
+};
+
+template<typename Store, typename Same>
+class unit_convert<Store, Same, Same> {
+ static constexpr factor = static_cast<Store>(1);
+};
+}
diff --git a/c++/unit_print.h b/c++/unit_print.h
new file mode 100644
index 0000000..0f3cb72
--- /dev/null
+++ b/c++/unit_print.h
@@ -0,0 +1,55 @@
+#include "./unit.h"
+
+#include <iostream>
+
+
+namespace std {
+template<typename UnitT, int64_t UnitE>
+inline ostream& operator<<(ostream& o, const kelun::unit_base<UnitT,UnitE>& ele){
+ o<<UnitT::short_name;
+ if constexpr ( UnitE != 1 ){
+ o<<'^'<<'('<<UnitE<<')';
+ }
+ return o;
+}
+}
+
+namespace kelun {
+template<typename... T>
+struct unit_print_impl {
+ static_assert(is_always_false<T...>, "Template type not supported");
+};
+
+template<typename UnitT, int64_t UnitE, typename... UnitTL, int64_t... UnitEL>
+struct unit_print_impl<unit_base<UnitT,UnitE>,unit_base<UnitTL,UnitEL>...> {
+ static std::ostream& print(std::ostream& o){
+
+ unit_base<UnitT,UnitE> element;
+
+ std::ostream& o_ret = o << element;
+
+ if constexpr (sizeof...(UnitTL) > 0){
+ std::ostream& o_ret_next = o_ret << ' ' << '*' << ' ';
+ return unit_print_impl<unit_base<UnitTL,UnitEL>...>::print(o_ret_next);
+ }
+
+ return o_ret<<']';
+ }
+};
+}
+
+namespace std {
+
+template<typename StorageT, typename... T>
+inline ostream& operator<<(ostream& o, const kelun::unit<StorageT,T...>& unit);
+
+template<typename StorageT, typename... UnitT, int64_t... UnitE>
+inline ostream& operator<<(ostream& o, const kelun::unit<StorageT,kelun::unit_base<UnitT,UnitE>...>& unit){
+ o << unit.data();
+ if constexpr (sizeof...(UnitT) > 0) {
+ auto& o_ret = o << ' '<<'[';
+ return kelun::unit_print_impl<kelun::unit_base<UnitT,UnitE>...>::print(o_ret);
+ }
+ return o;
+}
+}
diff --git a/c++/unit_reduction.h b/c++/unit_reduction.h
new file mode 100644
index 0000000..d9060d2
--- /dev/null
+++ b/c++/unit_reduction.h
@@ -0,0 +1,133 @@
+#pragma once
+
+#include <cstdint>
+#include <type_traits>
+
+namespace kelun {
+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;
+};
+}