downcasting_traits renamed to downcast_traits

- downcasting_traits -> downcast_traits
- downcasting_traits_t -> downcast_traits_t
- downcast_from -> downcast_base_t
- downcast_to removed
This commit is contained in:
Mateusz Pusz
2019-09-20 18:36:14 +02:00
parent da11f41529
commit 0cffcf7849
32 changed files with 118 additions and 129 deletions

View File

@@ -60,6 +60,7 @@ NOTE: This library as of now compiles correctly only with gcc-9.1 and newer.
- Support for derived dimensions in `exp` added - Support for derived dimensions in `exp` added
- Added `pow()` and `sqrt()` operations on quantities - Added `pow()` and `sqrt()` operations on quantities
- `units` removed from a `std::experimental` namespace - `units` removed from a `std::experimental` namespace
- `downcasting_traits` renamed to `downcast_traits` and refactored helpers
- 0.3.1 Sep 18, 2019 - 0.3.1 Sep 18, 2019
- cmcstl2 dependency changed to range-v3 0.9.1 - cmcstl2 dependency changed to range-v3 0.9.1

View File

@@ -89,7 +89,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<downcast_from<T>>; // exposition only detail::is_dimension<downcast_base_t<T>>; // exposition only
``` ```
#### `Exponents` #### `Exponents`
@@ -219,7 +219,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 = downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>; using type = downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>;
}; };
template<Dimension D1, Dimension D2> template<Dimension D1, Dimension D2>
@@ -275,7 +275,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<downcast_from<T>>; // exposition only detail::is_unit<downcast_base_t<T>>; // exposition only
``` ```
### `Quantities` ### `Quantities`
@@ -450,7 +450,7 @@ 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.
Downcasting capability is provided through dedicated `downcasting_traits`, concept, a few helper aliases and by Downcasting capability is provided through dedicated `downcast_traits`, concept, a few helper aliases and by
`base_type` member type in `downcast_base` class template. `base_type` member type in `downcast_base` class template.
```cpp ```cpp
@@ -467,28 +467,25 @@ concept Downcastable =
std::derived_from<T, downcast_base<typename T::base_type>>; std::derived_from<T, downcast_base<typename T::base_type>>;
template<Downcastable T> template<Downcastable T>
using downcast_from = T::base_type; using downcast_base_t = T::base_type;
template<Downcastable T> template<Downcastable T>
using downcast_to = std::type_identity<T>; struct downcast_traits : std::type_identity<T> {};
template<Downcastable T> template<Downcastable T>
struct downcasting_traits : downcast_to<T> {}; using downcast_traits_t = downcast_traits<T>::type;
template<Downcastable T>
using downcasting_traits_t = downcasting_traits<T>::type;
``` ```
With that the downcasting functionality is enabled by: With that the downcasting functionality is enabled by:
```cpp ```cpp
struct length : make_dimension_t<exp<base_dim_length, 1>> {}; struct length : make_dimension_t<exp<base_dim_length, 1>> {};
template<> struct downcasting_traits<downcast_from<length>> : downcast_to<length> {}; template<> struct downcast_traits<downcast_base_t<length>> : std::type_identity<length> {};
``` ```
```cpp ```cpp
struct kilometre : unit<length, std::kilo> {}; struct kilometre : unit<length, std::kilo> {};
template<> struct downcasting_traits<downcast_from<kilometre>> : downcast_to<kilometre> {}; template<> struct downcast_traits<downcast_base_t<kilometre>> : std::type_identity<kilometre> {};
``` ```
@@ -507,7 +504,7 @@ In order to extend the library with custom dimensions the user has to:
```cpp ```cpp
struct digital_information : units::make_dimension_t<units::exp<base_dim_digital_information, 1>> {}; struct digital_information : units::make_dimension_t<units::exp<base_dim_digital_information, 1>> {};
template<> template<>
struct units::downcasting_traits<units::downcast_from<digital_information>> : units::downcast_to<digital_information> {}; struct units::downcast_traits<units::downcast_base_t<digital_information>> : units::std::type_identity_t<digital_information> {};
``` ```
2. Define a concept that will match a new dimension: 2. Define a concept that will match a new dimension:
@@ -521,10 +518,10 @@ In order to extend the library with custom dimensions the user has to:
```cpp ```cpp
struct bit : units::unit<digital_information> {}; struct bit : units::unit<digital_information> {};
template<> struct units::downcasting_traits<units::downcast_from<bit>> : units::downcast_to<bit> {}; template<> struct units::downcast_traits<units::downcast_base_t<bit>> : units::std::type_identity_t<bit> {};
struct byte : units::unit<digital_information, units::ratio<8>> {}; struct byte : units::unit<digital_information, units::ratio<8>> {};
template<> struct units::downcasting_traits<units::downcast_from<byte>> : units::downcast_to<byte> {}; template<> struct units::downcast_traits<units::downcast_base_t<byte>> : units::std::type_identity_t<byte> {};
``` ```
4. Provide user-defined literals for the most important units: 4. Provide user-defined literals for the most important units:
@@ -568,7 +565,7 @@ In order to extend the library with custom dimensions the user has to:
and allow implicit conversion to and from the underlying value type or types that are and allow implicit conversion to and from the underlying value type or types that are
convertible to/from that value type. convertible to/from that value type.
9. Should we standardize accompany tools (`downcasting_traits`, `type_list` operations, `common_ratio`, etc)? 9. Should we standardize accompany tools (`downcast_traits`, `type_list` operations, `common_ratio`, etc)?
10. `k`, `K`, `W`, `F` UDLs conflict with gcc GNU extensions (https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Fixed_002dPoint.html) 10. `k`, `K`, `W`, `F` UDLs conflict with gcc GNU extensions (https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Fixed_002dPoint.html)
for floating point types. for floating point types.

