upcasting renamed to downcasting

This commit is contained in:
Mateusz Pusz
2019-07-18 23:24:24 +02:00
parent 7cbeb35e17
commit 03a22cba2a
15 changed files with 94 additions and 94 deletions

View File

@@ -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<Exponent... Es>
struct dimension : upcast_base<dimension<Es...>> {};
struct dimension : downcast_base<dimension<Es...>> {};
```
`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<typename T>
concept Dimension =
std::is_empty_v<T> &&
detail::is_dimension<upcast_from<T>>; // exposition only
detail::is_dimension<downcast_from<T>>; // exposition only
```
#### `Exponents`
@@ -195,7 +195,7 @@ struct dimension_multiply;
template<Exponent... E1, Exponent... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> {
using type = upcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>;
using type = downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>;
};
template<Dimension D1, Dimension D2>
@@ -219,7 +219,7 @@ struct merge_dimension {
```cpp
template<Dimension D, Ratio R>
requires (R::num > 0)
struct unit : upcast_base<unit<D, R>> {
struct unit : downcast_base<unit<D, R>> {
using dimension = D;
using ratio = R;
};
@@ -232,7 +232,7 @@ derived from `units::unit` class template:
template<typename T>
concept Unit =
std::is_empty_v<T> &&
detail::is_unit<upcast_from<T>>; // exposition only
detail::is_unit<downcast_from<T>>; // exposition only
```
### `Quantities`
@@ -268,18 +268,18 @@ public:
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1
quantity<dimension_multiply_t<D1, D2>, upcasting_traits_t<unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
quantity<dimension_multiply_t<D1, D2>, downcasting_traits_t<unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator*(const quantity<D1, U1, Rep1>& lhs,
const quantity<D2, U2, Rep2>& rhs);
template<Number Rep1, Dimension D, Unit U, Number Rep2>
quantity<dim_invert_t<D>, upcasting_traits_t<unit<dim_invert_t<D>, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>
quantity<dim_invert_t<D>, downcasting_traits_t<unit<dim_invert_t<D>, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator/(const Rep1& v,
const quantity<D, U, Rep2>& q) [[expects: q != quantity<D, U, Rep2>(0)]];
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_divide<typename U1::ratio, typename U2::ratio>::den == 1
quantity<dimension_divide_t<D1, D2>, upcasting_traits_t<unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
quantity<dimension_divide_t<D1, D2>, downcasting_traits_t<unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator/(const quantity<D1, U1, Rep1>& lhs,
const quantity<D2, U2, Rep2>& rhs) [[expects: rhs != quantity<D, U2, Rep2>(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<Upcastable T>
using upcast_from = T::base_type;
template<Downcastable T>
using downcast_from = T::base_type;
template<typename T>
using upcast_to = std::type_identity<T>;
using downcast_to = std::type_identity<T>;
template<typename T>
struct upcasting_traits : upcast_to<T> {};
struct downcasting_traits : downcast_to<T> {};
template<typename T>
using upcasting_traits_t = upcasting_traits<T>::type;
using downcasting_traits_t = downcasting_traits<T>::type;
```
With that the upcasting functionality is enabled by:
With that the downcasting functionality is enabled by:
```cpp
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_length>> : upcast_to<dimension_length> {};
template<> struct downcasting_traits<downcast_from<dimension_length>> : downcast_to<dimension_length> {};
```
```cpp
struct kilometer : unit<dimension_length, std::kilo> {};
template<> struct upcasting_traits<upcast_from<kilometer>> : upcast_to<kilometer> {};
template<> struct downcasting_traits<downcast_from<kilometer>> : downcast_to<kilometer> {};
```
@@ -417,11 +417,11 @@ template<> struct upcasting_traits<upcast_from<kilometer>> : upcast_to<kilometer
In order to extend the library with custom dimensions the user has to:
1. Create a new dimension type with the recipe of how to construct it from base dimensions and provide
upcasting trait for it:
downcasting trait for it:
```cpp
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
template<> struct upcasting_traits<upcast_from<dimension_velocity>> : upcast_to<dimension_velocity> {};
template<> struct downcasting_traits<downcast_from<dimension_velocity>> : downcast_to<dimension_velocity> {};
```
2. Provide `quantity` class template partial specialization for new dimension and provide its base type:
@@ -438,27 +438,27 @@ template<typename T>
concept Velocity = Quantity<T> && std::Same<typename T::dimension, dimension_velocity>;
```
4. Define units and provide upcasting traits for them:
4. Define units and provide downcasting traits for them:
- base unit
```cpp
struct meter : unit<dimension_length, std::ratio<1>> {};
template<> struct upcasting_traits<upcast_from<meter>> : upcast_to<meter> {};
template<> struct downcasting_traits<downcast_from<meter>> : downcast_to<meter> {};
```
- units with prefixes
```cpp
struct kilometer : kilo<meter> {};
template<> struct upcasting_traits<upcast_from<kilometer>> : upcast_to<kilometer> {};
template<> struct downcasting_traits<downcast_from<kilometer>> : downcast_to<kilometer> {};
```
- derived units
```cpp
struct kilometer_per_hour : derived_unit<dimension_velocity, kilometer, hour> {};
template<> struct upcasting_traits<upcast_from<kilometer_per_hour>> : upcast_to<kilometer_per_hour> {};
template<> struct downcasting_traits<downcast_from<kilometer_per_hour>> : downcast_to<kilometer_per_hour> {};
```
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?

View File

@@ -27,7 +27,7 @@
namespace units {
struct dimension_area : make_dimension_t<exp<base_dim_length, 2>> {};
template<> struct upcasting_traits<upcast_from<dimension_area>> : upcast_to<dimension_area> {};
template<> struct downcasting_traits<downcast_from<dimension_area>> : downcast_to<dimension_area> {};
template<typename T>
concept bool Area = Quantity<T> && std::Same<typename T::dimension, dimension_area>;
@@ -36,19 +36,19 @@ namespace units {
using area = quantity<dimension_area, U, Rep>;
struct square_millimeter : derived_unit<dimension_area, millimeter> {};
template<> struct upcasting_traits<upcast_from<square_millimeter>> : upcast_to<square_millimeter> {};
template<> struct downcasting_traits<downcast_from<square_millimeter>> : downcast_to<square_millimeter> {};
struct square_centimeter : derived_unit<dimension_area, centimeter> {};
template<> struct upcasting_traits<upcast_from<square_centimeter>> : upcast_to<square_centimeter> {};
template<> struct downcasting_traits<downcast_from<square_centimeter>> : downcast_to<square_centimeter> {};
struct square_meter : derived_unit<dimension_area, meter> {};
template<> struct upcasting_traits<upcast_from<square_meter>> : upcast_to<square_meter> {};
template<> struct downcasting_traits<downcast_from<square_meter>> : downcast_to<square_meter> {};
struct square_kilometer : derived_unit<dimension_area, kilometer, meter> {};
template<> struct upcasting_traits<upcast_from<square_kilometer>> : upcast_to<square_kilometer> {};
template<> struct downcasting_traits<downcast_from<square_kilometer>> : downcast_to<square_kilometer> {};
struct square_foot : derived_unit<dimension_area, foot> {};
template<> struct upcasting_traits<upcast_from<square_foot>> : upcast_to<square_foot> {};
template<> struct downcasting_traits<downcast_from<square_foot>> : downcast_to<square_foot> {};
inline namespace literals {

View File

@@ -28,27 +28,27 @@
namespace units {
template<typename BaseType>
struct upcast_base {
struct downcast_base {
using base_type = BaseType;
};
template<typename T>
concept bool Upcastable =
concept bool Downcastable =
requires {
typename T::base_type;
} &&
std::DerivedFrom<T, upcast_base<typename T::base_type>>;
std::DerivedFrom<T, downcast_base<typename T::base_type>>;
template<Upcastable T>
using upcast_from = T::base_type;
template<Downcastable T>
using downcast_from = T::base_type;
template<Upcastable T>
using upcast_to = std::type_identity<T>;
template<Downcastable T>
using downcast_to = std::type_identity<T>;
template<Upcastable T>
struct upcasting_traits : upcast_to<T> {};
template<Downcastable T>
struct downcasting_traits : downcast_to<T> {};
template<Upcastable T>
using upcasting_traits_t = upcasting_traits<T>::type;
template<Downcastable T>
using downcasting_traits_t = downcasting_traits<T>::type;
} // namespace units

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_current : make_dimension_t<exp<base_dim_current, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_current>> : upcast_to<dimension_current> {};
template<> struct downcasting_traits<downcast_from<dimension_current>> : downcast_to<dimension_current> {};
template<typename T>
concept bool Current = Quantity<T> && std::Same<typename T::dimension, dimension_current>;
@@ -37,7 +37,7 @@ namespace units {
using current = quantity<dimension_current, U, Rep>;
struct ampere : unit<dimension_current> {};
template<> struct upcasting_traits<upcast_from<ampere>> : upcast_to<ampere> {};
template<> struct downcasting_traits<downcast_from<ampere>> : downcast_to<ampere> {};
inline namespace literals {

View File

@@ -23,7 +23,7 @@
#pragma once
#include <units/bits/type_list.h>
#include <units/bits/upcasting.h>
#include <units/bits/downcasting.h>
namespace units {
@@ -81,7 +81,7 @@ namespace units {
// dimension
template<Exponent... Es>
struct dimension : upcast_base<dimension<Es...>> {};
struct dimension : downcast_base<dimension<Es...>> {};
// is_dimension
namespace detail {
@@ -97,7 +97,7 @@ namespace units {
template<typename T>
concept bool Dimension =
std::is_empty_v<T> &&
detail::is_dimension<upcast_from<T>>;
detail::is_dimension<downcast_from<T>>;
// dim_invert
@@ -106,7 +106,7 @@ namespace units {
struct dim_invert;
template<Exponent... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<upcasting_traits_t<dimension<exp_invert_t<Es>...>>> {};
struct dim_invert<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_invert_t<Es>...>>> {};
template<Dimension D>
using dim_invert_t = dim_invert<typename D::base_type>::type;
@@ -168,7 +168,7 @@ namespace units {
struct dimension_multiply;
template<Exponent... E1, Exponent... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<upcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<Dimension D1, Dimension D2>
using dimension_multiply_t = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_frequency : make_dimension_t<exp<base_dim_time, -1>> {};
template<> struct upcasting_traits<upcast_from<dimension_frequency>> : upcast_to<dimension_frequency> {};
template<> struct downcasting_traits<downcast_from<dimension_frequency>> : downcast_to<dimension_frequency> {};
template<typename T>
concept bool Frequency = Quantity<T> && std::Same<typename T::dimension, dimension_frequency>;
@@ -37,22 +37,22 @@ namespace units {
using frequency = quantity<dimension_frequency, U, Rep>;
struct hertz : derived_unit<dimension_frequency, second> {};
template<> struct upcasting_traits<upcast_from<hertz>> : upcast_to<hertz> {};
template<> struct downcasting_traits<downcast_from<hertz>> : downcast_to<hertz> {};
struct millihertz : milli<hertz> {};
template<> struct upcasting_traits<upcast_from<millihertz>> : upcast_to<millihertz> {};
template<> struct downcasting_traits<downcast_from<millihertz>> : downcast_to<millihertz> {};
struct kilohertz : kilo<hertz> {};
template<> struct upcasting_traits<upcast_from<kilohertz>> : upcast_to<kilohertz> {};
template<> struct downcasting_traits<downcast_from<kilohertz>> : downcast_to<kilohertz> {};
struct megahertz : mega<hertz> {};
template<> struct upcasting_traits<upcast_from<megahertz>> : upcast_to<megahertz> {};
template<> struct downcasting_traits<downcast_from<megahertz>> : downcast_to<megahertz> {};
struct gigahertz : giga<hertz> {};
template<> struct upcasting_traits<upcast_from<gigahertz>> : upcast_to<gigahertz> {};
template<> struct downcasting_traits<downcast_from<gigahertz>> : downcast_to<gigahertz> {};
struct terahertz : tera<hertz> {};
template<> struct upcasting_traits<upcast_from<terahertz>> : upcast_to<terahertz> {};
template<> struct downcasting_traits<downcast_from<terahertz>> : downcast_to<terahertz> {};
inline namespace literals {

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_length>> : upcast_to<dimension_length> {};
template<> struct downcasting_traits<downcast_from<dimension_length>> : downcast_to<dimension_length> {};
template<typename T>
concept bool Length = Quantity<T> && std::Same<typename T::dimension, dimension_length>;
@@ -38,16 +38,16 @@ namespace units {
// SI units
struct meter : unit<dimension_length> {};
template<> struct upcasting_traits<upcast_from<meter>> : upcast_to<meter> {};
template<> struct downcasting_traits<downcast_from<meter>> : downcast_to<meter> {};
struct millimeter : milli<meter> {};
template<> struct upcasting_traits<upcast_from<millimeter>> : upcast_to<millimeter> {};
template<> struct downcasting_traits<downcast_from<millimeter>> : downcast_to<millimeter> {};
struct centimeter : centi<meter> {};
template<> struct upcasting_traits<upcast_from<centimeter>> : upcast_to<centimeter> {};
template<> struct downcasting_traits<downcast_from<centimeter>> : downcast_to<centimeter> {};
struct kilometer : kilo<meter> {};
template<> struct upcasting_traits<upcast_from<kilometer>> : upcast_to<kilometer> {};
template<> struct downcasting_traits<downcast_from<kilometer>> : downcast_to<kilometer> {};
inline namespace literals {
@@ -71,16 +71,16 @@ namespace units {
// US customary units
struct yard : unit<dimension_length, ratio<9'144, 10'000>> {};
template<> struct upcasting_traits<upcast_from<yard>> : upcast_to<yard> {};
template<> struct downcasting_traits<downcast_from<yard>> : downcast_to<yard> {};
struct foot : unit<dimension_length, ratio_multiply<ratio<1, 3>, yard::ratio>> {};
template<> struct upcasting_traits<upcast_from<foot>> : upcast_to<foot> {};
template<> struct downcasting_traits<downcast_from<foot>> : downcast_to<foot> {};
struct inch : unit<dimension_length, ratio_multiply<ratio<1, 12>, foot::ratio>> {};
template<> struct upcasting_traits<upcast_from<inch>> : upcast_to<inch> {};
template<> struct downcasting_traits<downcast_from<inch>> : downcast_to<inch> {};
struct mile : unit<dimension_length, ratio_multiply<ratio<1'760>, yard::ratio>> {};
template<> struct upcasting_traits<upcast_from<mile>> : upcast_to<mile> {};
template<> struct downcasting_traits<downcast_from<mile>> : downcast_to<mile> {};
inline namespace literals {

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_luminous_intensity : make_dimension_t<exp<base_dim_luminous_intensity, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_luminous_intensity>> : upcast_to<dimension_luminous_intensity> {};
template<> struct downcasting_traits<downcast_from<dimension_luminous_intensity>> : downcast_to<dimension_luminous_intensity> {};
template<typename T>
concept bool LuminousIntensity = Quantity<T> && std::Same<typename T::dimension, dimension_luminous_intensity>;
@@ -37,7 +37,7 @@ namespace units {
using luminous_intensity = quantity<dimension_luminous_intensity, U, Rep>;
struct candela : unit<dimension_luminous_intensity> {};
template<> struct upcasting_traits<upcast_from<candela>> : upcast_to<candela> {};
template<> struct downcasting_traits<downcast_from<candela>> : downcast_to<candela> {};
inline namespace literals {

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_mass : make_dimension_t<exp<base_dim_mass, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_mass>> : upcast_to<dimension_mass> {};
template<> struct downcasting_traits<downcast_from<dimension_mass>> : downcast_to<dimension_mass> {};
template<typename T>
concept bool Mass = Quantity<T> && std::Same<typename T::dimension, dimension_mass>;
@@ -37,10 +37,10 @@ namespace units {
using mass = quantity<dimension_mass, U, Rep>;
struct gram : unit<dimension_mass, ratio<1, 1000>> {};
template<> struct upcasting_traits<upcast_from<gram>> : upcast_to<gram> {};
template<> struct downcasting_traits<downcast_from<gram>> : downcast_to<gram> {};
struct kilogram : kilo<gram> {};
template<> struct upcasting_traits<upcast_from<kilogram>> : upcast_to<kilogram> {};
template<> struct downcasting_traits<downcast_from<kilogram>> : downcast_to<kilogram> {};
inline namespace literals {

View File

@@ -67,7 +67,7 @@ namespace units {
template<Dimension D, Unit U1, Scalar Rep1, Unit U2, Scalar Rep2, Scalar Rep>
struct common_quantity<quantity<D, U1, Rep1>, quantity<D, U2, Rep2>, Rep> {
using type = quantity<D, upcasting_traits_t<unit<D, common_ratio<typename U1::ratio, typename U2::ratio>>>, Rep>;
using type = quantity<D, downcasting_traits_t<unit<D, common_ratio<typename U1::ratio, typename U2::ratio>>>, Rep>;
};
template<Quantity Q1, Quantity Q2, Scalar Rep = std::common_type_t<typename Q1::rep, typename Q2::rep>>
@@ -284,7 +284,7 @@ namespace units {
{
using dim = dimension_multiply_t<D1, D2>;
using common_rep = decltype(lhs.count() * rhs.count());
using ret = quantity<dim, upcasting_traits_t<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
using ret = quantity<dim, downcasting_traits_t<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
return ret(lhs.count() * rhs.count());
}
@@ -298,7 +298,7 @@ namespace units {
using dim = dim_invert_t<D>;
using common_rep = decltype(v / q.count());
using ret = quantity<dim, upcasting_traits_t<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
using ret = quantity<dim, downcasting_traits_t<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
using den = quantity<D, U, common_rep>;
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<D1, D2>;
using ret = quantity<dim, upcasting_traits_t<unit<dim, ratio_divide<typename U1::ratio, typename U2::ratio>>>, common_rep>;
using ret = quantity<dim, downcasting_traits_t<unit<dim, ratio_divide<typename U1::ratio, typename U2::ratio>>>, common_rep>;
return ret(lhs.count() / rhs.count());
}

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_substance : make_dimension_t<exp<base_dim_substance, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_substance>> : upcast_to<dimension_substance> {};
template<> struct downcasting_traits<downcast_from<dimension_substance>> : downcast_to<dimension_substance> {};
template<typename T>
concept bool Substance = Quantity<T> && std::Same<typename T::dimension, dimension_substance>;
@@ -37,7 +37,7 @@ namespace units {
using substance = quantity<dimension_substance, U, Rep>;
struct mole : unit<dimension_substance> {};
template<> struct upcasting_traits<upcast_from<mole>> : upcast_to<mole> {};
template<> struct downcasting_traits<downcast_from<mole>> : downcast_to<mole> {};
inline namespace literals {

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_temperature : make_dimension_t<exp<base_dim_temperature, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_temperature>> : upcast_to<dimension_temperature> {};
template<> struct downcasting_traits<downcast_from<dimension_temperature>> : downcast_to<dimension_temperature> {};
template<typename T>
concept bool ThermodynamicTemperature = Quantity<T> && std::Same<typename T::dimension, dimension_temperature>;
@@ -37,7 +37,7 @@ namespace units {
using temperature = quantity<dimension_temperature, U, Rep>;
struct kelvin : unit<dimension_temperature> {};
template<> struct upcasting_traits<upcast_from<kelvin>> : upcast_to<kelvin> {};
template<> struct downcasting_traits<downcast_from<kelvin>> : downcast_to<kelvin> {};
inline namespace literals {

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_time : make_dimension_t<exp<base_dim_time, 1>> {};
template<> struct upcasting_traits<upcast_from<dimension_time>> : upcast_to<dimension_time> {};
template<> struct downcasting_traits<downcast_from<dimension_time>> : downcast_to<dimension_time> {};
template<typename T>
concept bool Time = Quantity<T> && std::Same<typename T::dimension, dimension_time>;
@@ -37,22 +37,22 @@ namespace units {
using time = quantity<dimension_time, U, Rep>;
struct second : unit<dimension_time> {};
template<> struct upcasting_traits<upcast_from<second>> : upcast_to<second> {};
template<> struct downcasting_traits<downcast_from<second>> : downcast_to<second> {};
struct nanosecond : nano<second> {};
template<> struct upcasting_traits<upcast_from<nanosecond>> : upcast_to<nanosecond> {};
template<> struct downcasting_traits<downcast_from<nanosecond>> : downcast_to<nanosecond> {};
struct microsecond : micro<second> {};
template<> struct upcasting_traits<upcast_from<microsecond>> : upcast_to<microsecond> {};
template<> struct downcasting_traits<downcast_from<microsecond>> : downcast_to<microsecond> {};
struct millisecond : milli<second> {};
template<> struct upcasting_traits<upcast_from<millisecond>> : upcast_to<millisecond> {};
template<> struct downcasting_traits<downcast_from<millisecond>> : downcast_to<millisecond> {};
struct minute : unit<dimension_time, ratio<60>> {};
template<> struct upcasting_traits<upcast_from<minute>> : upcast_to<minute> {};
template<> struct downcasting_traits<downcast_from<minute>> : downcast_to<minute> {};
struct hour : unit<dimension_time, ratio<3600>> {};
template<> struct upcasting_traits<upcast_from<hour>> : upcast_to<hour> {};
template<> struct downcasting_traits<downcast_from<hour>> : downcast_to<hour> {};
inline namespace literals {

View File

@@ -30,7 +30,7 @@ namespace units {
template<Dimension D, Ratio R = ratio<1>>
requires (R::num > 0)
struct unit : upcast_base<unit<D, R>> {
struct unit : downcast_base<unit<D, R>> {
using dimension = D;
using ratio = R;
};
@@ -50,7 +50,7 @@ namespace units {
template<typename T>
concept bool Unit =
std::is_empty_v<T> &&
detail::is_unit<upcast_from<T>>;
detail::is_unit<downcast_from<T>>;
// derived_unit

View File

@@ -28,7 +28,7 @@
namespace units {
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
template<> struct upcasting_traits<upcast_from<dimension_velocity>> : upcast_to<dimension_velocity> {};
template<> struct downcasting_traits<downcast_from<dimension_velocity>> : downcast_to<dimension_velocity> {};
template<typename T>
concept bool Velocity = Quantity<T> && std::Same<typename T::dimension, dimension_velocity>;
@@ -37,13 +37,13 @@ namespace units {
using velocity = quantity<dimension_velocity, U, Rep>;
struct meter_per_second : derived_unit<dimension_velocity, meter, second> {};
template<> struct upcasting_traits<upcast_from<meter_per_second>> : upcast_to<meter_per_second> {};
template<> struct downcasting_traits<downcast_from<meter_per_second>> : downcast_to<meter_per_second> {};
struct kilometer_per_hour : derived_unit<dimension_velocity, kilometer, hour> {};
template<> struct upcasting_traits<upcast_from<kilometer_per_hour>> : upcast_to<kilometer_per_hour> {};
template<> struct downcasting_traits<downcast_from<kilometer_per_hour>> : downcast_to<kilometer_per_hour> {};
struct mile_per_hour : derived_unit<dimension_velocity, mile, hour> {};
template<> struct upcasting_traits<upcast_from<mile_per_hour>> : upcast_to<mile_per_hour> {};
template<> struct downcasting_traits<downcast_from<mile_per_hour>> : downcast_to<mile_per_hour> {};
inline namespace literals {