forked from mpusz/mp-units
upcasting renamed to downcasting
This commit is contained in:
@@ -27,7 +27,7 @@ static_assert(10_km / 5_km == 2);
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Approach
|
||||||
|
|
||||||
1. Safety and performance
|
1. Safety and performance
|
||||||
- strong types
|
- strong types
|
||||||
@@ -89,7 +89,7 @@ or more base dimensions:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<Exponent... Es>
|
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
|
`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>
|
template<typename T>
|
||||||
concept Dimension =
|
concept Dimension =
|
||||||
std::is_empty_v<T> &&
|
std::is_empty_v<T> &&
|
||||||
detail::is_dimension<upcast_from<T>>; // exposition only
|
detail::is_dimension<downcast_from<T>>; // exposition only
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `Exponents`
|
#### `Exponents`
|
||||||
@@ -195,7 +195,7 @@ struct dimension_multiply;
|
|||||||
|
|
||||||
template<Exponent... E1, Exponent... E2>
|
template<Exponent... E1, Exponent... E2>
|
||||||
struct dimension_multiply<dimension<E1...>, dimension<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>
|
template<Dimension D1, Dimension D2>
|
||||||
@@ -219,7 +219,7 @@ struct merge_dimension {
|
|||||||
```cpp
|
```cpp
|
||||||
template<Dimension D, Ratio R>
|
template<Dimension D, Ratio R>
|
||||||
requires (R::num > 0)
|
requires (R::num > 0)
|
||||||
struct unit : upcast_base<unit<D, R>> {
|
struct unit : downcast_base<unit<D, R>> {
|
||||||
using dimension = D;
|
using dimension = D;
|
||||||
using ratio = R;
|
using ratio = R;
|
||||||
};
|
};
|
||||||
@@ -232,7 +232,7 @@ derived from `units::unit` class template:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Unit =
|
concept Unit =
|
||||||
std::is_empty_v<T> &&
|
std::is_empty_v<T> &&
|
||||||
detail::is_unit<upcast_from<T>>; // exposition only
|
detail::is_unit<downcast_from<T>>; // exposition only
|
||||||
```
|
```
|
||||||
|
|
||||||
### `Quantities`
|
### `Quantities`
|
||||||
@@ -268,18 +268,18 @@ public:
|
|||||||
|
|
||||||
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
|
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
|
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,
|
constexpr operator*(const quantity<D1, U1, Rep1>& lhs,
|
||||||
const quantity<D2, U2, Rep2>& rhs);
|
const quantity<D2, U2, Rep2>& rhs);
|
||||||
|
|
||||||
template<Number Rep1, Dimension D, Unit U, Number Rep2>
|
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,
|
constexpr operator/(const Rep1& v,
|
||||||
const quantity<D, U, Rep2>& q) [[expects: q != quantity<D, U, Rep2>(0)]];
|
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>
|
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
|
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,
|
constexpr operator/(const quantity<D1, U1, Rep1>& lhs,
|
||||||
const quantity<D2, U2, Rep2>& rhs) [[expects: rhs != quantity<D, U2, Rep2>(0)]];
|
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
|
To explicitly force truncating conversions `quantity_cast` function is provided which is a direct
|
||||||
counterpart of `std::chrono::duration_cast`.
|
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
|
Most of the important design decisions in the library are dictated by the requirement of providing
|
||||||
the best user experience as possible.
|
the best user experience as possible.
|
||||||
@@ -347,7 +347,7 @@ and
|
|||||||
|
|
||||||
starts to be really hard to analyze or debug.
|
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:
|
same code will result with such an error:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -383,33 +383,33 @@ and
|
|||||||
|
|
||||||
are not arguably much easier to understand thus provide better user experience.
|
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
|
downcasting capability is provided through dedicated `downcasting_traits`, a few helper aliases and by
|
||||||
`base_type` member type in `upcast_base` class template.
|
`base_type` member type in `downcast_base` class template.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<Upcastable T>
|
template<Downcastable T>
|
||||||
using upcast_from = T::base_type;
|
using downcast_from = T::base_type;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using upcast_to = std::type_identity<T>;
|
using downcast_to = std::type_identity<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct upcasting_traits : upcast_to<T> {};
|
struct downcasting_traits : downcast_to<T> {};
|
||||||
|
|
||||||
template<typename 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
|
```cpp
|
||||||
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
|
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
|
```cpp
|
||||||
struct kilometer : unit<dimension_length, std::kilo> {};
|
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:
|
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
|
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
|
```cpp
|
||||||
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
|
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:
|
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>;
|
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
|
- base unit
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct meter : unit<dimension_length, std::ratio<1>> {};
|
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
|
- units with prefixes
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct kilometer : kilo<meter> {};
|
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
|
- derived units
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct kilometer_per_hour : derived_unit<dimension_velocity, kilometer, hour> {};
|
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:
|
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?
|
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?
|
In such a case all the operators have to be provided to a child class. Or maybe use CRTP?
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_area : make_dimension_t<exp<base_dim_length, 2>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Area = Quantity<T> && std::Same<typename T::dimension, dimension_area>;
|
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>;
|
using area = quantity<dimension_area, U, Rep>;
|
||||||
|
|
||||||
struct square_millimeter : derived_unit<dimension_area, millimeter> {};
|
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> {};
|
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> {};
|
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> {};
|
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> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,27 +28,27 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
template<typename BaseType>
|
template<typename BaseType>
|
||||||
struct upcast_base {
|
struct downcast_base {
|
||||||
using base_type = BaseType;
|
using base_type = BaseType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Upcastable =
|
concept bool Downcastable =
|
||||||
requires {
|
requires {
|
||||||
typename T::base_type;
|
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>
|
template<Downcastable T>
|
||||||
using upcast_from = T::base_type;
|
using downcast_from = T::base_type;
|
||||||
|
|
||||||
template<Upcastable T>
|
template<Downcastable T>
|
||||||
using upcast_to = std::type_identity<T>;
|
using downcast_to = std::type_identity<T>;
|
||||||
|
|
||||||
template<Upcastable T>
|
template<Downcastable T>
|
||||||
struct upcasting_traits : upcast_to<T> {};
|
struct downcasting_traits : downcast_to<T> {};
|
||||||
|
|
||||||
template<Upcastable T>
|
template<Downcastable T>
|
||||||
using upcasting_traits_t = upcasting_traits<T>::type;
|
using downcasting_traits_t = downcasting_traits<T>::type;
|
||||||
|
|
||||||
} // namespace units
|
} // namespace units
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_current : make_dimension_t<exp<base_dim_current, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Current = Quantity<T> && std::Same<typename T::dimension, dimension_current>;
|
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>;
|
using current = quantity<dimension_current, U, Rep>;
|
||||||
|
|
||||||
struct ampere : unit<dimension_current> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <units/bits/type_list.h>
|
#include <units/bits/type_list.h>
|
||||||
#include <units/bits/upcasting.h>
|
#include <units/bits/downcasting.h>
|
||||||
|
|
||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ namespace units {
|
|||||||
// dimension
|
// dimension
|
||||||
|
|
||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
struct dimension : upcast_base<dimension<Es...>> {};
|
struct dimension : downcast_base<dimension<Es...>> {};
|
||||||
|
|
||||||
// is_dimension
|
// is_dimension
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -97,7 +97,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Dimension =
|
concept bool Dimension =
|
||||||
std::is_empty_v<T> &&
|
std::is_empty_v<T> &&
|
||||||
detail::is_dimension<upcast_from<T>>;
|
detail::is_dimension<downcast_from<T>>;
|
||||||
|
|
||||||
|
|
||||||
// dim_invert
|
// dim_invert
|
||||||
@@ -106,7 +106,7 @@ namespace units {
|
|||||||
struct dim_invert;
|
struct dim_invert;
|
||||||
|
|
||||||
template<Exponent... Es>
|
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>
|
template<Dimension D>
|
||||||
using dim_invert_t = dim_invert<typename D::base_type>::type;
|
using dim_invert_t = dim_invert<typename D::base_type>::type;
|
||||||
@@ -168,7 +168,7 @@ namespace units {
|
|||||||
struct dimension_multiply;
|
struct dimension_multiply;
|
||||||
|
|
||||||
template<Exponent... E1, Exponent... E2>
|
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>
|
template<Dimension D1, Dimension D2>
|
||||||
using dimension_multiply_t = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
using dimension_multiply_t = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_frequency : make_dimension_t<exp<base_dim_time, -1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Frequency = Quantity<T> && std::Same<typename T::dimension, dimension_frequency>;
|
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>;
|
using frequency = quantity<dimension_frequency, U, Rep>;
|
||||||
|
|
||||||
struct hertz : derived_unit<dimension_frequency, second> {};
|
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> {};
|
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> {};
|
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> {};
|
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> {};
|
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> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Length = Quantity<T> && std::Same<typename T::dimension, dimension_length>;
|
concept bool Length = Quantity<T> && std::Same<typename T::dimension, dimension_length>;
|
||||||
@@ -38,16 +38,16 @@ namespace units {
|
|||||||
|
|
||||||
// SI units
|
// SI units
|
||||||
struct meter : unit<dimension_length> {};
|
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> {};
|
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> {};
|
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> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
@@ -71,16 +71,16 @@ namespace units {
|
|||||||
|
|
||||||
// US customary units
|
// US customary units
|
||||||
struct yard : unit<dimension_length, ratio<9'144, 10'000>> {};
|
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>> {};
|
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>> {};
|
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>> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_luminous_intensity : make_dimension_t<exp<base_dim_luminous_intensity, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool LuminousIntensity = Quantity<T> && std::Same<typename T::dimension, dimension_luminous_intensity>;
|
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>;
|
using luminous_intensity = quantity<dimension_luminous_intensity, U, Rep>;
|
||||||
|
|
||||||
struct candela : unit<dimension_luminous_intensity> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_mass : make_dimension_t<exp<base_dim_mass, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Mass = Quantity<T> && std::Same<typename T::dimension, dimension_mass>;
|
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>;
|
using mass = quantity<dimension_mass, U, Rep>;
|
||||||
|
|
||||||
struct gram : unit<dimension_mass, ratio<1, 1000>> {};
|
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> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ namespace units {
|
|||||||
|
|
||||||
template<Dimension D, Unit U1, Scalar Rep1, Unit U2, Scalar Rep2, Scalar Rep>
|
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> {
|
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>>
|
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 dim = dimension_multiply_t<D1, D2>;
|
||||||
using common_rep = decltype(lhs.count() * rhs.count());
|
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());
|
return ret(lhs.count() * rhs.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ namespace units {
|
|||||||
|
|
||||||
using dim = dim_invert_t<D>;
|
using dim = dim_invert_t<D>;
|
||||||
using common_rep = decltype(v / q.count());
|
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>;
|
using den = quantity<D, U, common_rep>;
|
||||||
return ret(v / den(q).count());
|
return ret(v / den(q).count());
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ namespace units {
|
|||||||
|
|
||||||
using common_rep = decltype(lhs.count() / rhs.count());
|
using common_rep = decltype(lhs.count() / rhs.count());
|
||||||
using dim = dimension_divide_t<D1, D2>;
|
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());
|
return ret(lhs.count() / rhs.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_substance : make_dimension_t<exp<base_dim_substance, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Substance = Quantity<T> && std::Same<typename T::dimension, dimension_substance>;
|
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>;
|
using substance = quantity<dimension_substance, U, Rep>;
|
||||||
|
|
||||||
struct mole : unit<dimension_substance> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_temperature : make_dimension_t<exp<base_dim_temperature, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool ThermodynamicTemperature = Quantity<T> && std::Same<typename T::dimension, dimension_temperature>;
|
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>;
|
using temperature = quantity<dimension_temperature, U, Rep>;
|
||||||
|
|
||||||
struct kelvin : unit<dimension_temperature> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_time : make_dimension_t<exp<base_dim_time, 1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Time = Quantity<T> && std::Same<typename T::dimension, dimension_time>;
|
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>;
|
using time = quantity<dimension_time, U, Rep>;
|
||||||
|
|
||||||
struct second : unit<dimension_time> {};
|
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> {};
|
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> {};
|
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> {};
|
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>> {};
|
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>> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ namespace units {
|
|||||||
|
|
||||||
template<Dimension D, Ratio R = ratio<1>>
|
template<Dimension D, Ratio R = ratio<1>>
|
||||||
requires (R::num > 0)
|
requires (R::num > 0)
|
||||||
struct unit : upcast_base<unit<D, R>> {
|
struct unit : downcast_base<unit<D, R>> {
|
||||||
using dimension = D;
|
using dimension = D;
|
||||||
using ratio = R;
|
using ratio = R;
|
||||||
};
|
};
|
||||||
@@ -50,7 +50,7 @@ namespace units {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Unit =
|
concept bool Unit =
|
||||||
std::is_empty_v<T> &&
|
std::is_empty_v<T> &&
|
||||||
detail::is_unit<upcast_from<T>>;
|
detail::is_unit<downcast_from<T>>;
|
||||||
|
|
||||||
|
|
||||||
// derived_unit
|
// derived_unit
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
|
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>
|
template<typename T>
|
||||||
concept bool Velocity = Quantity<T> && std::Same<typename T::dimension, dimension_velocity>;
|
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>;
|
using velocity = quantity<dimension_velocity, U, Rep>;
|
||||||
|
|
||||||
struct meter_per_second : derived_unit<dimension_velocity, meter, second> {};
|
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> {};
|
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> {};
|
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 {
|
inline namespace literals {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user