diff --git a/src/include/units/dimension.h b/src/include/units/dimension.h index 31eaf8bb..47039cae 100644 --- a/src/include/units/dimension.h +++ b/src/include/units/dimension.h @@ -27,23 +27,42 @@ namespace std::experimental::units { - // dim_id + struct base_dimension { + const char* name; + }; - template - using dim_id = std::integral_constant; + constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs) + { + const char* p1 = lhs.name; + const char* p2 = rhs.name; + for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { + if(*p1 != *p2) return false; + } + return *p1 == *p2; + } - // dim_id_less + constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs) + { + const char* p1 = lhs.name; + const char* p2 = rhs.name; + for(; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { + if(*p1 < *p2) return true; + if(*p2 < *p1) return false; + } + return (*p1 == '\0') && (*p2 != '\0'); + } - template - struct dim_id_less : std::bool_constant { + // base_dimension_less + + template + struct base_dimension_less : std::bool_constant { }; // exp - template // todo: to be replaced with fixed_string when supported by the compilers - // template + template struct exp { - using dimension = BaseDimension; + static constexpr const base_dimension& dimension = BaseDimension; static constexpr int value = Value; }; @@ -52,8 +71,8 @@ namespace std::experimental::units { template inline constexpr bool is_exp = false; - template - inline constexpr bool is_exp> = true; + template + inline constexpr bool is_exp> = true; } // namespace detail template @@ -62,7 +81,7 @@ namespace std::experimental::units { // exp_dim_id_less template - struct exp_dim_id_less : dim_id_less { + struct exp_less : base_dimension_less { }; // exp_invert @@ -70,7 +89,7 @@ namespace std::experimental::units { template struct exp_invert; - template + template struct exp_invert> { using type = exp; }; @@ -138,7 +157,7 @@ namespace std::experimental::units { using type = conditional>, dimension, type_list_push_front>; }; - template + template struct dim_consolidate, exp, ERest...>> { using type = conditional>, dim_consolidate_t, ERest...>>>; @@ -148,7 +167,7 @@ namespace std::experimental::units { template struct make_dimension { - using type = detail::dim_consolidate_t, exp_dim_id_less>>; + using type = detail::dim_consolidate_t, exp_less>>; }; template @@ -156,7 +175,7 @@ namespace std::experimental::units { template struct merge_dimension { - using type = detail::dim_consolidate_t>; + using type = detail::dim_consolidate_t>; }; template diff --git a/src/include/units/base_dimensions.h b/src/include/units/dimensions/base_dimensions.h similarity index 73% rename from src/include/units/base_dimensions.h rename to src/include/units/dimensions/base_dimensions.h index 2d71c329..6b6db449 100644 --- a/src/include/units/base_dimensions.h +++ b/src/include/units/dimensions/base_dimensions.h @@ -26,14 +26,12 @@ namespace std::experimental::units { - // todo: to be replaced with fixed_string when supported by the compilers - - struct base_dim_length : dim_id<0> {}; - struct base_dim_mass : dim_id<1> {}; - struct base_dim_time : dim_id<2> {}; - struct base_dim_current : dim_id<3> {}; - struct base_dim_temperature : dim_id<4> {}; - struct base_dim_substance : dim_id<5> {}; - struct base_dim_luminous_intensity : dim_id<6> {}; + inline constexpr base_dimension base_dim_length{"length"}; + inline constexpr base_dimension base_dim_mass{"mass"}; + inline constexpr base_dimension base_dim_time{"time"}; + inline constexpr base_dimension base_dim_current{"current"}; + inline constexpr base_dimension base_dim_temperature{"temperature"}; + inline constexpr base_dimension base_dim_substance{"substance"}; + inline constexpr base_dimension base_dim_luminous_intensity{"luminous intensity"}; } // namespace std::experimental::units diff --git a/src/include/units/dimensions/capacitance.h b/src/include/units/dimensions/capacitance.h index 51b7a457..cf77b7ac 100644 --- a/src/include/units/dimensions/capacitance.h +++ b/src/include/units/dimensions/capacitance.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include diff --git a/src/include/units/dimensions/current.h b/src/include/units/dimensions/current.h index 101e678a..db9b02d9 100644 --- a/src/include/units/dimensions/current.h +++ b/src/include/units/dimensions/current.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/electric_charge.h b/src/include/units/dimensions/electric_charge.h index eb0ac89a..fdcfb626 100644 --- a/src/include/units/dimensions/electric_charge.h +++ b/src/include/units/dimensions/electric_charge.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include diff --git a/src/include/units/dimensions/energy.h b/src/include/units/dimensions/energy.h index be491c5c..bf381f39 100644 --- a/src/include/units/dimensions/energy.h +++ b/src/include/units/dimensions/energy.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include diff --git a/src/include/units/dimensions/force.h b/src/include/units/dimensions/force.h index e431ef94..153fcdec 100644 --- a/src/include/units/dimensions/force.h +++ b/src/include/units/dimensions/force.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include diff --git a/src/include/units/dimensions/frequency.h b/src/include/units/dimensions/frequency.h index bca18c2a..b8853672 100644 --- a/src/include/units/dimensions/frequency.h +++ b/src/include/units/dimensions/frequency.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/length.h b/src/include/units/dimensions/length.h index d9d8dff8..6cf457fd 100644 --- a/src/include/units/dimensions/length.h +++ b/src/include/units/dimensions/length.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/luminous_intensity.h b/src/include/units/dimensions/luminous_intensity.h index 2cf74bfb..47717ebb 100644 --- a/src/include/units/dimensions/luminous_intensity.h +++ b/src/include/units/dimensions/luminous_intensity.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/mass.h b/src/include/units/dimensions/mass.h index bd9e8690..c3bb12cd 100644 --- a/src/include/units/dimensions/mass.h +++ b/src/include/units/dimensions/mass.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/power.h b/src/include/units/dimensions/power.h index 0423e17d..a461c3b2 100644 --- a/src/include/units/dimensions/power.h +++ b/src/include/units/dimensions/power.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/pressure.h b/src/include/units/dimensions/pressure.h index 70dcb0e6..e2f7ffff 100644 --- a/src/include/units/dimensions/pressure.h +++ b/src/include/units/dimensions/pressure.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/substance.h b/src/include/units/dimensions/substance.h index 203885cd..eca2fa1e 100644 --- a/src/include/units/dimensions/substance.h +++ b/src/include/units/dimensions/substance.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/temperature.h b/src/include/units/dimensions/temperature.h index 544eba4c..a41f7e88 100644 --- a/src/include/units/dimensions/temperature.h +++ b/src/include/units/dimensions/temperature.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/time.h b/src/include/units/dimensions/time.h index d2ace8c4..d1f53f1c 100644 --- a/src/include/units/dimensions/time.h +++ b/src/include/units/dimensions/time.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace std::experimental::units { diff --git a/src/include/units/dimensions/voltage.h b/src/include/units/dimensions/voltage.h index ffb4bf08..3dd92d71 100644 --- a/src/include/units/dimensions/voltage.h +++ b/src/include/units/dimensions/voltage.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include diff --git a/src/include/units/unit.h b/src/include/units/unit.h index 30561d61..755ddab3 100644 --- a/src/include/units/unit.h +++ b/src/include/units/unit.h @@ -63,18 +63,18 @@ namespace std::experimental::units { template struct get_unit_base_dim> { static_assert(sizeof...(Rest) == 0, "Base unit expected"); - using dimension = E::dimension; + static constexpr const base_dimension& dimension = E::dimension; }; - template + template struct get_ratio { using ratio = ::std::experimental::units::ratio<1>; }; - template + template struct get_ratio { - using unit_base_dim = get_unit_base_dim::dimension; - using ratio = conditional::dimension; + using ratio = conditional<&unit_base_dim == &BaseDimension, typename U::ratio, typename get_ratio::ratio>; }; @@ -105,7 +105,7 @@ namespace std::experimental::units { template struct derived_ratio, Us...> { using rest_ratio = derived_ratio, Us...>::ratio; - using e_ratio = get_ratio::ratio; + using e_ratio = get_ratio::ratio; using ratio = ratio_op::ratio; }; diff --git a/test/unit_test/test_dimension.cpp b/test/unit_test/test_dimension.cpp index 8b637224..8f4bb9bb 100644 --- a/test/unit_test/test_dimension.cpp +++ b/test/unit_test/test_dimension.cpp @@ -27,46 +27,48 @@ using namespace std::experimental::units; namespace { - template - using e = exp, Value>; + inline constexpr base_dimension d0{"d0"}; + inline constexpr base_dimension d1{"d1"}; + inline constexpr base_dimension d2{"d2"}; + inline constexpr base_dimension d3{"d3"}; // exp_invert - static_assert(std::is_same_v>, e<0, -1>>); - static_assert(std::is_same_v>, e<1, 1>>); + static_assert(std::is_same_v>, exp>); + static_assert(std::is_same_v>, exp>); // make_dimension - static_assert(std::is_same_v>, dimension>>); - static_assert(std::is_same_v, e<1, 1>>, dimension, e<1, 1>>>); - static_assert(std::is_same_v, e<0, 1>>, dimension, e<1, 1>>>); - static_assert(std::is_same_v, e<1, 1>>, dimension>>); - static_assert(std::is_same_v, e<1, -1>>, dimension<>>); + static_assert(std::is_same_v>, dimension>>); + static_assert(std::is_same_v, exp>, dimension, exp>>); + static_assert(std::is_same_v, exp>, dimension, exp>>); + static_assert(std::is_same_v, exp>, dimension>>); + static_assert(std::is_same_v, exp>, dimension<>>); - static_assert(std::is_same_v, e<1, 1>, e<0, 1>, e<1, 1>>, dimension, e<1, 2>>>); + static_assert(std::is_same_v, exp, exp, exp>, dimension, exp>>); static_assert( - std::is_same_v, e<1, -1>, e<0, -1>, e<1, -1>>, dimension, e<1, -2>>>); + std::is_same_v, exp, exp, exp>, dimension, exp>>); - static_assert(std::is_same_v, e<1, 1>, e<1, -1>>, dimension>>); - static_assert(std::is_same_v, e<0, -1>, e<1, 1>>, dimension>>); - static_assert(std::is_same_v, e<1, 1>, e<0, -1>>, dimension>>); - static_assert(std::is_same_v, e<1, 1>, e<0, -1>, e<1, -1>>, dimension<>>); + static_assert(std::is_same_v, exp, exp>, dimension>>); + static_assert(std::is_same_v, exp, exp>, dimension>>); + static_assert(std::is_same_v, exp, exp>, dimension>>); + static_assert(std::is_same_v, exp, exp, exp>, dimension<>>); // dimension_multiply static_assert( - std::is_same_v>, dimension>>, dimension, e<1, 1>>>); - static_assert(std::is_same_v, e<1, 1>, e<2, 1>>, dimension>>, - dimension, e<1, 1>, e<2, 1>, e<3, 1>>>); - static_assert(std::is_same_v, e<1, 1>, e<2, 1>>, dimension>>, - dimension, e<1, 2>, e<2, 1>>>); - static_assert(std::is_same_v, e<1, 1>, e<2, 1>>, dimension>>, - dimension, e<2, 1>>>); + std::is_same_v>, dimension>>, dimension, exp>>); + static_assert(std::is_same_v, exp, exp>, dimension>>, + dimension, exp, exp, exp>>); + static_assert(std::is_same_v, exp, exp>, dimension>>, + dimension, exp, exp>>); + static_assert(std::is_same_v, exp, exp>, dimension>>, + dimension, exp>>); // dimension_divide static_assert( - std::is_same_v>, dimension>>, dimension, e<1, -1>>>); - static_assert(std::is_same_v>, dimension>>, dimension<>>); + std::is_same_v>, dimension>>, dimension, exp>>); + static_assert(std::is_same_v>, dimension>>, dimension<>>); } // namespace diff --git a/test/unit_test/test_type_list.cpp b/test/unit_test/test_type_list.cpp index 2c6cd240..ccf688a4 100644 --- a/test/unit_test/test_type_list.cpp +++ b/test/unit_test/test_type_list.cpp @@ -82,41 +82,21 @@ namespace { std::is_same_v>::second_list, type_list>); // type_list_merge_sorted + inline constexpr base_dimension d0{"d0"}; + inline constexpr base_dimension d1{"d1"}; - static_assert(std::is_same_v>, type_list>, dim_id_less>, - type_list, dim_id<1>>>); - static_assert(std::is_same_v>, type_list>, dim_id_less>, - type_list, dim_id<1>>>); - - static_assert(std::is_same_v, dim_id<38>>, - type_list, dim_id<43>>, dim_id_less>, - type_list, dim_id<27>, dim_id<38>, dim_id<43>>>); - static_assert( - std::is_same_v, dim_id<82>>, type_list>, dim_id_less>, - type_list, dim_id<10>, dim_id<82>>>); + static_assert(std::is_same_v>, type_list>, exp_less>, + type_list, exp>>); + static_assert(std::is_same_v>, type_list>, exp_less>, + type_list, exp>>); // type_list_sort template - using dim_sort_t = type_list_sort; + using exp_sort_t = type_list_sort; - static_assert(std::is_same_v>>, type_list>>); - static_assert(std::is_same_v, dim_id<1>>>, type_list, dim_id<1>>>); - static_assert(std::is_same_v, dim_id<0>>>, type_list, dim_id<1>>>); - static_assert(std::is_same_v< - dim_sort_t, dim_id<27>, dim_id<43>, dim_id<3>, dim_id<9>, dim_id<82>, dim_id<10>>>, - type_list, dim_id<9>, dim_id<10>, dim_id<27>, dim_id<38>, dim_id<43>, dim_id<82>>>); - - // exp_dim_id_less - - template - using e = exp, Value>; - - template - using exp_sort_t = type_list_sort; - - static_assert(std::is_same_v>>, dimension>>); - static_assert(std::is_same_v, e<1, -1>>>, dimension, e<1, -1>>>); - static_assert(std::is_same_v, e<0, -1>>>, dimension, e<1, 1>>>); + static_assert(std::is_same_v>>, dimension>>); + static_assert(std::is_same_v, exp>>, dimension, exp>>); + static_assert(std::is_same_v, exp>>, dimension, exp>>); } // namespace