View File

@@ -40,15 +40,12 @@ namespace units {
std::derived_from<T, downcast_base<typename T::base_type>>; std::derived_from<T, downcast_base<typename T::base_type>>;
template<Downcastable T> template<Downcastable T>
using downcast_from = T::base_type; using downcast_base_t = T::base_type;
template<Downcastable T> template<Downcastable T>
using downcast_to = std::type_identity<T>; struct downcast_traits : std::type_identity<T> {};
template<Downcastable T> template<Downcastable T>
struct downcasting_traits : downcast_to<T> {}; using downcast_traits_t = downcast_traits<T>::type;
template<Downcastable T>
using downcasting_traits_t = downcasting_traits<T>::type;
} // namespace units } // namespace units

View File

@@ -87,7 +87,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<downcast_from<T>>; detail::is_dimension<downcast_base_t<T>>;
// exp // exp
@@ -156,10 +156,10 @@ namespace units {
struct dim_invert; struct dim_invert;
template<typename... Es> template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_invert_t<Es>...>>> {}; struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exp_invert_t<Es>...>>> {};
template<Dimension D> template<Dimension D>
using dim_invert_t = dim_invert<downcast_from<D>>::type; using dim_invert_t = dim_invert<downcast_base_t<D>>::type;
// todo: force as the only user interface to create dimensions through modules // todo: force as the only user interface to create dimensions through modules
@@ -221,7 +221,7 @@ namespace units {
template<Dimension Dim, int Num, int Den, Exponent... ERest> template<Dimension Dim, int Num, int Den, Exponent... ERest>
struct extract<exp<Dim, Num, Den>, ERest...> { struct extract<exp<Dim, Num, Den>, ERest...> {
using type = extract_t<exp<downcast_from<Dim>, Num, Den>, ERest...>; using type = extract_t<exp<downcast_base_t<Dim>, Num, Den>, ERest...>;
}; };
} // namespace detail } // namespace detail
@@ -248,7 +248,7 @@ namespace units {
struct dimension_multiply; struct dimension_multiply;
template<typename... E1, typename... E2> template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {}; struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_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;
@@ -271,7 +271,7 @@ namespace units {
struct dimension_sqrt; struct dimension_sqrt;
template<typename... Es> template<typename... Es>
struct dimension_sqrt<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_multiply_t<Es, 1, 2>...>>> {}; struct dimension_sqrt<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exp_multiply_t<Es, 1, 2>...>>> {};
template<Dimension D> template<Dimension D>
using dimension_sqrt_t = dimension_sqrt<typename D::base_type>::type; using dimension_sqrt_t = dimension_sqrt<typename D::base_type>::type;
@@ -281,7 +281,7 @@ namespace units {
struct dimension_pow; struct dimension_pow;
template<typename... Es, std::size_t N> template<typename... Es, std::size_t N>
struct dimension_pow<dimension<Es...>, N> : std::type_identity<downcasting_traits_t<dimension<exp_multiply_t<Es, N, 1>...>>> {}; struct dimension_pow<dimension<Es...>, N> : std::type_identity<downcast_traits_t<dimension<exp_multiply_t<Es, N, 1>...>>> {};
template<Dimension D, std::size_t N> template<Dimension D, std::size_t N>
using dimension_pow_t = dimension_pow<typename D::base_type, N>::type; using dimension_pow_t = dimension_pow<typename D::base_type, N>::type;

View File

@@ -27,13 +27,13 @@
namespace units { namespace units {
struct acceleration : make_dimension_t<exp<velocity, 1>, exp<base_dim_time, -1>> {}; struct acceleration : make_dimension_t<exp<velocity, 1>, exp<base_dim_time, -1>> {};
template<> struct downcasting_traits<downcast_from<acceleration>> : downcast_to<acceleration> {}; template<> struct downcast_traits<downcast_base_t<acceleration>> : std::type_identity<acceleration> {};
template<typename T> template<typename T>
concept bool Acceleration = QuantityOf<T, acceleration>; concept bool Acceleration = QuantityOf<T, acceleration>;
struct metre_per_second_sq : derived_unit<acceleration, metre, second> {}; struct metre_per_second_sq : derived_unit<acceleration, metre, second> {};
template<> struct downcasting_traits<downcast_from<metre_per_second_sq>> : downcast_to<metre_per_second_sq> {}; template<> struct downcast_traits<downcast_base_t<metre_per_second_sq>> : std::type_identity<metre_per_second_sq> {};
inline namespace literals { inline namespace literals {

View File

@@ -27,25 +27,25 @@
namespace units { namespace units {
struct area : make_dimension_t<exp<base_dim_length, 2>> {}; struct area : make_dimension_t<exp<base_dim_length, 2>> {};
template<> struct downcasting_traits<downcast_from<area>> : downcast_to<area> {}; template<> struct downcast_traits<downcast_base_t<area>> : std::type_identity<area> {};
template<typename T> template<typename T>
concept bool Area = QuantityOf<T, area>; concept bool Area = QuantityOf<T, area>;
struct square_millimetre : derived_unit<area, millimetre> {}; struct square_millimetre : derived_unit<area, millimetre> {};
template<> struct downcasting_traits<downcast_from<square_millimetre>> : downcast_to<square_millimetre> {}; template<> struct downcast_traits<downcast_base_t<square_millimetre>> : std::type_identity<square_millimetre> {};
struct square_centimetre : derived_unit<area, centimetre> {}; struct square_centimetre : derived_unit<area, centimetre> {};
template<> struct downcasting_traits<downcast_from<square_centimetre>> : downcast_to<square_centimetre> {}; template<> struct downcast_traits<downcast_base_t<square_centimetre>> : std::type_identity<square_centimetre> {};
struct square_metre : derived_unit<area, metre> {}; struct square_metre : derived_unit<area, metre> {};
template<> struct downcasting_traits<downcast_from<square_metre>> : downcast_to<square_metre> {}; template<> struct downcast_traits<downcast_base_t<square_metre>> : std::type_identity<square_metre> {};
struct square_kilometre : derived_unit<area, kilometre, metre> {}; struct square_kilometre : derived_unit<area, kilometre, metre> {};
template<> struct downcasting_traits<downcast_from<square_kilometre>> : downcast_to<square_kilometre> {}; template<> struct downcast_traits<downcast_base_t<square_kilometre>> : std::type_identity<square_kilometre> {};
struct square_foot : derived_unit<area, foot> {}; struct square_foot : derived_unit<area, foot> {};
template<> struct downcasting_traits<downcast_from<square_foot>> : downcast_to<square_foot> {}; template<> struct downcast_traits<downcast_base_t<square_foot>> : std::type_identity<square_foot> {};
inline namespace literals { inline namespace literals {

View File

@@ -29,13 +29,13 @@
namespace units { namespace units {
struct capacitance : make_dimension_t<exp<electric_charge, 1>, exp<voltage, -1>> {}; struct capacitance : make_dimension_t<exp<electric_charge, 1>, exp<voltage, -1>> {};
template<> struct downcasting_traits<downcast_from<capacitance>> : downcast_to<capacitance> {}; template<> struct downcast_traits<downcast_base_t<capacitance>> : std::type_identity<capacitance> {};
template<typename T> template<typename T>
concept bool Capacitance = QuantityOf<T, capacitance>; concept bool Capacitance = QuantityOf<T, capacitance>;
struct farad : derived_unit<capacitance, kilogram, metre, second, ampere> {}; struct farad : derived_unit<capacitance, kilogram, metre, second, ampere> {};
template<> struct downcasting_traits<downcast_from<farad>> : downcast_to<farad> {}; template<> struct downcast_traits<downcast_base_t<farad>> : std::type_identity<farad> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,13 +28,13 @@
namespace units { namespace units {
struct current : make_dimension_t<exp<base_dim_current, 1>> {}; struct current : make_dimension_t<exp<base_dim_current, 1>> {};
template<> struct downcasting_traits<downcast_from<current>> : downcast_to<current> {}; template<> struct downcast_traits<downcast_base_t<current>> : std::type_identity<current> {};
template<typename T> template<typename T>
concept bool Current = QuantityOf<T, current>; concept bool Current = QuantityOf<T, current>;
struct ampere : unit<current> {}; struct ampere : unit<current> {};
template<> struct downcasting_traits<downcast_from<ampere>> : downcast_to<ampere> {}; template<> struct downcast_traits<downcast_base_t<ampere>> : std::type_identity<ampere> {};
inline namespace literals { inline namespace literals {

View File

@@ -29,13 +29,13 @@
namespace units { namespace units {
struct electric_charge : make_dimension_t<exp<base_dim_time, 1>, exp<base_dim_current, 1>> {}; struct electric_charge : make_dimension_t<exp<base_dim_time, 1>, exp<base_dim_current, 1>> {};
template<> struct downcasting_traits<downcast_from<electric_charge>> : downcast_to<electric_charge> {}; template<> struct downcast_traits<downcast_base_t<electric_charge>> : std::type_identity<electric_charge> {};
template<typename T> template<typename T>
concept bool ElectricCharge = QuantityOf<T, electric_charge>; concept bool ElectricCharge = QuantityOf<T, electric_charge>;
struct coulomb : derived_unit<electric_charge, second, ampere> {}; struct coulomb : derived_unit<electric_charge, second, ampere> {};
template<> struct downcasting_traits<downcast_from<coulomb>> : downcast_to<coulomb> {}; template<> struct downcast_traits<downcast_base_t<coulomb>> : std::type_identity<coulomb> {};
inline namespace literals { inline namespace literals {

View File

@@ -29,13 +29,13 @@
namespace units { namespace units {
struct energy : make_dimension_t<exp<force, 1>, exp<length, 1>> {}; struct energy : make_dimension_t<exp<force, 1>, exp<length, 1>> {};
template<> struct downcasting_traits<downcast_from<energy>> : downcast_to<energy> {}; template<> struct downcast_traits<downcast_base_t<energy>> : std::type_identity<energy> {};
template<typename T> template<typename T>
concept bool Energy = QuantityOf<T, energy>; concept bool Energy = QuantityOf<T, energy>;
struct joule : derived_unit<energy, kilogram, metre, second> {}; struct joule : derived_unit<energy, kilogram, metre, second> {};
template<> struct downcasting_traits<downcast_from<joule>> : downcast_to<joule> {}; template<> struct downcast_traits<downcast_base_t<joule>> : std::type_identity<joule> {};
inline namespace literals { inline namespace literals {

View File

@@ -29,13 +29,13 @@
namespace units { namespace units {
struct force : make_dimension_t<exp<base_dim_mass, 1>, exp<acceleration, 1>> {}; struct force : make_dimension_t<exp<base_dim_mass, 1>, exp<acceleration, 1>> {};
template<> struct downcasting_traits<downcast_from<force>> : downcast_to<force> {}; template<> struct downcast_traits<downcast_base_t<force>> : std::type_identity<force> {};
template<typename T> template<typename T>
concept bool Force = QuantityOf<T, force>; concept bool Force = QuantityOf<T, force>;
struct newton : derived_unit<force, kilogram, metre, second> {}; struct newton : derived_unit<force, kilogram, metre, second> {};
template<> struct downcasting_traits<downcast_from<newton>> : downcast_to<newton> {}; template<> struct downcast_traits<downcast_base_t<newton>> : std::type_identity<newton> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,28 +28,28 @@
namespace units { namespace units {
struct frequency : make_dimension_t<exp<base_dim_time, -1>> {}; struct frequency : make_dimension_t<exp<base_dim_time, -1>> {};
template<> struct downcasting_traits<downcast_from<frequency>> : downcast_to<frequency> {}; template<> struct downcast_traits<downcast_base_t<frequency>> : std::type_identity<frequency> {};
template<typename T> template<typename T>
concept bool Frequency = QuantityOf<T, frequency>; concept bool Frequency = QuantityOf<T, frequency>;
struct hertz : derived_unit<frequency, second> {}; struct hertz : derived_unit<frequency, second> {};
template<> struct downcasting_traits<downcast_from<hertz>> : downcast_to<hertz> {}; template<> struct downcast_traits<downcast_base_t<hertz>> : std::type_identity<hertz> {};
struct millihertz : milli<hertz> {}; struct millihertz : milli<hertz> {};
template<> struct downcasting_traits<downcast_from<millihertz>> : downcast_to<millihertz> {}; template<> struct downcast_traits<downcast_base_t<millihertz>> : std::type_identity<millihertz> {};
struct kilohertz : kilo<hertz> {}; struct kilohertz : kilo<hertz> {};
template<> struct downcasting_traits<downcast_from<kilohertz>> : downcast_to<kilohertz> {}; template<> struct downcast_traits<downcast_base_t<kilohertz>> : std::type_identity<kilohertz> {};
struct megahertz : mega<hertz> {}; struct megahertz : mega<hertz> {};
template<> struct downcasting_traits<downcast_from<megahertz>> : downcast_to<megahertz> {}; template<> struct downcast_traits<downcast_base_t<megahertz>> : std::type_identity<megahertz> {};
struct gigahertz : giga<hertz> {}; struct gigahertz : giga<hertz> {};
template<> struct downcasting_traits<downcast_from<gigahertz>> : downcast_to<gigahertz> {}; template<> struct downcast_traits<downcast_base_t<gigahertz>> : std::type_identity<gigahertz> {};
struct terahertz : tera<hertz> {}; struct terahertz : tera<hertz> {};
template<> struct downcasting_traits<downcast_from<terahertz>> : downcast_to<terahertz> {}; template<> struct downcast_traits<downcast_base_t<terahertz>> : std::type_identity<terahertz> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,23 +28,23 @@
namespace units { namespace units {
struct length : make_dimension_t<exp<base_dim_length, 1>> {}; struct length : make_dimension_t<exp<base_dim_length, 1>> {};
template<> struct downcasting_traits<downcast_from<length>> : downcast_to<length> {}; template<> struct downcast_traits<downcast_base_t<length>> : std::type_identity<length> {};
template<typename T> template<typename T>
concept bool Length = QuantityOf<T, length>; concept bool Length = QuantityOf<T, length>;
// SI units // SI units
struct metre : unit<length> {}; struct metre : unit<length> {};
template<> struct downcasting_traits<downcast_from<metre>> : downcast_to<metre> {}; template<> struct downcast_traits<downcast_base_t<metre>> : std::type_identity<metre> {};
struct millimetre : milli<metre> {}; struct millimetre : milli<metre> {};
template<> struct downcasting_traits<downcast_from<millimetre>> : downcast_to<millimetre> {}; template<> struct downcast_traits<downcast_base_t<millimetre>> : std::type_identity<millimetre> {};
struct centimetre : centi<metre> {}; struct centimetre : centi<metre> {};
template<> struct downcasting_traits<downcast_from<centimetre>> : downcast_to<centimetre> {}; template<> struct downcast_traits<downcast_base_t<centimetre>> : std::type_identity<centimetre> {};
struct kilometre : kilo<metre> {}; struct kilometre : kilo<metre> {};
template<> struct downcasting_traits<downcast_from<kilometre>> : downcast_to<kilometre> {}; template<> struct downcast_traits<downcast_base_t<kilometre>> : std::type_identity<kilometre> {};
inline namespace literals { inline namespace literals {
@@ -68,16 +68,16 @@ namespace units {
// US customary units // US customary units
struct yard : unit<length, ratio<9'144, 10'000>> {}; struct yard : unit<length, ratio<9'144, 10'000>> {};
template<> struct downcasting_traits<downcast_from<yard>> : downcast_to<yard> {}; template<> struct downcast_traits<downcast_base_t<yard>> : std::type_identity<yard> {};
struct foot : unit<length, ratio_multiply<ratio<1, 3>, yard::ratio>> {}; struct foot : unit<length, ratio_multiply<ratio<1, 3>, yard::ratio>> {};
template<> struct downcasting_traits<downcast_from<foot>> : downcast_to<foot> {}; template<> struct downcast_traits<downcast_base_t<foot>> : std::type_identity<foot> {};
struct inch : unit<length, ratio_multiply<ratio<1, 12>, foot::ratio>> {}; struct inch : unit<length, ratio_multiply<ratio<1, 12>, foot::ratio>> {};
template<> struct downcasting_traits<downcast_from<inch>> : downcast_to<inch> {}; template<> struct downcast_traits<downcast_base_t<inch>> : std::type_identity<inch> {};
struct mile : unit<length, ratio_multiply<ratio<1'760>, yard::ratio>> {}; struct mile : unit<length, ratio_multiply<ratio<1'760>, yard::ratio>> {};
template<> struct downcasting_traits<downcast_from<mile>> : downcast_to<mile> {}; template<> struct downcast_traits<downcast_base_t<mile>> : std::type_identity<mile> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,13 +28,13 @@
namespace units { namespace units {
struct luminous_intensity : make_dimension_t<exp<base_dim_luminous_intensity, 1>> {}; struct luminous_intensity : make_dimension_t<exp<base_dim_luminous_intensity, 1>> {};
template<> struct downcasting_traits<downcast_from<luminous_intensity>> : downcast_to<luminous_intensity> {}; template<> struct downcast_traits<downcast_base_t<luminous_intensity>> : std::type_identity<luminous_intensity> {};
template<typename T> template<typename T>
concept bool LuminousIntensity = QuantityOf<T, luminous_intensity>; concept bool LuminousIntensity = QuantityOf<T, luminous_intensity>;
struct candela : unit<luminous_intensity> {}; struct candela : unit<luminous_intensity> {};
template<> struct downcasting_traits<downcast_from<candela>> : downcast_to<candela> {}; template<> struct downcast_traits<downcast_base_t<candela>> : std::type_identity<candela> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,16 +28,16 @@
namespace units { namespace units {
struct mass : make_dimension_t<exp<base_dim_mass, 1>> {}; struct mass : make_dimension_t<exp<base_dim_mass, 1>> {};
template<> struct downcasting_traits<downcast_from<mass>> : downcast_to<mass> {}; template<> struct downcast_traits<downcast_base_t<mass>> : std::type_identity<mass> {};
template<typename T> template<typename T>
concept bool Mass = QuantityOf<T, mass>; concept bool Mass = QuantityOf<T, mass>;
struct gram : unit<mass, ratio<1, 1000>> {}; struct gram : unit<mass, ratio<1, 1000>> {};
template<> struct downcasting_traits<downcast_from<gram>> : downcast_to<gram> {}; template<> struct downcast_traits<downcast_base_t<gram>> : std::type_identity<gram> {};
struct kilogram : kilo<gram> {}; struct kilogram : kilo<gram> {};
template<> struct downcasting_traits<downcast_from<kilogram>> : downcast_to<kilogram> {}; template<> struct downcast_traits<downcast_base_t<kilogram>> : std::type_identity<kilogram> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,13 +28,13 @@
namespace units { namespace units {
struct power : make_dimension_t<exp<energy, 1>, exp<base_dim_time, -1>> {}; struct power : make_dimension_t<exp<energy, 1>, exp<base_dim_time, -1>> {};
template<> struct downcasting_traits<downcast_from<power>> : downcast_to<power> {}; template<> struct downcast_traits<downcast_base_t<power>> : std::type_identity<power> {};
template<typename T> template<typename T>
concept bool Power = QuantityOf<T, power>; concept bool Power = QuantityOf<T, power>;
struct watt : derived_unit<power, kilogram, metre, second> {}; struct watt : derived_unit<power, kilogram, metre, second> {};
template<> struct downcasting_traits<downcast_from<watt>> : downcast_to<watt> {}; template<> struct downcast_traits<downcast_base_t<watt>> : std::type_identity<watt> {};
inline namespace literals { inline namespace literals {

View File

@@ -29,13 +29,13 @@
namespace units { namespace units {
struct pressure : make_dimension_t<exp<force, 1>, exp<area, -1>> {}; struct pressure : make_dimension_t<exp<force, 1>, exp<area, -1>> {};
template<> struct downcasting_traits<downcast_from<pressure>> : downcast_to<pressure> {}; template<> struct downcast_traits<downcast_base_t<pressure>> : std::type_identity<pressure> {};
template<typename T> template<typename T>
concept bool Pressure = QuantityOf<T, pressure>; concept bool Pressure = QuantityOf<T, pressure>;
struct pascal : derived_unit<pressure, kilogram, metre, second> {}; struct pascal : derived_unit<pressure, kilogram, metre, second> {};
template<> struct downcasting_traits<downcast_from<pascal>> : downcast_to<pascal> {}; template<> struct downcast_traits<downcast_base_t<pascal>> : std::type_identity<pascal> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,13 +28,13 @@
namespace units { namespace units {
struct substance : make_dimension_t<exp<base_dim_substance, 1>> {}; struct substance : make_dimension_t<exp<base_dim_substance, 1>> {};
template<> struct downcasting_traits<downcast_from<substance>> : downcast_to<substance> {}; template<> struct downcast_traits<downcast_base_t<substance>> : std::type_identity<substance> {};
template<typename T> template<typename T>
concept bool Substance = QuantityOf<T, substance>; concept bool Substance = QuantityOf<T, substance>;
struct mole : unit<substance> {}; struct mole : unit<substance> {};
template<> struct downcasting_traits<downcast_from<mole>> : downcast_to<mole> {}; template<> struct downcast_traits<downcast_base_t<mole>> : std::type_identity<mole> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,13 +28,13 @@
namespace units { namespace units {
struct temperature : make_dimension_t<exp<base_dim_temperature, 1>> {}; struct temperature : make_dimension_t<exp<base_dim_temperature, 1>> {};
template<> struct downcasting_traits<downcast_from<temperature>> : downcast_to<temperature> {}; template<> struct downcast_traits<downcast_base_t<temperature>> : std::type_identity<temperature> {};
template<typename T> template<typename T>
concept bool ThermodynamicTemperature = QuantityOf<T, temperature>; concept bool ThermodynamicTemperature = QuantityOf<T, temperature>;
struct kelvin : unit<temperature> {}; struct kelvin : unit<temperature> {};
template<> struct downcasting_traits<downcast_from<kelvin>> : downcast_to<kelvin> {}; template<> struct downcast_traits<downcast_base_t<kelvin>> : std::type_identity<kelvin> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,28 +28,28 @@
namespace units { namespace units {
struct time : make_dimension_t<exp<base_dim_time, 1>> {}; struct time : make_dimension_t<exp<base_dim_time, 1>> {};
template<> struct downcasting_traits<downcast_from<time>> : downcast_to<time> {}; template<> struct downcast_traits<downcast_base_t<time>> : std::type_identity<time> {};
template<typename T> template<typename T>
concept bool Time = QuantityOf<T, time>; concept bool Time = QuantityOf<T, time>;
struct second : unit<time> {}; struct second : unit<time> {};
template<> struct downcasting_traits<downcast_from<second>> : downcast_to<second> {}; template<> struct downcast_traits<downcast_base_t<second>> : std::type_identity<second> {};
struct nanosecond : nano<second> {}; struct nanosecond : nano<second> {};
template<> struct downcasting_traits<downcast_from<nanosecond>> : downcast_to<nanosecond> {}; template<> struct downcast_traits<downcast_base_t<nanosecond>> : std::type_identity<nanosecond> {};
struct microsecond : micro<second> {}; struct microsecond : micro<second> {};
template<> struct downcasting_traits<downcast_from<microsecond>> : downcast_to<microsecond> {}; template<> struct downcast_traits<downcast_base_t<microsecond>> : std::type_identity<microsecond> {};
struct millisecond : milli<second> {}; struct millisecond : milli<second> {};
template<> struct downcasting_traits<downcast_from<millisecond>> : downcast_to<millisecond> {}; template<> struct downcast_traits<downcast_base_t<millisecond>> : std::type_identity<millisecond> {};
struct minute : unit<time, ratio<60>> {}; struct minute : unit<time, ratio<60>> {};
template<> struct downcasting_traits<downcast_from<minute>> : downcast_to<minute> {}; template<> struct downcast_traits<downcast_base_t<minute>> : std::type_identity<minute> {};
struct hour : unit<time, ratio<3600>> {}; struct hour : unit<time, ratio<3600>> {};
template<> struct downcasting_traits<downcast_from<hour>> : downcast_to<hour> {}; template<> struct downcast_traits<downcast_base_t<hour>> : std::type_identity<hour> {};
inline namespace literals { inline namespace literals {

View File

@@ -28,19 +28,19 @@
namespace units { namespace units {
struct velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {}; struct velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
template<> struct downcasting_traits<downcast_from<velocity>> : downcast_to<velocity> {}; template<> struct downcast_traits<downcast_base_t<velocity>> : std::type_identity<velocity> {};
template<typename T> template<typename T>
concept bool Velocity = QuantityOf<T, velocity>; concept bool Velocity = QuantityOf<T, velocity>;
struct metre_per_second : derived_unit<velocity, metre, second> {}; struct metre_per_second : derived_unit<velocity, metre, second> {};
template<> struct downcasting_traits<downcast_from<metre_per_second>> : downcast_to<metre_per_second> {}; template<> struct downcast_traits<downcast_base_t<metre_per_second>> : std::type_identity<metre_per_second> {};
struct kilometre_per_hour : derived_unit<velocity, kilometre, hour> {}; struct kilometre_per_hour : derived_unit<velocity, kilometre, hour> {};
template<> struct downcasting_traits<downcast_from<kilometre_per_hour>> : downcast_to<kilometre_per_hour> {}; template<> struct downcast_traits<downcast_base_t<kilometre_per_hour>> : std::type_identity<kilometre_per_hour> {};
struct mile_per_hour : derived_unit<velocity, mile, hour> {}; struct mile_per_hour : derived_unit<velocity, mile, hour> {};
template<> struct downcasting_traits<downcast_from<mile_per_hour>> : downcast_to<mile_per_hour> {}; template<> struct downcast_traits<downcast_base_t<mile_per_hour>> : std::type_identity<mile_per_hour> {};
inline namespace literals { inline namespace literals {

View File

@@ -31,13 +31,13 @@
namespace units { namespace units {
struct voltage : make_dimension_t<exp<power, 1>, exp<base_dim_current, -1>> {}; struct voltage : make_dimension_t<exp<power, 1>, exp<base_dim_current, -1>> {};
template<> struct downcasting_traits<downcast_from<voltage>> : downcast_to<voltage> {}; template<> struct downcast_traits<downcast_base_t<voltage>> : std::type_identity<voltage> {};
template<typename T> template<typename T>
concept bool Voltage = QuantityOf<T, voltage>; concept bool Voltage = QuantityOf<T, voltage>;
struct volt : derived_unit<voltage, kilogram, metre, second, ampere> {}; struct volt : derived_unit<voltage, kilogram, metre, second, ampere> {};
template<> struct downcasting_traits<downcast_from<volt>> : downcast_to<volt> {}; template<> struct downcast_traits<downcast_base_t<volt>> : std::type_identity<volt> {};
inline namespace literals { inline namespace literals {

View File

@@ -27,25 +27,25 @@
namespace units { namespace units {
struct volume : make_dimension_t<exp<base_dim_length, 3>> {}; struct volume : make_dimension_t<exp<base_dim_length, 3>> {};
template<> struct downcasting_traits<downcast_from<volume>> : downcast_to<volume> {}; template<> struct downcast_traits<downcast_base_t<volume>> : std::type_identity<volume> {};
template<typename T> template<typename T>
concept bool Volume = QuantityOf<T, volume>; concept bool Volume = QuantityOf<T, volume>;
struct cubic_millimetre : derived_unit<volume, millimetre> {}; struct cubic_millimetre : derived_unit<volume, millimetre> {};
template<> struct downcasting_traits<downcast_from<cubic_millimetre>> : downcast_to<cubic_millimetre> {}; template<> struct downcast_traits<downcast_base_t<cubic_millimetre>> : std::type_identity<cubic_millimetre> {};
struct cubic_centimetre : derived_unit<volume, centimetre> {}; struct cubic_centimetre : derived_unit<volume, centimetre> {};
template<> struct downcasting_traits<downcast_from<cubic_centimetre>> : downcast_to<cubic_centimetre> {}; template<> struct downcast_traits<downcast_base_t<cubic_centimetre>> : std::type_identity<cubic_centimetre> {};
struct cubic_metre : derived_unit<volume, metre> {}; struct cubic_metre : derived_unit<volume, metre> {};
template<> struct downcasting_traits<downcast_from<cubic_metre>> : downcast_to<cubic_metre> {}; template<> struct downcast_traits<downcast_base_t<cubic_metre>> : std::type_identity<cubic_metre> {};
struct cubic_kilometre : derived_unit<volume, kilometre, metre> {}; struct cubic_kilometre : derived_unit<volume, kilometre, metre> {};
template<> struct downcasting_traits<downcast_from<cubic_kilometre>> : downcast_to<cubic_kilometre> {}; template<> struct downcast_traits<downcast_base_t<cubic_kilometre>> : std::type_identity<cubic_kilometre> {};
struct cubic_foot : derived_unit<volume, foot> {}; struct cubic_foot : derived_unit<volume, foot> {};
template<> struct downcasting_traits<downcast_from<cubic_foot>> : downcast_to<cubic_foot> {}; template<> struct downcast_traits<downcast_base_t<cubic_foot>> : std::type_identity<cubic_foot> {};
inline namespace literals { inline namespace literals {

View File

@@ -32,7 +32,7 @@ namespace units {
{ {
using dim = dimension_pow_t<typename U::dimension, N>; using dim = dimension_pow_t<typename U::dimension, N>;
using r = ratio_pow<typename U::ratio, N>; using r = ratio_pow<typename U::ratio, N>;
return quantity<downcasting_traits_t<unit<dim, r>>, Rep>(std::pow(q.count(), N)); return quantity<downcast_traits_t<unit<dim, r>>, Rep>(std::pow(q.count(), N));
} }
template<typename U, typename Rep> template<typename U, typename Rep>
@@ -40,7 +40,7 @@ namespace units {
{ {
using dim = dimension_sqrt_t<typename U::dimension>; using dim = dimension_sqrt_t<typename U::dimension>;
using r = ratio_sqrt<typename U::ratio>; using r = ratio_sqrt<typename U::ratio>;
return quantity<downcasting_traits_t<unit<dim, r>>, Rep>(std::sqrt(q.count())); return quantity<downcast_traits_t<unit<dim, r>>, Rep>(std::sqrt(q.count()));
} }
} // namespace units } // namespace units

View File

@@ -71,7 +71,7 @@ namespace units {
template<typename U1, typename Rep1, typename U2, typename Rep2, typename Rep> template<typename U1, typename Rep1, typename U2, typename Rep2, typename Rep>
requires same_dim<typename U1::dimension, typename U2::dimension> requires same_dim<typename U1::dimension, typename U2::dimension>
struct common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, Rep> { struct common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, Rep> {
using type = quantity<downcasting_traits_t<unit<typename U1::dimension, common_ratio<typename U1::ratio, typename U2::ratio>>>, Rep>; using type = quantity<downcast_traits_t<unit<typename U1::dimension, 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>>
@@ -307,7 +307,7 @@ namespace units {
{ {
using dim = dimension_multiply_t<typename U1::dimension, typename U2::dimension>; using dim = dimension_multiply_t<typename U1::dimension, typename U2::dimension>;
using common_rep = decltype(lhs.count() * rhs.count()); using common_rep = decltype(lhs.count() * rhs.count());
using ret = quantity<downcasting_traits_t<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>; using ret = quantity<downcast_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());
} }
@@ -321,7 +321,7 @@ namespace units {
using dim = dim_invert_t<typename U::dimension>; using dim = dim_invert_t<typename U::dimension>;
using common_rep = decltype(v / q.count()); using common_rep = decltype(v / q.count());
using ret = quantity<downcasting_traits_t<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>; using ret = quantity<downcast_traits_t<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
using den = quantity<U, common_rep>; using den = quantity<U, common_rep>;
return ret(v / den(q).count()); return ret(v / den(q).count());
} }
@@ -362,7 +362,7 @@ namespace units {
using common_rep = decltype(lhs.count() / rhs.count()); using common_rep = decltype(lhs.count() / rhs.count());
using dim = dimension_divide_t<typename U1::dimension, typename U2::dimension>; using dim = dimension_divide_t<typename U1::dimension, typename U2::dimension>;
using ret = quantity<downcasting_traits_t<unit<dim, ratio_divide<typename U1::ratio, typename U2::ratio>>>, common_rep>; using ret = quantity<downcast_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());
} }

View File

@@ -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<downcast_from<T>>; detail::is_unit<downcast_base_t<T>>;
// derived_unit // derived_unit

View File

@@ -119,7 +119,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<downcast_from<T>>; detail::is_dimension<downcast_base_t<T>>;
// dim_invert // dim_invert
@@ -128,7 +128,7 @@ namespace units {
struct dim_invert; struct dim_invert;
template<Exponent... Es> template<Exponent... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_invert_t<Es>...>>> {}; struct dim_invert<dimension<Es...>> : std::type_identity<downcast_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;
@@ -195,7 +195,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<downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {}; struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_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;

View File

@@ -119,7 +119,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<downcast_from<T>>; detail::is_dimension<downcast_base_t<T>>;
// dim_invert // dim_invert
@@ -128,7 +128,7 @@ namespace units {
struct dim_invert; struct dim_invert;
template<typename... Es> template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_invert_t<Es>...>>> {}; struct dim_invert<dimension<Es...>> : std::type_identity<downcast_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;
@@ -195,7 +195,7 @@ namespace units {
struct dimension_multiply; struct dimension_multiply;
template<typename... E1, typename... E2> template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {}; struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_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;

View File

@@ -99,7 +99,7 @@ namespace units {
struct dim_invert; struct dim_invert;
template<typename... Es> template<typename... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<downcasting_traits_t<dimension<exp_invert_t<Es>...>>> {}; struct dim_invert<dimension<Es...>> : std::type_identity<downcast_traits_t<dimension<exp_invert_t<Es>...>>> {};
template<typename D> template<typename D>
using dim_invert_t = dim_invert<typename D::base_type>::type; using dim_invert_t = dim_invert<typename D::base_type>::type;
@@ -166,7 +166,7 @@ namespace units {
struct dimension_multiply; struct dimension_multiply;
template<typename... E1, typename... E2> template<typename... E1, typename... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcasting_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {}; struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_traits_t<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
template<typename D1, typename D2> template<typename D1, typename 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;

View File

@@ -40,15 +40,12 @@ namespace units {
std::derived_from<T, downcast_base<typename T::base_type>>; std::derived_from<T, downcast_base<typename T::base_type>>;
template<Downcastable T> template<Downcastable T>
using downcast_from = T::base_type; using downcast_base_t = T::base_type;
template<Downcastable T> template<Downcastable T>
using downcast_to = std::type_identity<T>; struct downcast_traits : std::type_identity<T> {};
template<Downcastable T> template<Downcastable T>
struct downcasting_traits : downcast_to<T> {}; using downcast_traits_t = downcast_traits<T>::type;
template<Downcastable T>
using downcasting_traits_t = downcasting_traits<T>::type;
} // namespace units } // namespace units

View File

@@ -33,15 +33,12 @@ namespace units {
}; };
template<typename T> template<typename T>
using downcast_from = T::base_type; using downcast_base_t = T::base_type;
template<typename T> template<typename T>
using downcast_to = std::type_identity<T>; struct downcast_traits : std::type_identity<T> {};
template<typename T> template<typename T>
struct downcasting_traits : downcast_to<T> {}; using downcast_traits_t = downcast_traits<T>::type;
template<typename T>
using downcasting_traits_t = downcasting_traits<T>::type;
} // namespace units } // namespace units

View File

@@ -49,9 +49,9 @@ namespace {
} }
} }
template<> struct units::downcasting_traits<units::downcast_from<digital_information>> : units::downcast_to<digital_information> {}; template<> struct units::downcast_traits<units::downcast_base_t<digital_information>> : std::type_identity<digital_information> {};
template<> struct units::downcasting_traits<units::downcast_from<bit>> : units::downcast_to<bit> {}; template<> struct units::downcast_traits<units::downcast_base_t<bit>> : std::type_identity<bit> {};
template<> struct units::downcasting_traits<units::downcast_from<::byte>> : units::downcast_to<::byte> {}; template<> struct units::downcast_traits<units::downcast_base_t<::byte>> : std::type_identity<::byte> {};
namespace { namespace {
@@ -76,11 +76,11 @@ namespace {
namespace units { namespace units {
template<> struct downcasting_traits<downcast_from<power_spectral_density>> : downcast_to<power_spectral_density> {}; template<> struct downcast_traits<downcast_base_t<power_spectral_density>> : std::type_identity<power_spectral_density> {};
template<> struct downcasting_traits<downcast_from<sq_volt_per_hertz>> : downcast_to<sq_volt_per_hertz> {}; template<> struct downcast_traits<downcast_base_t<sq_volt_per_hertz>> : std::type_identity<sq_volt_per_hertz> {};
template<> struct downcasting_traits<downcast_from<amplitude_spectral_density>> : downcast_to<amplitude_spectral_density> {}; template<> struct downcast_traits<downcast_base_t<amplitude_spectral_density>> : std::type_identity<amplitude_spectral_density> {};
template<> struct downcasting_traits<downcast_from<volt_per_sqrt_hertz>> : downcast_to<volt_per_sqrt_hertz> {}; template<> struct downcast_traits<downcast_base_t<volt_per_sqrt_hertz>> : std::type_identity<volt_per_sqrt_hertz> {};
} }