From 03a22cba2aa794f70fc4b9c9a629f50628b2b594 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 18 Jul 2019 23:24:24 +0200 Subject: [PATCH] upcasting renamed to downcasting --- doc/DESIGN.md | 56 +++++++++---------- src/include/units/area.h | 12 ++-- .../units/bits/{upcasting.h => downcasting.h} | 22 ++++---- src/include/units/current.h | 4 +- src/include/units/dimension.h | 10 ++-- src/include/units/frequency.h | 14 ++--- src/include/units/length.h | 18 +++--- src/include/units/luminous_intensity.h | 4 +- src/include/units/mass.h | 6 +- src/include/units/quantity.h | 8 +-- src/include/units/substance.h | 4 +- src/include/units/temperature.h | 4 +- src/include/units/time.h | 14 ++--- src/include/units/unit.h | 4 +- src/include/units/velocity.h | 8 +-- 15 files changed, 94 insertions(+), 94 deletions(-) rename src/include/units/bits/{upcasting.h => downcasting.h} (76%) diff --git a/doc/DESIGN.md b/doc/DESIGN.md index cb6ac186..5c11c2a1 100644 --- a/doc/DESIGN.md +++ b/doc/DESIGN.md @@ -27,7 +27,7 @@ static_assert(10_km / 5_km == 2); ``` -## Requirements +## Approach 1. Safety and performance - strong types @@ -89,7 +89,7 @@ or more base dimensions: ```cpp template -struct dimension : upcast_base> {}; +struct dimension : downcast_base> {}; ``` `units::Dimension` is a Concept that is satisfied by a type that is empty and publicly @@ -99,7 +99,7 @@ derived from `units::dimension` class template: template concept Dimension = std::is_empty_v && - detail::is_dimension>; // exposition only + detail::is_dimension>; // exposition only ``` #### `Exponents` @@ -195,7 +195,7 @@ struct dimension_multiply; template struct dimension_multiply, dimension> { - using type = upcasting_traits_t, dimension>>; + using type = downcasting_traits_t, dimension>>; }; template @@ -219,7 +219,7 @@ struct merge_dimension { ```cpp template requires (R::num > 0) -struct unit : upcast_base> { +struct unit : downcast_base> { using dimension = D; using ratio = R; }; @@ -232,7 +232,7 @@ derived from `units::unit` class template: template concept Unit = std::is_empty_v && - detail::is_unit>; // exposition only + detail::is_unit>; // exposition only ``` ### `Quantities` @@ -268,18 +268,18 @@ public: template requires treat_as_floating_point> || std::ratio_multiply::den == 1 - quantity, upcasting_traits_t, std::ratio_multiply>>, std::common_type_t> + quantity, downcasting_traits_t, std::ratio_multiply>>, std::common_type_t> constexpr operator*(const quantity& lhs, const quantity& rhs); template - quantity, upcasting_traits_t, std::ratio>>, std::common_type_t> + quantity, downcasting_traits_t, std::ratio>>, std::common_type_t> constexpr operator/(const Rep1& v, const quantity& q) [[expects: q != quantity(0)]]; template requires treat_as_floating_point> || std::ratio_divide::den == 1 - quantity, upcasting_traits_t, std::ratio_divide>>, std::common_type_t> + quantity, downcasting_traits_t, std::ratio_divide>>, std::common_type_t> constexpr operator/(const quantity& lhs, const quantity& rhs) [[expects: rhs != quantity(0)]]; }; @@ -300,7 +300,7 @@ operation and provides it directly to `units::common_quantity_t` type trait. To explicitly force truncating conversions `quantity_cast` function is provided which is a direct counterpart of `std::chrono::duration_cast`. -## Strong types instead of aliases, and type upcasting capability +## Strong types instead of aliases, and type downcasting capability Most of the important design decisions in the library are dictated by the requirement of providing the best user experience as possible. @@ -347,7 +347,7 @@ and starts to be really hard to analyze or debug. -That is why it was decided to provide automated upcasting capability when possible. With that the +That is why it was decided to provide automated downcasting capability when possible. With that the same code will result with such an error: ```text @@ -383,33 +383,33 @@ and are not arguably much easier to understand thus provide better user experience. -Upcasting capability is provided through dedicated `upcasting_traits`, a few helper aliases and by -`base_type` member type in `upcast_base` class template. +downcasting capability is provided through dedicated `downcasting_traits`, a few helper aliases and by +`base_type` member type in `downcast_base` class template. ```cpp -template -using upcast_from = T::base_type; +template +using downcast_from = T::base_type; template -using upcast_to = std::type_identity; +using downcast_to = std::type_identity; template -struct upcasting_traits : upcast_to {}; +struct downcasting_traits : downcast_to {}; template -using upcasting_traits_t = upcasting_traits::type; +using downcasting_traits_t = downcasting_traits::type; ``` -With that the upcasting functionality is enabled by: +With that the downcasting functionality is enabled by: ```cpp struct dimension_length : make_dimension_t> {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` ```cpp struct kilometer : unit {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` @@ -417,11 +417,11 @@ template<> struct upcasting_traits> : upcast_to, exp> {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` 2. Provide `quantity` class template partial specialization for new dimension and provide its base type: @@ -438,27 +438,27 @@ template concept Velocity = Quantity && std::Same; ``` -4. Define units and provide upcasting traits for them: +4. Define units and provide downcasting traits for them: - base unit ```cpp struct meter : unit> {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` - units with prefixes ```cpp struct kilometer : kilo {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` - derived units ```cpp struct kilometer_per_hour : derived_unit {}; -template<> struct upcasting_traits> : upcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; ``` 5. Provide user-defined literals for the most important units: @@ -507,7 +507,7 @@ Additionally, it should make the error logs even shorter thus easier to understa 1. Should we ensure that dimension is always a result of `make_dimension`? How to do it? -2. Should we provide strong types and upcasting_traits for `quantity` type? +2. Should we provide strong types and downcasting_traits for `quantity` type? In such a case all the operators have to be provided to a child class. Or maybe use CRTP? diff --git a/src/include/units/area.h b/src/include/units/area.h index 588d75f4..791eea8b 100644 --- a/src/include/units/area.h +++ b/src/include/units/area.h @@ -27,7 +27,7 @@ namespace units { struct dimension_area : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Area = Quantity && std::Same; @@ -36,19 +36,19 @@ namespace units { using area = quantity; struct square_millimeter : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct square_centimeter : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct square_meter : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct square_kilometer : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct square_foot : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/bits/upcasting.h b/src/include/units/bits/downcasting.h similarity index 76% rename from src/include/units/bits/upcasting.h rename to src/include/units/bits/downcasting.h index e2edeedf..b6e89620 100644 --- a/src/include/units/bits/upcasting.h +++ b/src/include/units/bits/downcasting.h @@ -28,27 +28,27 @@ namespace units { template - struct upcast_base { + struct downcast_base { using base_type = BaseType; }; template - concept bool Upcastable = + concept bool Downcastable = requires { typename T::base_type; } && - std::DerivedFrom>; + std::DerivedFrom>; - template - using upcast_from = T::base_type; + template + using downcast_from = T::base_type; - template - using upcast_to = std::type_identity; + template + using downcast_to = std::type_identity; - template - struct upcasting_traits : upcast_to {}; + template + struct downcasting_traits : downcast_to {}; - template - using upcasting_traits_t = upcasting_traits::type; + template + using downcasting_traits_t = downcasting_traits::type; } // namespace units diff --git a/src/include/units/current.h b/src/include/units/current.h index eb989fe3..69e070c3 100644 --- a/src/include/units/current.h +++ b/src/include/units/current.h @@ -28,7 +28,7 @@ namespace units { struct dimension_current : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Current = Quantity && std::Same; @@ -37,7 +37,7 @@ namespace units { using current = quantity; struct ampere : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/dimension.h b/src/include/units/dimension.h index 06ce4649..c27aff4f 100644 --- a/src/include/units/dimension.h +++ b/src/include/units/dimension.h @@ -23,7 +23,7 @@ #pragma once #include -#include +#include namespace units { @@ -81,7 +81,7 @@ namespace units { // dimension template - struct dimension : upcast_base> {}; + struct dimension : downcast_base> {}; // is_dimension namespace detail { @@ -97,7 +97,7 @@ namespace units { template concept bool Dimension = std::is_empty_v && - detail::is_dimension>; + detail::is_dimension>; // dim_invert @@ -106,7 +106,7 @@ namespace units { struct dim_invert; template - struct dim_invert> : std::type_identity...>>> {}; + struct dim_invert> : std::type_identity...>>> {}; template using dim_invert_t = dim_invert::type; @@ -168,7 +168,7 @@ namespace units { struct dimension_multiply; template - struct dimension_multiply, dimension> : std::type_identity, dimension>>> {}; + struct dimension_multiply, dimension> : std::type_identity, dimension>>> {}; template using dimension_multiply_t = dimension_multiply::type; diff --git a/src/include/units/frequency.h b/src/include/units/frequency.h index a8cb6c97..6b262696 100644 --- a/src/include/units/frequency.h +++ b/src/include/units/frequency.h @@ -28,7 +28,7 @@ namespace units { struct dimension_frequency : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Frequency = Quantity && std::Same; @@ -37,22 +37,22 @@ namespace units { using frequency = quantity; struct hertz : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct millihertz : milli {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct kilohertz : kilo {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct megahertz : mega {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct gigahertz : giga {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct terahertz : tera {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/length.h b/src/include/units/length.h index 22fb7a4f..9e366c67 100644 --- a/src/include/units/length.h +++ b/src/include/units/length.h @@ -28,7 +28,7 @@ namespace units { struct dimension_length : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Length = Quantity && std::Same; @@ -38,16 +38,16 @@ namespace units { // SI units struct meter : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct millimeter : milli {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct centimeter : centi {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct kilometer : kilo {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { @@ -71,16 +71,16 @@ namespace units { // US customary units struct yard : unit> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct foot : unit, yard::ratio>> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct inch : unit, foot::ratio>> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct mile : unit, yard::ratio>> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/luminous_intensity.h b/src/include/units/luminous_intensity.h index 3fe05d04..518ef760 100644 --- a/src/include/units/luminous_intensity.h +++ b/src/include/units/luminous_intensity.h @@ -28,7 +28,7 @@ namespace units { struct dimension_luminous_intensity : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool LuminousIntensity = Quantity && std::Same; @@ -37,7 +37,7 @@ namespace units { using luminous_intensity = quantity; struct candela : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/mass.h b/src/include/units/mass.h index 3f458d3c..c7e04493 100644 --- a/src/include/units/mass.h +++ b/src/include/units/mass.h @@ -28,7 +28,7 @@ namespace units { struct dimension_mass : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Mass = Quantity && std::Same; @@ -37,10 +37,10 @@ namespace units { using mass = quantity; struct gram : unit> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct kilogram : kilo {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index 06b73fa5..d79ec59c 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -67,7 +67,7 @@ namespace units { template struct common_quantity, quantity, Rep> { - using type = quantity>>, Rep>; + using type = quantity>>, Rep>; }; template> @@ -284,7 +284,7 @@ namespace units { { using dim = dimension_multiply_t; using common_rep = decltype(lhs.count() * rhs.count()); - using ret = quantity>>, common_rep>; + using ret = quantity>>, common_rep>; return ret(lhs.count() * rhs.count()); } @@ -298,7 +298,7 @@ namespace units { using dim = dim_invert_t; using common_rep = decltype(v / q.count()); - using ret = quantity>>, common_rep>; + using ret = quantity>>, common_rep>; using den = quantity; return ret(v / den(q).count()); } @@ -337,7 +337,7 @@ namespace units { using common_rep = decltype(lhs.count() / rhs.count()); using dim = dimension_divide_t; - using ret = quantity>>, common_rep>; + using ret = quantity>>, common_rep>; return ret(lhs.count() / rhs.count()); } diff --git a/src/include/units/substance.h b/src/include/units/substance.h index 4fe89d84..0239116e 100644 --- a/src/include/units/substance.h +++ b/src/include/units/substance.h @@ -28,7 +28,7 @@ namespace units { struct dimension_substance : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Substance = Quantity && std::Same; @@ -37,7 +37,7 @@ namespace units { using substance = quantity; struct mole : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/temperature.h b/src/include/units/temperature.h index 9191ffd9..0942525d 100644 --- a/src/include/units/temperature.h +++ b/src/include/units/temperature.h @@ -28,7 +28,7 @@ namespace units { struct dimension_temperature : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool ThermodynamicTemperature = Quantity && std::Same; @@ -37,7 +37,7 @@ namespace units { using temperature = quantity; struct kelvin : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/time.h b/src/include/units/time.h index c62eca42..62245a03 100644 --- a/src/include/units/time.h +++ b/src/include/units/time.h @@ -28,7 +28,7 @@ namespace units { struct dimension_time : make_dimension_t> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Time = Quantity && std::Same; @@ -37,22 +37,22 @@ namespace units { using time = quantity; struct second : unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct nanosecond : nano {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct microsecond : micro {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct millisecond : milli {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct minute : unit> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct hour : unit> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals { diff --git a/src/include/units/unit.h b/src/include/units/unit.h index e9ea16db..9b261889 100644 --- a/src/include/units/unit.h +++ b/src/include/units/unit.h @@ -30,7 +30,7 @@ namespace units { template> requires (R::num > 0) - struct unit : upcast_base> { + struct unit : downcast_base> { using dimension = D; using ratio = R; }; @@ -50,7 +50,7 @@ namespace units { template concept bool Unit = std::is_empty_v && - detail::is_unit>; + detail::is_unit>; // derived_unit diff --git a/src/include/units/velocity.h b/src/include/units/velocity.h index fabbf7dd..72e9898d 100644 --- a/src/include/units/velocity.h +++ b/src/include/units/velocity.h @@ -28,7 +28,7 @@ namespace units { struct dimension_velocity : make_dimension_t, exp> {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; template concept bool Velocity = Quantity && std::Same; @@ -37,13 +37,13 @@ namespace units { using velocity = quantity; struct meter_per_second : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct kilometer_per_hour : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; struct mile_per_hour : derived_unit {}; - template<> struct upcasting_traits> : upcast_to {}; + template<> struct downcasting_traits> : downcast_to {}; inline namespace literals {