diff --git a/src/include/units/bits/tools.h b/src/include/units/bits/tools.h index 3bf4e09e..78235793 100644 --- a/src/include/units/bits/tools.h +++ b/src/include/units/bits/tools.h @@ -26,6 +26,16 @@ #include #include +namespace std { + + template + struct type_identity { using type = T; }; + + template + using type_identity_t = typename type_identity::type; + +} + namespace units { using namespace mp::std_concepts; // todo Remove when std::concepts will arrive diff --git a/src/include/units/dimension.h b/src/include/units/dimension.h index 10dfb44e..e9b4f4b4 100644 --- a/src/include/units/dimension.h +++ b/src/include/units/dimension.h @@ -78,10 +78,18 @@ namespace units { template using exp_invert_t = typename exp_invert::type; + // dimension_traits + + template + struct dimension_traits : std::type_identity {}; + + template + using dimension_traits_t = typename dimension_traits::type; + // dimension template - struct dimension; + struct dimension : std::type_identity> {}; // is_dimension namespace detail { @@ -93,7 +101,20 @@ namespace units { } // namespace detail template - concept bool Dimension = detail::is_dimension; + concept bool Dimension = detail::is_dimension; + + + // dim_invert + + template + struct dim_invert; + + template + struct dim_invert> : std::type_identity...>>> {}; + + template + using dim_invert_t = typename dim_invert::type; + // make_dimension @@ -144,12 +165,10 @@ namespace units { struct dimension_multiply; template - struct dimension_multiply, dimension> { - using type = make_dimension_t; - }; + struct dimension_multiply, dimension> : std::type_identity>> {}; template - using dimension_multiply_t = typename dimension_multiply::type; + using dimension_multiply_t = typename dimension_multiply::type; // dimension_divide @@ -162,6 +181,6 @@ namespace units { }; template - using dimension_divide_t = typename dimension_divide::type; + using dimension_divide_t = typename dimension_divide::type; } // namespace units diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index 9f7a0448..526af801 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -254,14 +254,14 @@ namespace units { return ret(lhs.count() * rhs.count()); } - template - quantity...>, unit...>, std::ratio>, std::common_type_t> + template + quantity, unit, std::ratio>, std::common_type_t> constexpr operator/(const Rep1& v, - const quantity, U, Rep2>& q) + const quantity& q) { - using dim = dimension...>; + using dim = dim_invert_t; using ret = quantity>, std::common_type_t>; - using den = quantity, U, std::common_type_t>; + using den = quantity>; return ret(v / den(q).count()); } diff --git a/src/include/units/si/frequency.h b/src/include/units/si/frequency.h index 0d27b3a1..38276e0a 100644 --- a/src/include/units/si/frequency.h +++ b/src/include/units/si/frequency.h @@ -27,7 +27,6 @@ namespace units { - using dimension_frequency = make_dimension_t>; using millihertz = unit; using hertz = unit>; @@ -35,6 +34,8 @@ namespace units { using megahertz = unit; using gigahertz = unit; using terahertz = unit; + struct dimension_frequency : make_dimension_t> {}; + template<> struct dimension_traits : std::type_identity {}; template using frequency = quantity; diff --git a/src/include/units/si/length.h b/src/include/units/si/length.h index de31b55c..e7bd8de2 100644 --- a/src/include/units/si/length.h +++ b/src/include/units/si/length.h @@ -27,7 +27,8 @@ namespace units { - using dimension_length = make_dimension_t>; + struct dimension_length : make_dimension_t> {}; + template<> struct dimension_traits : std::type_identity {}; using millimeter = unit; using centimeter = unit>; diff --git a/src/include/units/si/time.h b/src/include/units/si/time.h index 41ec3353..e48ed372 100644 --- a/src/include/units/si/time.h +++ b/src/include/units/si/time.h @@ -27,14 +27,15 @@ namespace units { - using dimension_time = make_dimension_t>; - using nanosecond = unit; using microsecond = unit; using millisecond = unit; using second = unit>; using minute = unit>; using hour = unit>; + struct dimension_time : make_dimension_t> {}; + template<> struct dimension_traits : std::type_identity {}; + template using time = quantity; diff --git a/src/include/units/si/velocity.h b/src/include/units/si/velocity.h index adb6ca67..d8c85172 100644 --- a/src/include/units/si/velocity.h +++ b/src/include/units/si/velocity.h @@ -28,7 +28,8 @@ namespace units { - using dimension_velocity = make_dimension_t, exp>; + struct dimension_velocity : make_dimension_t, exp> {}; + template<> struct dimension_traits : std::type_identity {}; using meter_per_second = unit>; using kilometer_per_hour = unit>;