Skip to content

Commit

Permalink
concepts:
Browse files Browse the repository at this point in the history
Add a DimensionlessQuantity concept - multiplication by itself does not affect its dimension.
Add an Arithmetic concept  - the built in arithmetic types are models.
Make Arithmetic models of DimensionlessQuantity.

quantity:
Constrain the ambiguous multiply ops to multiplication by DimensionlessQuantity.
  • Loading branch information
kwikius committed May 31, 2020
1 parent 7089e2b commit b09c4af
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
17 changes: 17 additions & 0 deletions src/include/units/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,21 @@ concept Scalar =
std::regular<T> &&
(detail::constructible_from_integral<T> || detail::not_constructible_from_integral<T>);

template <typename T>
concept Arithmetic = std::is_arithmetic_v<T>;

namespace detail{

template <typename T>
inline constexpr bool is_dimensionless_quantity = false;

//The built in arithmetic types are dimensionless
template <Arithmetic T>
inline constexpr bool is_dimensionless_quantity<T> = true;
}

template <typename T>
concept DimensionlessQuantity = detail::is_dimensionless_quantity<T>;


} // namespace units
8 changes: 4 additions & 4 deletions src/include/units/quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,18 +322,18 @@ template<typename D, typename U1, typename Rep1, typename U2, typename Rep2>
return ret(ret(lhs).count() - ret(rhs).count());
}

template<typename D, typename U, typename Rep, Scalar Value>
template<typename D, typename U, typename Rep, DimensionlessQuantity Value>
[[nodiscard]] constexpr Quantity AUTO operator*(const quantity<D, U, Rep>& q, const Value& v)
requires std::regular_invocable<std::multiplies<>, Rep, Value> && std::is_arithmetic_v<Value>
requires std::regular_invocable<std::multiplies<>, Rep, Value>
{
using common_rep = decltype(q.count() * v);
using ret = quantity<D, U, common_rep>;
return ret(q.count() * v);
}

template<Scalar Value, typename D, typename U, typename Rep>
template<DimensionlessQuantity Value, typename D, typename U, typename Rep>
[[nodiscard]] constexpr Quantity AUTO operator*(const Value& v, const quantity<D, U, Rep>& q)
requires std::regular_invocable<std::multiplies<>, Value, Rep> && std::is_arithmetic_v<Value>
requires std::regular_invocable<std::multiplies<>, Value, Rep>
{
return q * v;
}
Expand Down

0 comments on commit b09c4af

Please sign in to comment.