mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-01 03:14:29 +02:00
feat: 💥 RepresentationOf
concept now also accepts a QuantitySpec
and accepts any representation character for quantity kinds
This commit is contained in:
@@ -148,7 +148,7 @@ As we remember, the `quantity` class template is defined as follows:
|
||||
|
||||
```cpp
|
||||
template<Reference auto R,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity;
|
||||
```
|
||||
|
||||
|
@@ -159,15 +159,28 @@ A `Reference` can either be:
|
||||
[value of a quantity](../../appendix/glossary.md#quantity-value).
|
||||
|
||||
|
||||
### `RepresentationOf<T, Ch>` { #RepresentationOf }
|
||||
### `RepresentationOf<T, V>` { #RepresentationOf }
|
||||
|
||||
`RepresentationOf` concept is satisfied by all `Representation` types that are of a specified
|
||||
[quantity character](../../appendix/glossary.md#character) `Ch`.
|
||||
`RepresentationOf` concept is satisfied:
|
||||
|
||||
- if the type of `V` satisfies [`QuantitySpec`](#QuantitySpec):
|
||||
|
||||
- by all [`Representation`](#Representation) types when `V` describes
|
||||
a [quantity kind](../../appendix/glossary.md#kind),
|
||||
- otherwise, by [`Representation`](#Representation) types that are of
|
||||
a [quantity character](../../appendix/glossary.md#character) associated with a provided
|
||||
quantity specification `V`.
|
||||
|
||||
- if `V` is of `quantity_character` type:
|
||||
|
||||
- by [`Representation`](#Representation) types that are of a provided
|
||||
[quantity character](../../appendix/glossary.md#character).
|
||||
|
||||
A user can declare a custom representation type to be of a specific character by providing the specialization
|
||||
with `true` for one or more of the following variable templates:
|
||||
|
||||
- `is_scalar<T>`
|
||||
- `is_complex<T>`
|
||||
- `is_vector<T>`
|
||||
- `is_tensor<T>`
|
||||
|
||||
|
@@ -316,7 +316,7 @@ This is why a `quantity` class template is defined in the library as:
|
||||
|
||||
```cpp
|
||||
template<Reference auto R,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity;
|
||||
```
|
||||
|
||||
@@ -365,7 +365,7 @@ In the **mp-units** library, the quantity point is implemented as:
|
||||
```cpp
|
||||
template<Reference auto R,
|
||||
PointOriginFor<get_quantity_spec(R)> auto PO,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity_point;
|
||||
```
|
||||
|
||||
|
@@ -20,7 +20,7 @@ In the **mp-units** library, a quantity is represented with the following class
|
||||
|
||||
```cpp
|
||||
template<Reference auto R,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity;
|
||||
```
|
||||
|
||||
|
@@ -96,7 +96,7 @@ origin:
|
||||
```cpp
|
||||
template<Reference auto R,
|
||||
PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R),
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity_point;
|
||||
```
|
||||
|
||||
|
@@ -39,7 +39,7 @@ namespace mp_units {
|
||||
|
||||
template<Reference R>
|
||||
struct delta_ {
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
[[nodiscard]] constexpr quantity<MP_UNITS_EXPRESSION_WORKAROUND(R{}), Rep> operator()(FwdRep&& lhs) const
|
||||
{
|
||||
return quantity{std::forward<FwdRep>(lhs), R{}};
|
||||
@@ -48,7 +48,7 @@ struct delta_ {
|
||||
|
||||
template<Reference R>
|
||||
struct absolute_ {
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
[[nodiscard]] constexpr quantity_point<MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}), Rep>
|
||||
operator()(FwdRep&& lhs) const
|
||||
{
|
||||
|
@@ -78,14 +78,15 @@ concept QuantityConvertibleTo =
|
||||
// deduced thus the function is evaluated here and may emit truncating conversion or other warnings)
|
||||
requires(QFrom q) { sudo_cast<QTo>(q); };
|
||||
|
||||
template<quantity_character Ch, typename Func, typename T, typename U>
|
||||
concept InvokeResultOf = std::regular_invocable<Func, T, U> && RepresentationOf<std::invoke_result_t<Func, T, U>, Ch>;
|
||||
template<auto QS, typename Func, typename T, typename U>
|
||||
concept InvokeResultOf = QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && std::regular_invocable<Func, T, U> &&
|
||||
RepresentationOf<std::invoke_result_t<Func, T, U>, QS>;
|
||||
|
||||
template<typename Func, typename Q1, typename Q2,
|
||||
quantity_character Ch = std::invoke_result_t<Func, std::remove_const_t<decltype(Q1::quantity_spec)>,
|
||||
std::remove_const_t<decltype(Q2::quantity_spec)>>::character>
|
||||
concept InvocableQuantities =
|
||||
Quantity<Q1> && Quantity<Q2> && InvokeResultOf<Ch, Func, typename Q1::rep, typename Q2::rep>;
|
||||
auto QS = std::invoke_result_t<Func, std::remove_const_t<decltype(Q1::quantity_spec)>,
|
||||
std::remove_const_t<decltype(Q2::quantity_spec)>>{}>
|
||||
concept InvocableQuantities = QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && Quantity<Q1> && Quantity<Q2> &&
|
||||
InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>;
|
||||
|
||||
// TODO remove the following when clang diagnostics improve
|
||||
// https://github.com/llvm/llvm-project/issues/96660
|
||||
@@ -104,7 +105,7 @@ concept CommonlyInvocableQuantities =
|
||||
Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> &&
|
||||
std::convertible_to<Q1, common_quantity_for<Func, Q1, Q2>> &&
|
||||
std::convertible_to<Q2, common_quantity_for<Func, Q1, Q2>> &&
|
||||
InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec).character>;
|
||||
InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>;
|
||||
|
||||
template<auto R1, auto R2, typename Rep1, typename Rep2>
|
||||
concept SameValueAs = (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>;
|
||||
@@ -128,7 +129,7 @@ MP_UNITS_EXPORT_BEGIN
|
||||
* @tparam R a reference of the quantity providing all information about quantity properties
|
||||
* @tparam Rep a type to be used to represent values of a quantity
|
||||
*/
|
||||
template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity {
|
||||
public:
|
||||
Rep numerical_value_is_an_implementation_detail_; ///< needs to be public for a structural type
|
||||
@@ -227,14 +228,14 @@ public:
|
||||
return quantity<detail::make_reference(quantity_spec, ToU{}), Rep>{*this};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep>
|
||||
template<RepresentationOf<quantity_spec> ToRep>
|
||||
requires detail::QuantityConvertibleTo<quantity, quantity<reference, ToRep>>
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto in() const
|
||||
{
|
||||
return quantity<reference, ToRep>{*this};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
template<RepresentationOf<quantity_spec> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
requires detail::QuantityConvertibleTo<quantity, quantity<detail::make_reference(quantity_spec, ToU{}), ToRep>>
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto in(ToU) const
|
||||
{
|
||||
@@ -248,14 +249,14 @@ public:
|
||||
return value_cast<ToU{}>(*this);
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep>
|
||||
template<RepresentationOf<quantity_spec> ToRep>
|
||||
requires requires(quantity q) { value_cast<ToRep>(q); }
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto force_in() const
|
||||
{
|
||||
return value_cast<ToRep>(*this);
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
template<RepresentationOf<quantity_spec> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
requires requires(quantity q) { value_cast<ToU{}, ToRep>(q); }
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto force_in(ToU) const
|
||||
{
|
||||
@@ -474,17 +475,15 @@ public:
|
||||
ret::reference};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::plus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs)
|
||||
{
|
||||
return lhs + ::mp_units::quantity{rhs};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::plus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs)
|
||||
{
|
||||
return ::mp_units::quantity{lhs} + rhs;
|
||||
@@ -501,17 +500,15 @@ public:
|
||||
ret::reference};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::minus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs)
|
||||
{
|
||||
return lhs - ::mp_units::quantity{rhs};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::minus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs)
|
||||
{
|
||||
return ::mp_units::quantity{lhs} - rhs;
|
||||
@@ -530,17 +527,15 @@ public:
|
||||
ret::reference};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::modulus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs)
|
||||
{
|
||||
return lhs % ::mp_units::quantity{rhs};
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
requires(Q::unit == ::mp_units::one) &&
|
||||
detail::InvokeResultOf<quantity_character::scalar, std::modulus<>, Rep, const Value&>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && detail::InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs)
|
||||
{
|
||||
return ::mp_units::quantity{lhs} % rhs;
|
||||
@@ -555,7 +550,7 @@ public:
|
||||
|
||||
template<std::derived_from<quantity> Q, typename Value>
|
||||
requires(!Quantity<Value>) &&
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec.character, std::multiplies<>, Rep, const Value&>
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& q, const Value& v)
|
||||
{
|
||||
return ::mp_units::quantity{q.numerical_value_ref_in(unit) * v, R};
|
||||
@@ -563,7 +558,7 @@ public:
|
||||
|
||||
template<typename Value, std::derived_from<quantity> Q>
|
||||
requires(!Quantity<Value>) &&
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec.character, std::multiplies<>, const Value&, Rep>
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep>
|
||||
[[nodiscard]] friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& v, const Q& q)
|
||||
{
|
||||
return ::mp_units::quantity{v * q.numerical_value_ref_in(unit), R};
|
||||
@@ -579,7 +574,7 @@ public:
|
||||
|
||||
template<std::derived_from<quantity> Q, typename Value>
|
||||
requires(!Quantity<Value>) &&
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec.character, std::divides<>, Rep, const Value&>
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&>
|
||||
[[nodiscard]] friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& q, const Value& v)
|
||||
{
|
||||
MP_UNITS_EXPECTS_DEBUG(v != quantity_values<Value>::zero());
|
||||
@@ -588,7 +583,7 @@ public:
|
||||
|
||||
template<typename Value, std::derived_from<quantity> Q>
|
||||
requires(!Quantity<Value>) &&
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec.character, std::divides<>, const Value&, Rep>
|
||||
(!Reference<Value>) && detail::InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep>
|
||||
[[nodiscard]] friend constexpr QuantityOf<inverse(quantity_spec)> auto operator/(const Value& v, const Q& q)
|
||||
{
|
||||
return ::mp_units::quantity{v / q.numerical_value_ref_in(unit), ::mp_units::one / R};
|
||||
@@ -605,7 +600,7 @@ public:
|
||||
return ct_lhs.numerical_value_ref_in(ct::unit) == ct_rhs.numerical_value_ref_in(ct::unit);
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && std::equality_comparable_with<Rep, Value>
|
||||
[[nodiscard]] friend constexpr bool operator==(const Q& lhs, const Value& rhs)
|
||||
{
|
||||
@@ -623,7 +618,7 @@ public:
|
||||
return ct_lhs.numerical_value_ref_in(ct::unit) <=> ct_rhs.numerical_value_ref_in(ct::unit);
|
||||
}
|
||||
|
||||
template<std::derived_from<quantity> Q, RepresentationOf<quantity_character::scalar> Value>
|
||||
template<std::derived_from<quantity> Q, Representation Value>
|
||||
requires(Q::unit == ::mp_units::one) && std::three_way_comparable_with<Rep, Value>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const Q& lhs, const Value& rhs)
|
||||
{
|
||||
@@ -650,18 +645,21 @@ template<mp_units::Quantity Q1, mp_units::Quantity Q2>
|
||||
requires requires {
|
||||
{ mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference;
|
||||
typename std::common_type_t<typename Q1::rep, typename Q2::rep>;
|
||||
requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>,
|
||||
mp_units::get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>;
|
||||
}
|
||||
struct std::common_type<Q1, Q2> {
|
||||
using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference),
|
||||
std::common_type_t<typename Q1::rep, typename Q2::rep>>;
|
||||
};
|
||||
|
||||
template<mp_units::Quantity Q, mp_units::RepresentationOf<mp_units::quantity_character::scalar> Value>
|
||||
requires(Q::unit == mp_units::one) && requires { typename std::common_type_t<typename Q::rep, Value>; }
|
||||
template<mp_units::Quantity Q, mp_units::Representation Value>
|
||||
requires(Q::unit == mp_units::one) &&
|
||||
requires { typename mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; }
|
||||
struct std::common_type<Q, Value> {
|
||||
using type = mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>;
|
||||
};
|
||||
|
||||
template<mp_units::Quantity Q, mp_units::RepresentationOf<mp_units::quantity_character::scalar> Value>
|
||||
requires(Q::unit == mp_units::one) && requires { typename std::common_type_t<typename Q::rep, Value>; }
|
||||
template<mp_units::Quantity Q, mp_units::Representation Value>
|
||||
requires requires { typename std::common_type<Q, Value>; }
|
||||
struct std::common_type<Value, Q> : std::common_type<Q, Value> {};
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep>
|
||||
MP_UNITS_EXPORT template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep>
|
||||
class quantity;
|
||||
|
||||
namespace detail {
|
||||
|
@@ -172,7 +172,7 @@ template<PointOrigin PO>
|
||||
* @tparam Rep a type to be used to represent values of a quantity point
|
||||
*/
|
||||
MP_UNITS_EXPORT template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R),
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
class quantity_point {
|
||||
public:
|
||||
// member types and values
|
||||
@@ -329,14 +329,14 @@ public:
|
||||
return ::mp_units::quantity_point{quantity_ref_from(point_origin).in(ToU{}), point_origin};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep>
|
||||
template<RepresentationOf<quantity_spec> ToRep>
|
||||
requires detail::QuantityConvertibleTo<quantity_type, quantity<reference, ToRep>>
|
||||
[[nodiscard]] constexpr QuantityPointOf<quantity_spec> auto in() const
|
||||
{
|
||||
return ::mp_units::quantity_point{quantity_ref_from(point_origin).template in<ToRep>(), point_origin};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
template<RepresentationOf<quantity_spec> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
requires detail::QuantityConvertibleTo<quantity_type, quantity<detail::make_reference(quantity_spec, ToU{}), ToRep>>
|
||||
[[nodiscard]] constexpr QuantityPointOf<quantity_spec> auto in(ToU) const
|
||||
{
|
||||
@@ -350,14 +350,14 @@ public:
|
||||
return ::mp_units::quantity_point{quantity_ref_from(point_origin).force_in(ToU{}), point_origin};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep>
|
||||
template<RepresentationOf<quantity_spec> ToRep>
|
||||
requires requires(quantity_type q) { value_cast<ToRep>(q); }
|
||||
[[nodiscard]] constexpr QuantityPointOf<quantity_spec> auto force_in() const
|
||||
{
|
||||
return ::mp_units::quantity_point{quantity_ref_from(point_origin).template force_in<ToRep>(), point_origin};
|
||||
}
|
||||
|
||||
template<RepresentationOf<quantity_spec.character> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
template<RepresentationOf<quantity_spec> ToRep, detail::UnitCompatibleWith<unit, quantity_spec> ToU>
|
||||
requires requires(quantity_type q) { value_cast<ToU{}, ToRep>(q); }
|
||||
[[nodiscard]] constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const
|
||||
{
|
||||
|
@@ -76,7 +76,7 @@ MP_UNITS_EXPORT template<typename T, auto QS>
|
||||
concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<MP_UNITS_REMOVE_CONST(decltype(QS)), T::_quantity_spec_>;
|
||||
|
||||
MP_UNITS_EXPORT template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep>
|
||||
class quantity_point;
|
||||
|
||||
namespace detail {
|
||||
|
@@ -190,24 +190,21 @@ struct reference {
|
||||
};
|
||||
|
||||
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, Reference R, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>)
|
||||
[[nodiscard]] constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r)
|
||||
{
|
||||
return quantity{std::forward<FwdRep>(lhs), r};
|
||||
}
|
||||
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, Reference R, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>)
|
||||
[[nodiscard]] constexpr quantity<inverse(R{}), Rep> operator/(FwdRep&& lhs, R)
|
||||
{
|
||||
return quantity{std::forward<FwdRep>(lhs), inverse(R{})};
|
||||
}
|
||||
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, Reference R, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))>
|
||||
[[deprecated(
|
||||
"References using offset units (e.g., temperatures) should be constructed with the `delta` or `absolute` "
|
||||
@@ -217,8 +214,7 @@ operator*(FwdRep&& lhs, R r)
|
||||
return quantity{std::forward<FwdRep>(lhs), r};
|
||||
}
|
||||
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
template<typename FwdRep, Reference R, RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))>
|
||||
[[deprecated(
|
||||
"References using offset units (e.g., temperatures) should be constructed with the `delta` or `absolute` "
|
||||
@@ -229,7 +225,7 @@ operator/(FwdRep&& lhs, R)
|
||||
}
|
||||
|
||||
template<Reference R, typename Rep>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})>
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
|
||||
constexpr auto operator*(R, Rep&&)
|
||||
#if __cpp_deleted_function
|
||||
@@ -239,7 +235,7 @@ constexpr auto operator*(R, Rep&&)
|
||||
#endif
|
||||
|
||||
template<Reference R, typename Rep>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})>
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
|
||||
constexpr auto operator/(R, Rep&&)
|
||||
#if __cpp_deleted_function
|
||||
|
@@ -25,6 +25,7 @@
|
||||
// IWYU pragma: private, include <mp-units/framework.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/framework/customization_points.h>
|
||||
#include <mp-units/framework/quantity_spec_concepts.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#ifdef MP_UNITS_IMPORT_STD
|
||||
@@ -165,7 +166,11 @@ MP_UNITS_EXPORT template<typename T>
|
||||
concept Representation = detail::ScalarRepresentation<T> || detail::ComplexRepresentation<T> ||
|
||||
detail::VectorRepresentation<T> || detail::TensorRepresentation<T>;
|
||||
|
||||
MP_UNITS_EXPORT template<typename T, quantity_character Ch>
|
||||
concept RepresentationOf = detail::IsOfCharacter<T, Ch> && Representation<T>;
|
||||
MP_UNITS_EXPORT template<typename T, auto V>
|
||||
concept RepresentationOf =
|
||||
Representation<T> &&
|
||||
((QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(V))> &&
|
||||
(detail::QuantityKindSpec<MP_UNITS_REMOVE_CONST(decltype(V))> || detail::IsOfCharacter<T, V.character>)) ||
|
||||
(std::same_as<quantity_character, decltype(V)> && detail::IsOfCharacter<T, V>));
|
||||
|
||||
} // namespace mp_units
|
||||
|
@@ -63,7 +63,7 @@ template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
* @tparam ToRep a representation type to use for a target quantity
|
||||
*/
|
||||
template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires RepresentationOf<ToRep, Q::quantity_spec.character> && std::constructible_from<ToRep, typename Q::rep>
|
||||
requires RepresentationOf<ToRep, Q::quantity_spec> && std::constructible_from<ToRep, typename Q::rep>
|
||||
[[nodiscard]] constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q)
|
||||
{
|
||||
return detail::sudo_cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q));
|
||||
@@ -81,7 +81,7 @@ template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<F
|
||||
* @tparam ToRep a representation type to use for the target quantity
|
||||
*/
|
||||
template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec.character> &&
|
||||
requires(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> &&
|
||||
std::constructible_from<ToRep, typename Q::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::r
|
||||
}
|
||||
|
||||
template<Representation ToRep, Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec.character> &&
|
||||
requires(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> &&
|
||||
std::constructible_from<ToRep, typename Q::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||
{
|
||||
@@ -148,7 +148,7 @@ template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<F
|
||||
* @tparam ToRep a representation type to use for a target quantity point
|
||||
*/
|
||||
template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires RepresentationOf<ToRep, QP::quantity_spec.character> && std::constructible_from<ToRep, typename QP::rep>
|
||||
requires RepresentationOf<ToRep, QP::quantity_spec> && std::constructible_from<ToRep, typename QP::rep>
|
||||
[[nodiscard]] constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp)
|
||||
{
|
||||
return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
@@ -167,7 +167,7 @@ template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cv
|
||||
* @tparam ToRep a representation type to use for the target quantity
|
||||
*/
|
||||
template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec.character> &&
|
||||
requires(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> &&
|
||||
std::constructible_from<ToRep, typename QP::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
@@ -177,7 +177,7 @@ template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP =
|
||||
}
|
||||
|
||||
template<Representation ToRep, Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec.character> &&
|
||||
requires(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> &&
|
||||
std::constructible_from<ToRep, typename QP::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
|
@@ -319,7 +319,7 @@ static_assert(invalid_getter_with_unit_conversion<quantity>);
|
||||
///////////////////////////////////////
|
||||
|
||||
template<Reference auto R, basic_fixed_string additional_nttp_argument,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep = double>
|
||||
RepresentationOf<get_quantity_spec(R)> Rep = double>
|
||||
struct child_quantity : quantity<R, Rep> {
|
||||
using quantity_type = quantity<R, Rep>;
|
||||
static constexpr auto reference = R;
|
||||
|
Reference in New Issue
Block a user