Skip to content

Commit

Permalink
refactor: quantity_from_origin_ data member now has much less frien…
Browse files Browse the repository at this point in the history
…dly name
  • Loading branch information
mpusz committed Oct 17, 2023
1 parent abafd1d commit 8e48906
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 130 deletions.
63 changes: 35 additions & 28 deletions src/core/include/mp-units/quantity_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class quantity_point {
using rep = Rep;
using quantity_type = quantity<reference, Rep>;

quantity_type quantity_from_origin_; // needs to be public for a structural type
quantity_type quantity_from_origin_is_an_implementation_detail_; // needs to be public for a structural type

// static member functions
[[nodiscard]] static constexpr quantity_point min() noexcept
Expand All @@ -106,7 +106,7 @@ class quantity_point {
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) :
quantity_from_origin_([&] {
quantity_from_origin_is_an_implementation_detail_([&] {
if constexpr (is_same_v<std::remove_const_t<decltype(point_origin)>,
std::remove_const_t<decltype(QP::point_origin)>>)
return qp.quantity_ref_from(point_origin);
Expand All @@ -128,7 +128,7 @@ class quantity_point {
!std::convertible_to<
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>, quantity_type>)
quantity_point(const QP& qp) :
quantity_from_origin_(quantity_point_like_traits<QP>::to_quantity(qp).value)
quantity_from_origin_is_an_implementation_detail_(quantity_point_like_traits<QP>::to_quantity(qp).value)
{
}

Expand All @@ -149,13 +149,13 @@ class quantity_point {
template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
[[nodiscard]] constexpr quantity_type& quantity_ref_from(PO2) & noexcept
{
return quantity_from_origin_;
return quantity_from_origin_is_an_implementation_detail_;
}

template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
[[nodiscard]] constexpr const quantity_type& quantity_ref_from(PO2) const& noexcept
{
return quantity_from_origin_;
return quantity_from_origin_is_an_implementation_detail_;
}

template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
Expand Down Expand Up @@ -190,14 +190,16 @@ class quantity_point {
std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
convert_explicitly> ||
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
operator QP_() const& noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
std::is_nothrow_copy_constructible_v<rep>)
operator QP_() const& noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
std::is_nothrow_copy_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_).value;
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_).value;
}

template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>>
Expand All @@ -206,61 +208,66 @@ class quantity_point {
std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
convert_explicitly> ||
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
operator QP_() && noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
std::is_nothrow_move_constructible_v<rep>)
operator QP_() && noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
std::is_nothrow_move_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_)).value;
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_is_an_implementation_detail_))
.value;
}

// member unary operators
template<typename QP>
friend constexpr decltype(auto) operator++(QP&& qp)
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> && requires { ++qp.quantity_from_origin_; }
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires { ++qp.quantity_from_origin_is_an_implementation_detail_; }
{
++qp.quantity_from_origin_;
++qp.quantity_from_origin_is_an_implementation_detail_;
return std::forward<QP>(qp);
}

[[nodiscard]] constexpr quantity_point operator++(int)
requires requires { quantity_from_origin_++; }
requires requires { quantity_from_origin_is_an_implementation_detail_++; }
{
return quantity_point(quantity_from_origin_++);
return quantity_point(quantity_from_origin_is_an_implementation_detail_++);
}

template<typename QP>
friend constexpr decltype(auto) operator--(QP&& qp)
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> && requires { --qp.quantity_from_origin_; }
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires { --qp.quantity_from_origin_is_an_implementation_detail_; }
{
--qp.quantity_from_origin_;
--qp.quantity_from_origin_is_an_implementation_detail_;
return std::forward<QP>(qp);
}

[[nodiscard]] constexpr quantity_point operator--(int)
requires requires { quantity_from_origin_--; }
requires requires { quantity_from_origin_is_an_implementation_detail_--; }
{
return quantity_point(quantity_from_origin_--);
return quantity_point(quantity_from_origin_is_an_implementation_detail_--);
}

// compound assignment operators
template<typename QP>
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires(quantity_type q) { quantity_from_origin_ += q; }
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ += q; }
friend constexpr decltype(auto) operator+=(QP&& qp, const quantity_type& q)
{
qp.quantity_from_origin_ += q;
qp.quantity_from_origin_is_an_implementation_detail_ += q;
return std::forward<QP>(qp);
}

template<typename QP>
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires(quantity_type q) { quantity_from_origin_ -= q; }
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ -= q; }
friend constexpr decltype(auto) operator-=(QP&& qp, const quantity_type& q)
{
qp.quantity_from_origin_ -= q;
qp.quantity_from_origin_is_an_implementation_detail_ -= q;
return std::forward<QP>(qp);
}

Expand All @@ -276,7 +283,7 @@ class quantity_point {
template<Quantity Q>
requires std::constructible_from<quantity_type, Q> &&
ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO.quantity_spec>
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_(std::forward<Q>(q))
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
{
}
};
Expand Down
Loading

0 comments on commit 8e48906

Please sign in to comment.