mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 12:24:26 +02:00
feat: PointOrigin
arithmetics support added
This commit is contained in:
@@ -116,8 +116,34 @@ template<typename T>
|
||||
requires is_derived_from_specialization_of_quantity_point<T>
|
||||
inline constexpr bool is_quantity_point<T> = true;
|
||||
|
||||
// the below was introduced to workaround gcc-12 bug that produced an error
|
||||
// "error: ‘const struct mp_units::isq::time’ has no member named ‘absolute_point_origin’"
|
||||
template<typename PO1, typename PO2>
|
||||
constexpr bool same_absolute_point_origins_lazy(PO1, PO2)
|
||||
{
|
||||
if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1> &&
|
||||
is_derived_from_specialization_of_relative_point_origin<PO2>)
|
||||
return std::same_as<std::remove_const_t<decltype(PO1::absolute_point_origin)>,
|
||||
std::remove_const_t<decltype(PO2::absolute_point_origin)>>;
|
||||
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1>)
|
||||
return std::same_as<std::remove_const_t<decltype(PO1::absolute_point_origin)>, PO2>;
|
||||
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO2>)
|
||||
return std::same_as<PO1, std::remove_const_t<decltype(PO2::absolute_point_origin)>>;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename PO1, auto PO2>
|
||||
concept PointOriginOf =
|
||||
PointOrigin<PO1> && PointOrigin<std::remove_const_t<decltype(PO2)>> &&
|
||||
(std::same_as<PO1, std::remove_const_t<decltype(PO2)>> || detail::same_absolute_point_origins_lazy(PO1{}, PO2) ||
|
||||
(detail::is_specialization_of_absolute_point_origin<PO1> &&
|
||||
detail::is_specialization_of_absolute_point_origin<std::remove_const_t<decltype(PO2)>> &&
|
||||
implicitly_convertible(PO1::quantity_spec, PO2.quantity_spec) &&
|
||||
!detail::NestedQuantityKindSpecOf<PO1::quantity_spec, PO2.quantity_spec>));
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantity points with provided dimension or quantity spec
|
||||
*
|
||||
@@ -127,15 +153,8 @@ inline constexpr bool is_quantity_point<T> = true;
|
||||
*/
|
||||
template<typename QP, auto V>
|
||||
concept QuantityPointOf =
|
||||
QuantityPoint<QP> &&
|
||||
(ReferenceOf<std::remove_const_t<decltype(QP::reference)>, V> ||
|
||||
(PointOrigin<std::remove_const_t<decltype(V)>> &&
|
||||
(std::same_as<std::remove_const_t<decltype(QP::point_origin)>, std::remove_const_t<decltype(V)>> ||
|
||||
std::same_as<std::remove_const_t<decltype(QP::absolute_point_origin)>, std::remove_const_t<decltype(V)>> ||
|
||||
(detail::is_specialization_of_absolute_point_origin<std::remove_const_t<decltype(QP::absolute_point_origin)>> &&
|
||||
detail::is_specialization_of_absolute_point_origin<std::remove_const_t<decltype(V)>> &&
|
||||
implicitly_convertible(QP::absolute_point_origin.quantity_spec, V.quantity_spec) &&
|
||||
!detail::DerivedFromQuantityKindSpecOf<QP::absolute_point_origin.quantity_spec, V.quantity_spec>))));
|
||||
QuantityPoint<QP> && (ReferenceOf<std::remove_const_t<decltype(QP::reference)>, V> ||
|
||||
PointOriginOf<std::remove_const_t<decltype(QP::absolute_point_origin)>, V>);
|
||||
|
||||
/**
|
||||
* @brief A concept matching all external quantity point like types
|
||||
|
@@ -37,7 +37,9 @@ struct absolute_point_origin {
|
||||
template<QuantityPoint auto QP>
|
||||
struct relative_point_origin {
|
||||
static constexpr QuantityPoint auto quantity_point = QP;
|
||||
static constexpr QuantitySpec auto quantity_spec = QP.quantity_spec;
|
||||
static constexpr QuantitySpec auto quantity_spec =
|
||||
common_quantity_spec(QP.quantity_spec, QP.point_origin.quantity_spec);
|
||||
static constexpr PointOrigin auto absolute_point_origin = QP.absolute_point_origin;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
@@ -114,16 +116,17 @@ public:
|
||||
|
||||
template<QuantityPointOf<absolute_point_origin> QP>
|
||||
requires std::constructible_from<quantity_type, typename QP::quantity_type>
|
||||
// TODO add perfect forwarding
|
||||
constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) quantity_point(const QP& qp) :
|
||||
q_([&] {
|
||||
if constexpr (is_same_v<std::remove_const_t<decltype(point_origin)>,
|
||||
std::remove_const_t<decltype(QP::point_origin)>>) {
|
||||
return qp.relative();
|
||||
} else if constexpr (detail::is_derived_from_specialization_of_relative_point_origin<
|
||||
} else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<
|
||||
std::remove_const_t<decltype(point_origin)>>) {
|
||||
return qp.absolute() - zero().absolute();
|
||||
} else {
|
||||
return qp.absolute();
|
||||
} else {
|
||||
return qp.absolute() - zero().absolute();
|
||||
}
|
||||
}())
|
||||
{
|
||||
@@ -146,11 +149,11 @@ public:
|
||||
{
|
||||
if constexpr (is_same_v<NewPO, std::remove_const_t<decltype(point_origin)>>) {
|
||||
return *this;
|
||||
} else if constexpr (detail::is_derived_from_specialization_of_relative_point_origin<NewPO>) {
|
||||
auto q = absolute() - origin.quantity_point.absolute();
|
||||
} else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<NewPO>) {
|
||||
auto q = absolute();
|
||||
return quantity_point<reference, NewPO{}, typename decltype(q)::rep>(std::move(q));
|
||||
} else {
|
||||
auto q = absolute();
|
||||
auto q = absolute() - origin.quantity_point.absolute();
|
||||
return quantity_point<reference, NewPO{}, typename decltype(q)::rep>(std::move(q));
|
||||
}
|
||||
}
|
||||
@@ -242,35 +245,57 @@ explicit quantity_point(QP)
|
||||
template<auto R1, auto PO1, typename Rep1, auto R2, typename Rep2>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<std::remove_const_t<decltype(R2)>, get_quantity_spec(R1)>
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point<R1, PO1, Rep1>& lhs,
|
||||
const quantity<R2, Rep2>& rhs)
|
||||
requires requires { lhs.relative() + rhs; }
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point<R1, PO1, Rep1>& qp,
|
||||
const quantity<R2, Rep2>& q)
|
||||
requires requires { qp.relative() + q; }
|
||||
{
|
||||
const auto q = lhs.relative() + rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<q_type::reference, PO1, typename q_type::rep>(q);
|
||||
auto temp = qp.relative() + q;
|
||||
using q_type = decltype(temp);
|
||||
return quantity_point<q_type::reference, PO1, typename q_type::rep>(std::move(temp));
|
||||
}
|
||||
|
||||
template<auto R1, typename Rep1, auto R2, auto PO2, typename Rep2>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<std::remove_const_t<decltype(R1)>, get_quantity_spec(R2)>
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity<R1, Rep1>& lhs,
|
||||
const quantity_point<R2, PO2, Rep2>& rhs)
|
||||
requires requires { rhs + lhs; }
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity<R1, Rep1>& q,
|
||||
const quantity_point<R2, PO2, Rep2>& qp)
|
||||
requires requires { q + qp.relative(); }
|
||||
{
|
||||
return rhs + lhs;
|
||||
return qp + q;
|
||||
}
|
||||
|
||||
template<PointOrigin PO, Quantity Q>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, Q&& q)
|
||||
{
|
||||
return quantity_point<Q::reference, PO{}, typename Q::rep>(std::forward<Q>(q));
|
||||
}
|
||||
|
||||
template<Quantity Q, PointOrigin PO>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(Q&& q, PO po)
|
||||
{
|
||||
return po + std::forward<Q>(q);
|
||||
}
|
||||
|
||||
template<auto R1, auto PO1, typename Rep1, auto R2, typename Rep2>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<std::remove_const_t<decltype(R2)>, get_quantity_spec(R1)>
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point<R1, PO1, Rep1>& lhs,
|
||||
const quantity<R2, Rep2>& rhs)
|
||||
requires requires { lhs.relative() - rhs; }
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point<R1, PO1, Rep1>& qp,
|
||||
const quantity<R2, Rep2>& q)
|
||||
requires requires { qp.relative() - q; }
|
||||
{
|
||||
const auto q = lhs.relative() - rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<q_type::reference, PO1, typename q_type::rep>(q);
|
||||
const auto temp = qp.relative() - q;
|
||||
using q_type = decltype(temp);
|
||||
return quantity_point<q_type::reference, PO1, typename q_type::rep>(std::move(temp));
|
||||
}
|
||||
|
||||
template<PointOrigin PO, Quantity Q>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] constexpr QuantityPoint auto operator-(PO po, const Q& q)
|
||||
requires requires { -q; }
|
||||
{
|
||||
return po + (-q);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP1, QuantityPointOf<QP1::absolute_point_origin> QP2>
|
||||
@@ -278,12 +303,55 @@ template<QuantityPoint QP1, QuantityPointOf<QP1::absolute_point_origin> QP2>
|
||||
requires requires { lhs.absolute() - rhs.absolute(); }
|
||||
{
|
||||
if constexpr (is_same_v<std::remove_const_t<decltype(QP1::point_origin)>,
|
||||
std::remove_const_t<decltype(QP2::point_origin)>>)
|
||||
return lhs.relative() - rhs.relative();
|
||||
else
|
||||
std::remove_const_t<decltype(QP2::point_origin)>>) {
|
||||
constexpr auto common_qs = common_quantity_spec(QP1::quantity_spec, QP1::point_origin.quantity_spec,
|
||||
QP2::quantity_spec, QP2::point_origin.quantity_spec);
|
||||
return quantity_cast<common_qs>(lhs.relative() - rhs.relative());
|
||||
} else
|
||||
return lhs.absolute() - rhs.absolute();
|
||||
}
|
||||
|
||||
template<PointOrigin PO, QuantityPointOf<PO{}> QP>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(QP::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] constexpr Quantity auto operator-(const QP& qp, PO)
|
||||
{
|
||||
constexpr auto common_qs = common_quantity_spec(PO::quantity_spec, QP::quantity_spec, QP::point_origin.quantity_spec);
|
||||
if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO>) {
|
||||
if constexpr (is_same_v<std::remove_const_t<PO>, std::remove_const_t<decltype(QP::point_origin)>>)
|
||||
return quantity_cast<common_qs>(qp.relative());
|
||||
else
|
||||
return quantity_cast<common_qs>(qp.absolute());
|
||||
} else {
|
||||
if constexpr (is_same_v<std::remove_const_t<PO>, std::remove_const_t<decltype(QP::point_origin)>>)
|
||||
return quantity_cast<common_qs>(qp.relative());
|
||||
else
|
||||
return quantity_cast<common_qs>(qp.absolute() - PO::quantity_point.absolute());
|
||||
}
|
||||
}
|
||||
|
||||
template<PointOrigin PO, QuantityPointOf<PO{}> QP>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(QP::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] constexpr Quantity auto operator-(PO po, const QP& qp)
|
||||
{
|
||||
return -(qp - po);
|
||||
}
|
||||
|
||||
template<PointOrigin PO1, PointOriginOf<PO1{}> PO2>
|
||||
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::quantity_spec)>, PO2::quantity_spec> &&
|
||||
(detail::is_derived_from_specialization_of_relative_point_origin<PO1> ||
|
||||
detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
|
||||
[[nodiscard]] constexpr Quantity auto operator-(PO1 po1, PO2 po2)
|
||||
{
|
||||
constexpr auto common_qs = common_quantity_spec(PO1::quantity_spec, PO2::quantity_spec);
|
||||
if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO1>) {
|
||||
return quantity_cast<common_qs>(-po2.quantity_point.absolute());
|
||||
} else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO2>) {
|
||||
return quantity_cast<common_qs>(po1.quantity_point.absolute());
|
||||
} else {
|
||||
return quantity_cast<common_qs>(po1.quantity_point - po2.quantity_point);
|
||||
}
|
||||
}
|
||||
|
||||
template<QuantityPoint QP1, QuantityPointOf<QP1::absolute_point_origin> QP2>
|
||||
requires std::three_way_comparable_with<typename QP1::quantity_type, typename QP2::quantity_type>
|
||||
[[nodiscard]] constexpr auto operator<=>(const QP1& lhs, const QP2& rhs)
|
||||
|
@@ -420,6 +420,8 @@ static_assert(quantity_point<isq::height[m], tower_peak>(42 * m).point_from(towe
|
||||
static_assert(quantity_point<isq::height[m], mean_sea_level>(42 * m).point_from(tower_peak).relative() == -42 * m);
|
||||
static_assert(quantity_point<isq::height[m], ground_level>(84 * m).point_from(tower_peak).relative() == 42 * m);
|
||||
|
||||
static_assert(is_of_type<quantity_point<isq::height[m], ground_level, short>(42 * m).point_from(mean_sea_level),
|
||||
quantity_point<isq::height[m], mean_sea_level, int>>);
|
||||
|
||||
///////////////////////////////////
|
||||
// obtaining an absolute quantity
|
||||
@@ -593,7 +595,7 @@ static_assert(invalid_compound_assignments<quantity_point>);
|
||||
// binary operators
|
||||
////////////////////
|
||||
|
||||
template<template<auto> typename QP>
|
||||
template<template<auto> typename QP, auto Origin>
|
||||
concept invalid_binary_operations = requires {
|
||||
// can't add two quantity points
|
||||
requires !requires { QP<isq::length[m]>(1 * m) + QP<isq::length[m]>(1 * m); };
|
||||
@@ -601,24 +603,34 @@ concept invalid_binary_operations = requires {
|
||||
// can't add more generic quantity (violates point_origin quantity_spec)
|
||||
requires !requires { QP<isq::height[m]>(1 * m) + isq::length(1 * m); };
|
||||
requires !requires { isq::length(1 * m) + QP<isq::height[m]>(1 * m); };
|
||||
requires !requires { Origin + isq::length(1 * m); };
|
||||
requires !requires { isq::length(1 * m) + Origin; };
|
||||
|
||||
// can't subtract more generic quantity (violates point_origin quantity_spec)
|
||||
requires !requires { QP<isq::height[m]>(1 * m) - isq::length(1 * m); };
|
||||
requires !requires { Origin - isq::length(1 * m); };
|
||||
|
||||
// quantity point can't be subtracted from a quantity
|
||||
requires !requires { 1 * m - QP<si::metre>(1 * m); };
|
||||
requires !requires { 1 * m - Origin; };
|
||||
|
||||
// no crossdimensional addition and subtraction
|
||||
requires !requires { QP<si::metre>(1 * m) + 1 * s; };
|
||||
requires !requires { QP<si::metre>(1 * m) - 1 * s; };
|
||||
requires !requires { Origin + 1 * s; };
|
||||
requires !requires { Origin - 1 * s; };
|
||||
|
||||
// unit constants
|
||||
requires !requires { QP<si::metre>(1) + m; };
|
||||
requires !requires { QP<si::metre>(1) - m; };
|
||||
requires !requires { Origin + m; };
|
||||
requires !requires { Origin - m; };
|
||||
requires !requires { m + QP<si::metre>(1); };
|
||||
requires !requires { m - QP<si::metre>(1); };
|
||||
requires !requires { m + Origin; };
|
||||
requires !requires { m - Origin; };
|
||||
};
|
||||
static_assert(invalid_binary_operations<quantity_point>);
|
||||
static_assert(invalid_binary_operations<quantity_point, mean_sea_level>);
|
||||
|
||||
template<template<auto, auto> typename QP>
|
||||
concept invalid_binary_operations_with_origins = requires {
|
||||
@@ -638,6 +650,20 @@ concept invalid_binary_operations_with_origins = requires {
|
||||
};
|
||||
static_assert(invalid_binary_operations_with_origins<quantity_point>);
|
||||
|
||||
template<PointOrigin auto QP1, PointOrigin auto QP2>
|
||||
concept invalid_subtraction_of_point_origins = requires {
|
||||
requires !requires { QP1 - QP2; };
|
||||
requires !requires { QP2 - QP1; };
|
||||
};
|
||||
|
||||
// cant'subtract two unrelated quantity points
|
||||
static_assert(invalid_subtraction_of_point_origins<mean_sea_level, absolute_point_origin<isq::length>{}>);
|
||||
|
||||
// cant'subtract two absolute quantity points as we do not know the unit for the resulting quantity
|
||||
static_assert(
|
||||
invalid_subtraction_of_point_origins<absolute_point_origin<isq::length>{}, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(invalid_subtraction_of_point_origins<mean_sea_level, mean_sea_level>);
|
||||
|
||||
// same representation type
|
||||
static_assert(is_of_type<quantity_point(1 * m) + 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
@@ -695,6 +721,58 @@ static_assert(is_of_type<isq::height(1 * m) + quantity_point(isq::length(1 * km)
|
||||
static_assert(is_of_type<isq::height(1 * km) + quantity_point(isq::length(1 * m)),
|
||||
quantity_point<isq::length[m], absolute_point_origin<isq::length>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} + 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} + 1 * km,
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} + isq::length(1 * m),
|
||||
quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} + isq::distance(1 * m),
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<isq::length>{} + isq::distance(1 * km),
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<1 * m + absolute_point_origin<isq::length>{},
|
||||
quantity_point<si::metre, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<1 * km + absolute_point_origin<isq::length>{},
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<isq::length(1 * m) + absolute_point_origin<isq::length>{},
|
||||
quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<isq::distance(1 * m) + absolute_point_origin<isq::length>{},
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<isq::distance(1 * km) + absolute_point_origin<isq::length>{},
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<isq::length>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} + 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} + 1 * km,
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} + isq::distance(1 * m),
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<kind_of<isq::length>>{} + isq::distance(1 * km),
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<1 * m + absolute_point_origin<kind_of<isq::length>>{},
|
||||
quantity_point<si::metre, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<1 * km + absolute_point_origin<kind_of<isq::length>>{},
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<isq::distance(1 * m) + absolute_point_origin<kind_of<isq::length>>{},
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<isq::distance(1 * km) + absolute_point_origin<kind_of<isq::length>>{},
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<mean_sea_level + 1 * m, quantity_point<si::metre, mean_sea_level, int>>);
|
||||
static_assert(is_of_type<mean_sea_level + 1 * km, quantity_point<si::kilo<si::metre>, mean_sea_level, int>>);
|
||||
static_assert(is_of_type<1 * m + mean_sea_level, quantity_point<si::metre, mean_sea_level, int>>);
|
||||
static_assert(is_of_type<1 * km + mean_sea_level, quantity_point<si::kilo<si::metre>, mean_sea_level, int>>);
|
||||
|
||||
static_assert(is_of_type<ground_level + 1 * m, quantity_point<si::metre, ground_level, int>>);
|
||||
static_assert(is_of_type<ground_level + 1 * km, quantity_point<si::kilo<si::metre>, ground_level, int>>);
|
||||
static_assert(is_of_type<1 * m + ground_level, quantity_point<si::metre, ground_level, int>>);
|
||||
static_assert(is_of_type<1 * km + ground_level, quantity_point<si::kilo<si::metre>, ground_level, int>>);
|
||||
|
||||
static_assert(is_of_type<quantity_point(1 * m) - 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km) - 1 * m,
|
||||
@@ -723,6 +801,32 @@ static_assert(is_of_type<quantity_point(isq::length(1 * m)) - isq::height(1 * km
|
||||
static_assert(is_of_type<quantity_point(isq::length(1 * km)) - isq::height(1 * m),
|
||||
quantity_point<isq::length[m], absolute_point_origin<isq::length>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} - 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} - 1 * km,
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} - isq::distance(1 * m),
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<isq::length>{} - isq::distance(1 * km),
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<isq::length>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - 1 * m,
|
||||
quantity_point<si::metre, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - 1 * km,
|
||||
quantity_point<si::kilo<si::metre>, absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - isq::distance(1 * m),
|
||||
quantity_point<isq::distance[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<kind_of<isq::length>>{} - isq::distance(1 * km),
|
||||
quantity_point<isq::distance[si::kilo<si::metre>], absolute_point_origin<kind_of<isq::length>>{}, int>>);
|
||||
|
||||
static_assert(is_of_type<mean_sea_level - 1 * m, quantity_point<si::metre, mean_sea_level, int>>);
|
||||
static_assert(is_of_type<mean_sea_level - 1 * km, quantity_point<si::kilo<si::metre>, mean_sea_level, int>>);
|
||||
|
||||
static_assert(is_of_type<ground_level - 1 * m, quantity_point<si::metre, ground_level, int>>);
|
||||
static_assert(is_of_type<ground_level - 1 * km, quantity_point<si::kilo<si::metre>, ground_level, int>>);
|
||||
|
||||
static_assert(is_of_type<quantity_point(1 * m) - quantity_point(1 * m), quantity<si::metre, int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km) - quantity_point(1 * m), quantity<si::metre, int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m) - quantity_point(1 * km), quantity<si::metre, int>>);
|
||||
@@ -742,27 +846,107 @@ static_assert(
|
||||
static_assert(
|
||||
is_of_type<quantity_point(isq::length(1 * km)) - quantity_point(isq::height(1 * m)), quantity<isq::length[m], int>>);
|
||||
|
||||
static_assert(is_of_type<quantity_point(1 * m, mean_sea_level) - quantity_point(1 * m, ground_level),
|
||||
static_assert(is_of_type<quantity_point<si::metre, mean_sea_level, int>(1 * m) -
|
||||
quantity_point<si::metre, mean_sea_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, ground_level) - quantity_point(1 * m, mean_sea_level),
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, ground_level, int>(1 * m) - quantity_point<si::metre, ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, tower_peak, int>(1 * m) - quantity_point<si::metre, tower_peak, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point<si::metre, mean_sea_level, int>(1 * m) -
|
||||
quantity_point<si::metre, ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, tower_peak) - quantity_point(1 * m, ground_level),
|
||||
static_assert(is_of_type<quantity_point<si::metre, ground_level, int>(1 * m) -
|
||||
quantity_point<si::metre, mean_sea_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, ground_level) - quantity_point(1 * m, tower_peak),
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, tower_peak, int>(1 * m) - quantity_point<si::metre, ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, ground_level, int>(1 * m) - quantity_point<si::metre, tower_peak, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, tower_peak, int>(1 * m) - quantity_point<si::metre, mean_sea_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point<si::metre, mean_sea_level, int>(1 * m) - quantity_point<si::metre, tower_peak, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point<si::metre, other_ground_level, int>(1 * m) -
|
||||
quantity_point<si::metre, ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, tower_peak) - quantity_point(1 * m, mean_sea_level),
|
||||
static_assert(is_of_type<quantity_point<si::metre, ground_level, int>(1 * m) -
|
||||
quantity_point<si::metre, other_ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, mean_sea_level) - quantity_point(1 * m, tower_peak),
|
||||
static_assert(is_of_type<quantity_point<si::metre, other_ground_level, int>(1 * m) -
|
||||
quantity_point<si::metre, tower_peak, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, other_ground_level) - quantity_point(1 * m, ground_level),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, ground_level) - quantity_point(1 * m, other_ground_level),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, other_ground_level) - quantity_point(1 * m, tower_peak),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, tower_peak) - quantity_point(1 * m, other_ground_level),
|
||||
static_assert(is_of_type<quantity_point<si::metre, tower_peak, int>(1 * m) -
|
||||
quantity_point<si::metre, other_ground_level, int>(1 * m),
|
||||
quantity<isq::height[si::metre], int>>);
|
||||
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} - quantity_point(1 * m), quantity<isq::length[m], int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<isq::length>{} - quantity_point(1 * km), quantity<isq::length[km], int>>);
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<isq::length>{} - quantity_point(isq::height(1 * m)), quantity<isq::length[m], int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<isq::length>{} - quantity_point(isq::height(1 * km)),
|
||||
quantity<isq::length[km], int>>);
|
||||
|
||||
static_assert(
|
||||
is_of_type<absolute_point_origin<kind_of<isq::length>>{} - quantity_point(1 * m), quantity<si::metre, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - quantity_point(1 * km),
|
||||
quantity<si::kilo<si::metre>, int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - quantity_point(isq::height(1 * m)),
|
||||
quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<absolute_point_origin<kind_of<isq::length>>{} - quantity_point(isq::height(1 * km)),
|
||||
quantity<isq::height[km], int>>);
|
||||
|
||||
static_assert(is_of_type<mean_sea_level - quantity_point(1 * m, mean_sea_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<mean_sea_level - quantity_point(1 * km, mean_sea_level), quantity<isq::height[km], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, mean_sea_level) - mean_sea_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km, mean_sea_level) - mean_sea_level, quantity<isq::height[km], int>>);
|
||||
|
||||
static_assert(is_of_type<ground_level - quantity_point(1 * m, ground_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<ground_level - quantity_point(1 * km, ground_level), quantity<isq::height[km], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, ground_level) - ground_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km, ground_level) - ground_level, quantity<isq::height[km], int>>);
|
||||
|
||||
static_assert(is_of_type<mean_sea_level - quantity_point(1 * m, ground_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<mean_sea_level - quantity_point(1 * km, ground_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, ground_level) - mean_sea_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km, ground_level) - mean_sea_level, quantity<isq::height[m], int>>);
|
||||
|
||||
static_assert(is_of_type<ground_level - quantity_point(1 * m, mean_sea_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<ground_level - quantity_point(1 * km, mean_sea_level), quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * m, mean_sea_level) - ground_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<quantity_point(1 * km, mean_sea_level) - ground_level, quantity<isq::height[m], int>>);
|
||||
|
||||
static_assert(is_of_type<ground_level - ground_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<mean_sea_level - ground_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<ground_level - mean_sea_level, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<ground_level - tower_peak, quantity<isq::height[m], int>>);
|
||||
static_assert(is_of_type<tower_peak - ground_level, quantity<isq::height[m], int>>);
|
||||
|
||||
static_assert(
|
||||
is_of_type<quantity_point(isq::length(1 * m)) - quantity_point(isq::height(1 * m)), quantity<isq::length[m], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point(isq::length(1 * m)) - quantity_point(isq::height(1 * km)), quantity<isq::length[m], int>>);
|
||||
static_assert(
|
||||
is_of_type<quantity_point(isq::length(1 * km)) - quantity_point(isq::height(1 * m)), quantity<isq::length[m], int>>);
|
||||
|
||||
static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + ground_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + ground_level) - (1 * m + mean_sea_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + ground_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + ground_level) - (1 * m + tower_peak), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + mean_sea_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + tower_peak), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + ground_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + ground_level) - (1 * m + other_ground_level), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + tower_peak), quantity<isq::height[si::metre], int>>);
|
||||
static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + other_ground_level), quantity<isq::height[si::metre], int>>);
|
||||
|
||||
|
||||
// check for integral types promotion
|
||||
static_assert(
|
||||
|
Reference in New Issue
Block a user