mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 18:37:15 +02:00
refactor: units no longer inherit from each other
This commit is contained in:
@ -62,6 +62,13 @@ struct propagate_point_origin<U, true> {
|
|||||||
static constexpr auto point_origin = U::point_origin;
|
static constexpr auto point_origin = U::point_origin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<Magnitude auto M, Unit U>
|
||||||
|
struct scaled_unit_impl : detail::propagate_point_origin<U> {
|
||||||
|
using _base_type_ = scaled_unit_impl; // exposition only
|
||||||
|
static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M;
|
||||||
|
static constexpr U reference_unit{};
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,10 +81,7 @@ struct propagate_point_origin<U, true> {
|
|||||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||||
*/
|
*/
|
||||||
template<Magnitude auto M, Unit U>
|
template<Magnitude auto M, Unit U>
|
||||||
struct scaled_unit : detail::propagate_point_origin<U> {
|
struct scaled_unit final : detail::scaled_unit_impl<M, U> {};
|
||||||
static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M;
|
|
||||||
static constexpr U reference_unit{};
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@ -137,6 +141,7 @@ struct named_unit;
|
|||||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS>
|
template<symbol_text Symbol, detail::QuantityKindSpec auto QS>
|
||||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||||
struct named_unit<Symbol, QS> {
|
struct named_unit<Symbol, QS> {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||||
static constexpr auto quantity_spec = QS;
|
static constexpr auto quantity_spec = QS;
|
||||||
};
|
};
|
||||||
@ -144,6 +149,7 @@ struct named_unit<Symbol, QS> {
|
|||||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
template<symbol_text Symbol, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||||
struct named_unit<Symbol, QS, PO> {
|
struct named_unit<Symbol, QS, PO> {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||||
static constexpr auto quantity_spec = QS;
|
static constexpr auto quantity_spec = QS;
|
||||||
static constexpr auto point_origin = PO;
|
static constexpr auto point_origin = PO;
|
||||||
@ -162,6 +168,7 @@ struct named_unit<Symbol, QS, PO> {
|
|||||||
template<symbol_text Symbol>
|
template<symbol_text Symbol>
|
||||||
requires(!Symbol.empty())
|
requires(!Symbol.empty())
|
||||||
struct named_unit<Symbol> {
|
struct named_unit<Symbol> {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -175,13 +182,15 @@ struct named_unit<Symbol> {
|
|||||||
*/
|
*/
|
||||||
template<symbol_text Symbol, Unit auto U>
|
template<symbol_text Symbol, Unit auto U>
|
||||||
requires(!Symbol.empty())
|
requires(!Symbol.empty())
|
||||||
struct named_unit<Symbol, U> : decltype(U) {
|
struct named_unit<Symbol, U> : decltype(U)::_base_type_ {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
template<symbol_text Symbol, Unit auto U, PointOrigin auto PO>
|
template<symbol_text Symbol, Unit auto U, PointOrigin auto PO>
|
||||||
requires(!Symbol.empty())
|
requires(!Symbol.empty())
|
||||||
struct named_unit<Symbol, U, PO> : decltype(U) {
|
struct named_unit<Symbol, U, PO> : decltype(U)::_base_type_ {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||||
static constexpr auto point_origin = PO;
|
static constexpr auto point_origin = PO;
|
||||||
};
|
};
|
||||||
@ -197,14 +206,16 @@ struct named_unit<Symbol, U, PO> : decltype(U) {
|
|||||||
*/
|
*/
|
||||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS>
|
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS>
|
||||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||||
struct named_unit<Symbol, U, QS> : decltype(U) {
|
struct named_unit<Symbol, U, QS> : decltype(U)::_base_type_ {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||||
static constexpr auto quantity_spec = QS;
|
static constexpr auto quantity_spec = QS;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||||
struct named_unit<Symbol, U, QS, PO> : decltype(U) {
|
struct named_unit<Symbol, U, QS, PO> : decltype(U)::_base_type_ {
|
||||||
|
using _base_type_ = named_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||||
static constexpr auto quantity_spec = QS;
|
static constexpr auto quantity_spec = QS;
|
||||||
static constexpr auto point_origin = PO;
|
static constexpr auto point_origin = PO;
|
||||||
@ -234,7 +245,8 @@ struct named_unit<Symbol, U, QS, PO> : decltype(U) {
|
|||||||
*/
|
*/
|
||||||
MP_UNITS_EXPORT template<symbol_text Symbol, Magnitude auto M, PrefixableUnit auto U>
|
MP_UNITS_EXPORT template<symbol_text Symbol, Magnitude auto M, PrefixableUnit auto U>
|
||||||
requires(!Symbol.empty())
|
requires(!Symbol.empty())
|
||||||
struct prefixed_unit : decltype(M * U) {
|
struct prefixed_unit : decltype(M * U)::_base_type_ {
|
||||||
|
using _base_type_ = prefixed_unit; // exposition only
|
||||||
static constexpr auto symbol = Symbol + U.symbol;
|
static constexpr auto symbol = Symbol + U.symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -243,6 +255,11 @@ namespace detail {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_one : std::false_type {};
|
struct is_one : std::false_type {};
|
||||||
|
|
||||||
|
template<DerivedUnitExpr... Expr>
|
||||||
|
struct derived_unit_impl : detail::expr_fractions<detail::is_one, Expr...> {
|
||||||
|
using _base_type_ = derived_unit_impl; // exposition only
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,7 +308,7 @@ struct is_one : std::false_type {};
|
|||||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||||
*/
|
*/
|
||||||
template<detail::DerivedUnitExpr... Expr>
|
template<detail::DerivedUnitExpr... Expr>
|
||||||
struct derived_unit : detail::expr_fractions<detail::is_one, Expr...> {};
|
struct derived_unit : detail::derived_unit_impl<Expr...> {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unit one
|
* @brief Unit one
|
||||||
@ -299,7 +316,7 @@ struct derived_unit : detail::expr_fractions<detail::is_one, Expr...> {};
|
|||||||
* Unit of a dimensionless quantity.
|
* Unit of a dimensionless quantity.
|
||||||
*/
|
*/
|
||||||
// clang-format off
|
// clang-format off
|
||||||
MP_UNITS_EXPORT inline constexpr struct one : derived_unit<> {} one;
|
MP_UNITS_EXPORT inline constexpr struct one : detail::derived_unit_impl<> {} one;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -337,10 +354,10 @@ template<typename T, typename F, int Num, int... Den>
|
|||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power<F, Num, Den...>&);
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power<F, Num, Den...>&);
|
||||||
|
|
||||||
template<Unit T, typename... Expr>
|
template<Unit T, typename... Expr>
|
||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit<Expr...>&);
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit_impl<Expr...>&);
|
||||||
|
|
||||||
template<Unit T, auto M, typename U>
|
template<Unit T, auto M, typename U>
|
||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit<M, U>&)
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit_impl<M, U>&)
|
||||||
{
|
{
|
||||||
using base = decltype(get_canonical_unit_impl(U{}, U{}));
|
using base = decltype(get_canonical_unit_impl(U{}, U{}));
|
||||||
return canonical_unit<decltype(M * base::mag){}, base::reference_unit>{};
|
return canonical_unit<decltype(M * base::mag){}, base::reference_unit>{};
|
||||||
@ -392,10 +409,10 @@ template<typename... Us>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<Unit T, typename... Expr>
|
template<Unit T, typename... Expr>
|
||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit<Expr...>&)
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit_impl<Expr...>&)
|
||||||
{
|
{
|
||||||
using num = decltype(get_canonical_unit_impl(typename derived_unit<Expr...>::_num_{}));
|
using num = decltype(get_canonical_unit_impl(typename derived_unit_impl<Expr...>::_num_{}));
|
||||||
using den = decltype(get_canonical_unit_impl(typename derived_unit<Expr...>::_den_{}));
|
using den = decltype(get_canonical_unit_impl(typename derived_unit_impl<Expr...>::_den_{}));
|
||||||
return canonical_unit<decltype(num::mag / den::mag){}, decltype(num::reference_unit / den::reference_unit){}>{};
|
return canonical_unit<decltype(num::mag / den::mag){}, decltype(num::reference_unit / den::reference_unit){}>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,9 +616,9 @@ template<Unit U1, Unit U2>
|
|||||||
requires(decltype(detail::have_same_canonical_reference_unit(u1, u2))::value)
|
requires(decltype(detail::have_same_canonical_reference_unit(u1, u2))::value)
|
||||||
{
|
{
|
||||||
if constexpr (U1{} == U2{}) {
|
if constexpr (U1{} == U2{}) {
|
||||||
if constexpr (std::derived_from<U1, U2>)
|
if constexpr (std::derived_from<U1, typename U2::_base_type_>)
|
||||||
return u1;
|
return u1;
|
||||||
else if constexpr (std::derived_from<U2, U1>)
|
else if constexpr (std::derived_from<U2, typename U1::_base_type_>)
|
||||||
return u2;
|
return u2;
|
||||||
else
|
else
|
||||||
// TODO Check if there is a better choice here
|
// TODO Check if there is a better choice here
|
||||||
@ -695,7 +712,7 @@ constexpr Out unit_symbol_impl(Out out, U, const unit_symbol_formatting& fmt, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename CharT, std::output_iterator<CharT> Out, auto M, typename U>
|
template<typename CharT, std::output_iterator<CharT> Out, auto M, typename U>
|
||||||
constexpr Out unit_symbol_impl(Out out, const scaled_unit<M, U>& u, const unit_symbol_formatting& fmt,
|
constexpr Out unit_symbol_impl(Out out, const scaled_unit_impl<M, U>& u, const unit_symbol_formatting& fmt,
|
||||||
bool negative_power)
|
bool negative_power)
|
||||||
{
|
{
|
||||||
if constexpr (M == mag<1>) {
|
if constexpr (M == mag<1>) {
|
||||||
@ -764,13 +781,13 @@ constexpr Out unit_symbol_impl(Out out, const type_list<Nums...>& nums, const ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
|
template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
|
||||||
constexpr Out unit_symbol_impl(Out out, const derived_unit<Expr...>&, const unit_symbol_formatting& fmt,
|
constexpr Out unit_symbol_impl(Out out, const derived_unit_impl<Expr...>&, const unit_symbol_formatting& fmt,
|
||||||
bool negative_power)
|
bool negative_power)
|
||||||
{
|
{
|
||||||
(void)negative_power;
|
(void)negative_power;
|
||||||
MP_UNITS_EXPECTS(negative_power == false);
|
MP_UNITS_EXPECTS(negative_power == false);
|
||||||
return unit_symbol_impl<CharT>(out, typename derived_unit<Expr...>::_num_{}, typename derived_unit<Expr...>::_den_{},
|
return unit_symbol_impl<CharT>(out, typename derived_unit_impl<Expr...>::_num_{},
|
||||||
fmt);
|
typename derived_unit_impl<Expr...>::_den_{}, fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -52,6 +52,8 @@ struct scaled_unit;
|
|||||||
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
||||||
struct named_unit;
|
struct named_unit;
|
||||||
|
|
||||||
|
MP_UNITS_EXPORT struct one;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<symbol_text Symbol, auto... Args>
|
template<symbol_text Symbol, auto... Args>
|
||||||
@ -126,9 +128,14 @@ void is_unit_impl(const scaled_unit<M, U>*);
|
|||||||
template<symbol_text Symbol, auto... Args>
|
template<symbol_text Symbol, auto... Args>
|
||||||
void is_unit_impl(const named_unit<Symbol, Args...>*);
|
void is_unit_impl(const named_unit<Symbol, Args...>*);
|
||||||
|
|
||||||
|
template<symbol_text Symbol, auto M, auto U>
|
||||||
|
void is_unit_impl(const prefixed_unit<Symbol, M, U>*);
|
||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
void is_unit_impl(const derived_unit<Expr...>*);
|
void is_unit_impl(const derived_unit<Expr...>*);
|
||||||
|
|
||||||
|
void is_unit_impl(const one*);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_specialization_of_unit = false;
|
inline constexpr bool is_specialization_of_unit = false;
|
||||||
|
|
||||||
|
@ -138,8 +138,6 @@ static_assert(!detail::QuantityKindSpec<int>);
|
|||||||
// TODO add tests
|
// TODO add tests
|
||||||
|
|
||||||
// Unit
|
// Unit
|
||||||
struct metre_per_second : decltype(si::metre / si::second) {};
|
|
||||||
|
|
||||||
static_assert(Unit<struct si::metre>);
|
static_assert(Unit<struct si::metre>);
|
||||||
static_assert(Unit<decltype(si::kilogram)>);
|
static_assert(Unit<decltype(si::kilogram)>);
|
||||||
static_assert(Unit<decltype(si::kilo<si::gram>)>);
|
static_assert(Unit<decltype(si::kilo<si::gram>)>);
|
||||||
@ -151,13 +149,12 @@ static_assert(Unit<decltype(square(si::metre))>);
|
|||||||
static_assert(Unit<decltype(pow<2>(si::metre))>);
|
static_assert(Unit<decltype(pow<2>(si::metre))>);
|
||||||
static_assert(Unit<struct si::standard_gravity>);
|
static_assert(Unit<struct si::standard_gravity>);
|
||||||
static_assert(Unit<scaled_unit<mag<10>, struct si::second>>);
|
static_assert(Unit<scaled_unit<mag<10>, struct si::second>>);
|
||||||
static_assert(Unit<metre_per_second>);
|
|
||||||
static_assert(Unit<derived_unit<struct si::metre, per<struct si::second>>>);
|
static_assert(Unit<derived_unit<struct si::metre, per<struct si::second>>>);
|
||||||
static_assert(Unit<struct one>);
|
static_assert(Unit<struct one>);
|
||||||
static_assert(!Unit<named_unit<"?", isq::length>>);
|
static_assert(!Unit<named_unit<"?", kind_of<isq::length>>>);
|
||||||
static_assert(!Unit<named_unit<"?">>);
|
static_assert(!Unit<named_unit<"?">>);
|
||||||
static_assert(!Unit<named_unit<"?", si::metre / si::second>>);
|
static_assert(!Unit<named_unit<"?", si::metre / si::second>>);
|
||||||
static_assert(!Unit<named_unit<"?", si::metre, isq::length>>);
|
static_assert(!Unit<named_unit<"?", si::metre, kind_of<isq::length>>>);
|
||||||
static_assert(!Unit<prefixed_unit<"?", mag<10>, si::second>>);
|
static_assert(!Unit<prefixed_unit<"?", mag<10>, si::second>>);
|
||||||
static_assert(!Unit<struct isq::dim_length>);
|
static_assert(!Unit<struct isq::dim_length>);
|
||||||
static_assert(!Unit<int>);
|
static_assert(!Unit<int>);
|
||||||
@ -177,13 +174,12 @@ static_assert(!detail::NamedUnit<decltype(square(si::metre))>);
|
|||||||
static_assert(!detail::NamedUnit<decltype(pow<2>(si::metre))>);
|
static_assert(!detail::NamedUnit<decltype(pow<2>(si::metre))>);
|
||||||
static_assert(detail::NamedUnit<struct si::standard_gravity>);
|
static_assert(detail::NamedUnit<struct si::standard_gravity>);
|
||||||
static_assert(!detail::NamedUnit<scaled_unit<mag<10>, struct si::second>>);
|
static_assert(!detail::NamedUnit<scaled_unit<mag<10>, struct si::second>>);
|
||||||
static_assert(!detail::NamedUnit<metre_per_second>);
|
|
||||||
static_assert(!detail::NamedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
static_assert(!detail::NamedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
||||||
static_assert(!detail::NamedUnit<struct one>);
|
static_assert(!detail::NamedUnit<struct one>);
|
||||||
static_assert(!detail::NamedUnit<named_unit<"?", isq::length>>);
|
static_assert(!detail::NamedUnit<named_unit<"?", kind_of<isq::length>>>);
|
||||||
static_assert(!detail::NamedUnit<named_unit<"?">>);
|
static_assert(!detail::NamedUnit<named_unit<"?">>);
|
||||||
static_assert(!detail::NamedUnit<named_unit<"?", si::metre / si::second>>);
|
static_assert(!detail::NamedUnit<named_unit<"?", si::metre / si::second>>);
|
||||||
static_assert(!detail::NamedUnit<named_unit<"?", si::metre, isq::length>>);
|
static_assert(!detail::NamedUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
|
||||||
static_assert(!detail::NamedUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
static_assert(!detail::NamedUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
||||||
static_assert(!detail::NamedUnit<struct isq::dim_length>);
|
static_assert(!detail::NamedUnit<struct isq::dim_length>);
|
||||||
static_assert(!detail::NamedUnit<int>);
|
static_assert(!detail::NamedUnit<int>);
|
||||||
@ -203,13 +199,12 @@ static_assert(!PrefixableUnit<decltype(square(si::metre))>);
|
|||||||
static_assert(!PrefixableUnit<decltype(pow<2>(si::metre))>);
|
static_assert(!PrefixableUnit<decltype(pow<2>(si::metre))>);
|
||||||
static_assert(PrefixableUnit<struct si::standard_gravity>);
|
static_assert(PrefixableUnit<struct si::standard_gravity>);
|
||||||
static_assert(!PrefixableUnit<scaled_unit<mag<10>, struct si::second>>);
|
static_assert(!PrefixableUnit<scaled_unit<mag<10>, struct si::second>>);
|
||||||
static_assert(!PrefixableUnit<metre_per_second>);
|
|
||||||
static_assert(!PrefixableUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
static_assert(!PrefixableUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
||||||
static_assert(!PrefixableUnit<struct one>);
|
static_assert(!PrefixableUnit<struct one>);
|
||||||
static_assert(!PrefixableUnit<named_unit<"?", isq::length>>);
|
static_assert(!PrefixableUnit<named_unit<"?", kind_of<isq::length>>>);
|
||||||
static_assert(!PrefixableUnit<named_unit<"?">>);
|
static_assert(!PrefixableUnit<named_unit<"?">>);
|
||||||
static_assert(!PrefixableUnit<named_unit<"?", si::metre / si::second>>);
|
static_assert(!PrefixableUnit<named_unit<"?", si::metre / si::second>>);
|
||||||
static_assert(!PrefixableUnit<named_unit<"?", si::metre, isq::length>>);
|
static_assert(!PrefixableUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
|
||||||
static_assert(!PrefixableUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
static_assert(!PrefixableUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
||||||
static_assert(!PrefixableUnit<struct isq::dim_length>);
|
static_assert(!PrefixableUnit<struct isq::dim_length>);
|
||||||
static_assert(!PrefixableUnit<int>);
|
static_assert(!PrefixableUnit<int>);
|
||||||
@ -229,13 +224,12 @@ static_assert(AssociatedUnit<decltype(square(si::metre))>);
|
|||||||
static_assert(AssociatedUnit<decltype(pow<2>(si::metre))>);
|
static_assert(AssociatedUnit<decltype(pow<2>(si::metre))>);
|
||||||
static_assert(AssociatedUnit<struct si::standard_gravity>);
|
static_assert(AssociatedUnit<struct si::standard_gravity>);
|
||||||
static_assert(AssociatedUnit<scaled_unit<mag<10>, struct si::second>>);
|
static_assert(AssociatedUnit<scaled_unit<mag<10>, struct si::second>>);
|
||||||
static_assert(AssociatedUnit<metre_per_second>);
|
|
||||||
static_assert(AssociatedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
static_assert(AssociatedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
|
||||||
static_assert(AssociatedUnit<struct one>);
|
static_assert(AssociatedUnit<struct one>);
|
||||||
static_assert(!AssociatedUnit<named_unit<"?", isq::length>>);
|
static_assert(!AssociatedUnit<named_unit<"?", kind_of<isq::length>>>);
|
||||||
static_assert(!AssociatedUnit<named_unit<"?">>);
|
static_assert(!AssociatedUnit<named_unit<"?">>);
|
||||||
static_assert(!AssociatedUnit<named_unit<"?", si::metre / si::second>>);
|
static_assert(!AssociatedUnit<named_unit<"?", si::metre / si::second>>);
|
||||||
static_assert(!AssociatedUnit<named_unit<"?", si::metre, isq::length>>);
|
static_assert(!AssociatedUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
|
||||||
static_assert(!AssociatedUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
static_assert(!AssociatedUnit<prefixed_unit<"?", mag<10>, si::second>>);
|
||||||
static_assert(!AssociatedUnit<struct isq::dim_length>);
|
static_assert(!AssociatedUnit<struct isq::dim_length>);
|
||||||
static_assert(!AssociatedUnit<int>);
|
static_assert(!AssociatedUnit<int>);
|
||||||
|
@ -192,7 +192,7 @@ static_assert(is_of_type<2 * m_per_s, quantity<reference<speed_, derived_unit<me
|
|||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
120 * length[kilometre] / (2 * time[hour]),
|
120 * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{}, int>>);
|
||||||
static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]);
|
static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
@ -201,14 +201,14 @@ static_assert(
|
|||||||
const auto duration = 2;
|
const auto duration = 2;
|
||||||
return distance * length[kilometre] / (duration * time[hour]);
|
return distance * length[kilometre] / (duration * time[hour]);
|
||||||
}(),
|
}(),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{}, int>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
|
is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
|
||||||
std::int64_t>>);
|
std::int64_t>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<120.L * length[kilometre] / (2 * time[hour]),
|
is_of_type<120.L * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<std::remove_const_t<decltype(si::kilo<metre>)>, per<hour_>>>{},
|
||||||
long double>>);
|
long double>>);
|
||||||
|
|
||||||
static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>);
|
static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>);
|
||||||
@ -226,7 +226,7 @@ static_assert(is_of_type<42 * nu::length[nu::second] / (42 * nu::time[nu::second
|
|||||||
static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity<reference<speed_, one_>{}, int>>);
|
static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity<reference<speed_, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::speed[one], quantity<reference<speed_, one_>{}, int>>);
|
static_assert(is_of_type<42 * nu::speed[one], quantity<reference<speed_, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]),
|
static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>, kilogram_>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>, std::remove_const_t<decltype(si::kilo<gram>)>>{}, int>>);
|
||||||
|
|
||||||
template<auto dim, auto unit>
|
template<auto dim, auto unit>
|
||||||
concept invalid_nu_unit = !requires { dim[unit]; };
|
concept invalid_nu_unit = !requires { dim[unit]; };
|
||||||
|
Reference in New Issue
Block a user