1 parent
c12bf20703
commit
b19bf0761c
4 files changed
+90
-32
No files matched your search
@@ -60,22 +60,44 @@ inline constexpr bool is_derived_from_specialization_of_absolute_point_origin =
|
||||
template<typename T>
|
||||
concept QuantityPoint = detail::is_quantity_point<T>;
|
||||
|
||||
template<QuantityPoint auto QP>
|
||||
struct relative_point_origin;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_relative_point_origin = false;
|
||||
|
||||
template<auto QP>
|
||||
inline constexpr bool is_specialization_of_relative_point_origin<relative_point_origin<QP>> = true;
|
||||
|
||||
template<auto QP>
|
||||
void to_base_specialization_of_relative_point_origin(const volatile relative_point_origin<QP>*);
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_derived_from_specialization_of_relative_point_origin =
|
||||
requires(T* t) { to_base_specialization_of_relative_point_origin(t); };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantity point origins in the library
|
||||
*
|
||||
* Satisfied by either quantity points or by all types derived from `absolute_point_origin` class template.
|
||||
*/
|
||||
template<typename T>
|
||||
concept PointOrigin = QuantityPoint<T> || detail::is_derived_from_specialization_of_absolute_point_origin<T>;
|
||||
concept PointOrigin = detail::is_derived_from_specialization_of_absolute_point_origin<T> ||
|
||||
(detail::is_derived_from_specialization_of_relative_point_origin<T> &&
|
||||
!detail::is_specialization_of_relative_point_origin<T>);
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantity point origins for a specified quantity type in the library
|
||||
*
|
||||
* Satisfied by all quantity point origins that are defined using a provided quantity specification.
|
||||
*/
|
||||
template<typename T, auto Q>
|
||||
template<typename T, auto QS>
|
||||
concept PointOriginFor =
|
||||
PointOrigin<T> && QuantitySpec<std::remove_const_t<decltype(Q)>> && implicitly_convertible(Q, T::quantity_spec);
|
||||
PointOrigin<T> && QuantitySpec<std::remove_const_t<decltype(QS)>> && implicitly_convertible(QS, T::quantity_spec);
|
||||
|
||||
template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep>
|
||||
@@ -108,7 +130,8 @@ 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::absolute_point_origin)>, 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) &&
|
||||
|
||||
@@ -34,12 +34,18 @@ struct absolute_point_origin {
|
||||
static constexpr QuantitySpec auto quantity_spec = Q;
|
||||
};
|
||||
|
||||
template<QuantityPoint auto QP>
|
||||
struct relative_point_origin {
|
||||
static constexpr QuantityPoint auto parent_origin = QP;
|
||||
static constexpr QuantitySpec auto quantity_spec = QP.quantity_spec;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PointOrigin auto po)
|
||||
{
|
||||
if constexpr (requires { po.absolute_point_origin; })
|
||||
return po.absolute_point_origin;
|
||||
if constexpr (requires { po.parent_origin.absolute_point_origin; })
|
||||
return po.parent_origin.absolute_point_origin;
|
||||
else
|
||||
return po;
|
||||
}
|
||||
@@ -145,7 +151,7 @@ public:
|
||||
std::remove_const_t<decltype(point_origin)>>)
|
||||
return relative();
|
||||
else
|
||||
return point_origin.absolute() + relative();
|
||||
return point_origin.parent_origin.absolute() + relative();
|
||||
}
|
||||
|
||||
template<Unit U>
|
||||
|
||||
@@ -360,15 +360,20 @@ static_assert(!QuantityLike<int>);
|
||||
// QuantityPoint
|
||||
inline constexpr struct my_origin : absolute_point_origin<isq::length> {
|
||||
} my_origin;
|
||||
inline constexpr struct my_relative_origin :
|
||||
relative_point_origin<quantity_point<isq::length[si::metre]>{42 * si::metre}> {
|
||||
} my_relative_origin;
|
||||
|
||||
static_assert(QuantityPoint<quantity_point<si::metre>>);
|
||||
static_assert(QuantityPoint<quantity_point<isq::length[si::metre]>>);
|
||||
static_assert(QuantityPoint<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_origin>>);
|
||||
static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_relative_origin>>);
|
||||
static_assert(!QuantityPoint<std::remove_const_t<decltype(isq::length[si::metre])>>);
|
||||
static_assert(!QuantityPoint<absolute_point_origin<isq::length>>);
|
||||
static_assert(!QuantityPoint<struct my_origin>);
|
||||
static_assert(!QuantityPoint<struct my_relative_origin>);
|
||||
static_assert(!QuantityPoint<std::chrono::seconds>);
|
||||
static_assert(!QuantityPoint<std::chrono::time_point<std::chrono::system_clock>>);
|
||||
static_assert(!QuantityPoint<int>);
|
||||
@@ -390,28 +395,41 @@ static_assert(
|
||||
QuantityPointOf<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::length>{}, int>, isq::radius>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, isq::length>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, isq::radius>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::length>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::radius>);
|
||||
static_assert(QuantityPointOf<quantity_point<si::metre>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(QuantityPointOf<quantity_point<si::metre>, absolute_point_origin<isq::radius>{}>);
|
||||
static_assert(QuantityPointOf<quantity_point<si::metre>, my_origin>);
|
||||
static_assert(!QuantityPointOf<quantity_point<si::metre>, my_origin>);
|
||||
static_assert(!QuantityPointOf<quantity_point<si::metre>, my_relative_origin>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::length[si::metre]>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(!QuantityPointOf<quantity_point<isq::length[si::metre]>, absolute_point_origin<isq::radius>{}>);
|
||||
static_assert(!QuantityPointOf<quantity_point<isq::length[si::metre]>, my_origin>);
|
||||
static_assert(!QuantityPointOf<quantity_point<isq::length[si::metre]>, my_relative_origin>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre]>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre]>, absolute_point_origin<isq::radius>{}>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre]>, my_origin>);
|
||||
static_assert(!QuantityPointOf<quantity_point<isq::radius[si::metre]>, my_origin>);
|
||||
static_assert(!QuantityPointOf<quantity_point<isq::radius[si::metre]>, my_relative_origin>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, my_origin>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, my_relative_origin>);
|
||||
static_assert(
|
||||
QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(
|
||||
!QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, absolute_point_origin<isq::length>{}>);
|
||||
static_assert(
|
||||
!QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, absolute_point_origin<isq::radius>{}>);
|
||||
static_assert(
|
||||
!QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, absolute_point_origin<isq::radius>{}>);
|
||||
|
||||
// PointOrigin
|
||||
static_assert(PointOrigin<absolute_point_origin<isq::length>>);
|
||||
static_assert(PointOrigin<struct my_origin>);
|
||||
static_assert(PointOrigin<quantity_point<si::metre>>);
|
||||
static_assert(PointOrigin<quantity_point<isq::length[si::metre]>>);
|
||||
static_assert(PointOrigin<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(PointOrigin<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(PointOrigin<quantity_point<isq::radius[si::metre], my_origin>>);
|
||||
static_assert(PointOrigin<struct my_relative_origin>);
|
||||
static_assert(!PointOrigin<relative_point_origin<quantity_point<si::metre>{42 * si::metre}>>);
|
||||
static_assert(!PointOrigin<quantity_point<si::metre>>);
|
||||
static_assert(!PointOrigin<quantity_point<isq::length[si::metre]>>);
|
||||
static_assert(!PointOrigin<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(!PointOrigin<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::length>{}, int>>);
|
||||
static_assert(!PointOrigin<quantity_point<isq::radius[si::metre], my_origin>>);
|
||||
static_assert(!PointOrigin<std::remove_const_t<decltype(isq::length[si::metre])>>);
|
||||
static_assert(!PointOrigin<std::chrono::seconds>);
|
||||
static_assert(!PointOrigin<std::chrono::time_point<std::chrono::system_clock>>);
|
||||
@@ -426,42 +444,48 @@ static_assert(!PointOriginFor<absolute_point_origin<isq::length>, isq::time>);
|
||||
static_assert(PointOriginFor<struct my_origin, isq::length>);
|
||||
static_assert(PointOriginFor<struct my_origin, isq::radius>);
|
||||
static_assert(!PointOriginFor<struct my_origin, isq::time>);
|
||||
static_assert(PointOriginFor<quantity_point<si::metre>, isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<si::metre>, isq::radius>);
|
||||
static_assert(PointOriginFor<struct my_relative_origin, isq::length>);
|
||||
static_assert(PointOriginFor<struct my_relative_origin, isq::radius>);
|
||||
static_assert(!PointOriginFor<struct my_relative_origin, isq::time>);
|
||||
static_assert(!PointOriginFor<quantity_point<si::metre>, isq::length>);
|
||||
static_assert(!PointOriginFor<quantity_point<si::metre>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<si::metre>, isq::time>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::length[si::metre]>, isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::length[si::metre]>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::length[si::metre]>, isq::length>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::length[si::metre]>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::length[si::metre]>, isq::time>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre]>, isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::radius[si::metre]>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre]>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre]>, isq::time>);
|
||||
static_assert(
|
||||
PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>, isq::length>);
|
||||
!PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>, isq::length>);
|
||||
static_assert(
|
||||
PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>, isq::radius>);
|
||||
!PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>, isq::radius>);
|
||||
static_assert(
|
||||
!PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<isq::length>{}, int>, isq::time>);
|
||||
static_assert(
|
||||
!PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::radius>{}, int>, isq::length>);
|
||||
static_assert(
|
||||
PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::radius>{}, int>, isq::radius>);
|
||||
!PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::radius>{}, int>, isq::radius>);
|
||||
static_assert(
|
||||
!PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::radius>{}, int>, isq::time>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>,
|
||||
isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::length[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>,
|
||||
isq::radius>);
|
||||
static_assert(!PointOriginFor<
|
||||
quantity_point<isq::length[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>, isq::length>);
|
||||
static_assert(!PointOriginFor<
|
||||
quantity_point<isq::length[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>, isq::radius>);
|
||||
static_assert(!PointOriginFor<
|
||||
quantity_point<isq::length[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>, isq::time>);
|
||||
static_assert(!PointOriginFor<
|
||||
quantity_point<isq::radius[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>, isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>,
|
||||
isq::radius>);
|
||||
static_assert(!PointOriginFor<
|
||||
quantity_point<isq::radius[si::metre], absolute_point_origin<kind_of<isq::length>>{}, int>, isq::radius>);
|
||||
static_assert(
|
||||
!PointOriginFor<quantity_point<isq::radius[si::metre], absolute_point_origin<isq::length>{}, int>, isq::time>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::length>);
|
||||
static_assert(PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::time>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::length>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::radius>);
|
||||
static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::time>);
|
||||
static_assert(!PointOriginFor<std::remove_const_t<decltype(isq::length[si::metre])>, isq::length>);
|
||||
static_assert(!PointOriginFor<std::chrono::seconds, isq::length>);
|
||||
static_assert(!PointOriginFor<std::chrono::time_point<std::chrono::system_clock>, isq::length>);
|
||||
|
||||
@@ -39,8 +39,13 @@ using sys_seconds = std::chrono::time_point<std::chrono::system_clock, std::chro
|
||||
inline constexpr struct mean_sea_level : absolute_point_origin<isq::height> {
|
||||
} mean_sea_level;
|
||||
|
||||
inline constexpr quantity_point<isq::height[m], mean_sea_level> ground_level{42 * isq::height[m]};
|
||||
inline constexpr quantity_point<isq::height[m], mean_sea_level> everest_base_camp{5364 * m};
|
||||
inline constexpr struct ground_level :
|
||||
relative_point_origin<quantity_point<isq::height[m], mean_sea_level>{42 * isq::height[m]}> {
|
||||
} ground_level;
|
||||
|
||||
inline constexpr struct everest_base_camp :
|
||||
relative_point_origin<quantity_point<isq::height[m], mean_sea_level>{5364 * m}> {
|
||||
} everest_base_camp;
|
||||
|
||||
QUANTITY_SPEC(special_height, isq::height);
|
||||
QUANTITY_SPEC(activity, 1 / isq::time);
|
||||
|
||||
Reference in new issue
Block a user