refactor: number() and number_in() renamed to value() and value_in()

Resolves #423
This commit is contained in:
Mateusz Pusz
2023-08-23 17:15:32 +02:00
parent ae92b49775
commit a9204e2473
21 changed files with 349 additions and 351 deletions

View File

@@ -33,7 +33,7 @@ template<mp_units::Quantity Target, mp_units::Quantity Source>
requires std::constructible_from<Target, Source> requires std::constructible_from<Target, Source>
inline constexpr double conversion_factor(Target, Source) inline constexpr double conversion_factor(Target, Source)
{ {
return mp_units::value_cast<Target::unit>(1. * Source::reference).number(); return mp_units::value_cast<Target::unit>(1. * Source::reference).value();
} }
} // namespace } // namespace
@@ -55,6 +55,6 @@ int main()
std::cout << MP_UNITS_STD_FMT::format("conversion factor from lengthA::unit of {:%q} to lengthB::unit of {:%q}:\n\n", std::cout << MP_UNITS_STD_FMT::format("conversion factor from lengthA::unit of {:%q} to lengthB::unit of {:%q}:\n\n",
lengthA, lengthB) lengthA, lengthB)
<< MP_UNITS_STD_FMT::format("lengthB.number( {} ) == lengthA.number( {} ) * conversion_factor( {} )\n", << MP_UNITS_STD_FMT::format("lengthB.value( {} ) == lengthA.value( {} ) * conversion_factor( {} )\n",
lengthB.number(), lengthA.number(), conversion_factor(lengthB, lengthA)); lengthB.value(), lengthA.value(), conversion_factor(lengthB, lengthA));
} }

View File

@@ -75,14 +75,14 @@ template<Unit auto From, Unit auto To>
template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep> template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep>
quantity<To, Rep> exchange_to(quantity<From, Rep> q) quantity<To, Rep> exchange_to(quantity<From, Rep> q)
{ {
return static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.number()) * To; return static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.value()) * To;
} }
template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, auto PO, typename Rep> template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, auto PO, typename Rep>
quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q) quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q)
{ {
return quantity_point{ return quantity_point{
zero + static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * (q - q.absolute_point_origin).number()) * To}; zero + static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * (q - q.absolute_point_origin).value()) * To};
} }
int main() int main()

View File

@@ -74,19 +74,19 @@ using longitude =
template<class CharT, class Traits, typename T> template<class CharT, class Traits, typename T>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const latitude<T>& lat) std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const latitude<T>& lat)
{ {
if (lat.number() > 0) if (lat.value() > 0)
return os << "N" << lat.number(); return os << "N" << lat.value();
else else
return os << "S" << -lat.number(); return os << "S" << -lat.value();
} }
template<class CharT, class Traits, typename T> template<class CharT, class Traits, typename T>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const longitude<T>& lon) std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const longitude<T>& lon)
{ {
if (lon.number() > 0) if (lon.value() > 0)
return os << "E" << lon.number(); return os << "E" << lon.value();
else else
return os << "W" << -lon.number(); return os << "W" << -lon.value();
} }
inline namespace literals { inline namespace literals {
@@ -129,7 +129,7 @@ struct MP_UNITS_STD_FMT::formatter<geographic::latitude<T>> : formatter<T> {
auto format(geographic::latitude<T> lat, FormatContext& ctx) auto format(geographic::latitude<T> lat, FormatContext& ctx)
{ {
MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lat > geographic::latitude<T>::zero() ? 'N' : 'S'); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lat > geographic::latitude<T>::zero() ? 'N' : 'S');
return formatter<T>::format(lat > geographic::latitude<T>::zero() ? lat.number() : -lat.number(), ctx); return formatter<T>::format(lat > geographic::latitude<T>::zero() ? lat.value() : -lat.value(), ctx);
} }
}; };
@@ -139,7 +139,7 @@ struct MP_UNITS_STD_FMT::formatter<geographic::longitude<T>> : formatter<T> {
auto format(geographic::longitude<T> lon, FormatContext& ctx) auto format(geographic::longitude<T> lon, FormatContext& ctx)
{ {
MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lon > geographic::longitude<T>::zero() ? 'E' : 'W'); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lon > geographic::longitude<T>::zero() ? 'E' : 'W');
return formatter<T>::format(lon > geographic::longitude<T>::zero() ? lon.number() : -lon.number(), ctx); return formatter<T>::format(lon > geographic::longitude<T>::zero() ? lon.value() : -lon.value(), ctx);
} }
}; };

View File

@@ -97,7 +97,7 @@ template<earth_gravity_model M>
hae_altitude<M> to_hae(msl_altitude msl, position<long double> pos) hae_altitude<M> to_hae(msl_altitude msl, position<long double> pos)
{ {
const auto geoid_undulation = const auto geoid_undulation =
isq::height(GeographicLibWhatsMyOffset(pos.lat.number_in(si::degree), pos.lon.number_in(si::degree)) * si::metre); isq::height(GeographicLibWhatsMyOffset(pos.lat.value_in(si::degree), pos.lon.value_in(si::degree)) * si::metre);
return height_above_ellipsoid<M> + (msl - mean_sea_level - geoid_undulation); return height_above_ellipsoid<M> + (msl - mean_sea_level - geoid_undulation);
} }

View File

@@ -226,7 +226,7 @@ struct quantity_formatter {
explicit quantity_formatter(OutputIt o, quantity<Reference, Rep> q, const quantity_format_specs<CharT>& fspecs, explicit quantity_formatter(OutputIt o, quantity<Reference, Rep> q, const quantity_format_specs<CharT>& fspecs,
Locale lc) : Locale lc) :
out(o), val(std::move(q).number()), specs(fspecs), loc(std::move(lc)) out(o), val(std::move(q).value()), specs(fspecs), loc(std::move(lc))
{ {
} }
@@ -396,7 +396,7 @@ private:
if (begin == end || *begin == '}') { if (begin == end || *begin == '}') {
// default format should print value followed by the unit separated with 1 space // default format should print value followed by the unit separated with 1 space
out = mp_units::detail::format_units_quantity_value<CharT>(out, q.number(), specs.rep, ctx.locale()); out = mp_units::detail::format_units_quantity_value<CharT>(out, q.value(), specs.rep, ctx.locale());
if constexpr (mp_units::detail::has_unit_symbol(get_unit(Reference))) { if constexpr (mp_units::detail::has_unit_symbol(get_unit(Reference))) {
*out++ = CharT(' '); *out++ = CharT(' ');
out = unit_symbol_to<CharT>(out, get_unit(Reference)); out = unit_symbol_to<CharT>(out, get_unit(Reference));

View File

@@ -36,9 +36,9 @@ void to_stream(std::basic_ostream<CharT, Traits>& os, const quantity<R, Rep>& q)
{ {
if constexpr (is_same_v<Rep, std::uint8_t> || is_same_v<Rep, std::int8_t>) if constexpr (is_same_v<Rep, std::uint8_t> || is_same_v<Rep, std::int8_t>)
// promote the value to int // promote the value to int
os << +q.number(); os << +q.value();
else else
os << q.number(); os << q.value();
if constexpr (has_unit_symbol(get_unit(R))) { if constexpr (has_unit_symbol(get_unit(R))) {
os << " "; os << " ";
unit_symbol_to<CharT>(std::ostream_iterator<CharT>(os), get_unit(R)); unit_symbol_to<CharT>(std::ostream_iterator<CharT>(os), get_unit(R));
@@ -49,7 +49,7 @@ void to_stream(std::basic_ostream<CharT, Traits>& os, const quantity<R, Rep>& q)
template<typename CharT, typename Traits, auto R, typename Rep> template<typename CharT, typename Traits, auto R, typename Rep>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const quantity<R, Rep>& q) std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const quantity<R, Rep>& q)
requires requires { os << q.number(); } requires requires { os << q.value(); }
{ {
if (os.width()) { if (os.width()) {
// std::setw() applies to the whole quantity output so it has to be first put into std::string // std::setw() applies to the whole quantity output so it has to be first put into std::string

View File

@@ -51,9 +51,9 @@ template<QuantitySpec auto ToQS, typename Q>
{ {
if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(ToQS)>> && if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(ToQS)>> &&
AssociatedUnit<std::remove_const_t<decltype(q.unit)>>) AssociatedUnit<std::remove_const_t<decltype(q.unit)>>)
return make_quantity<q.unit>(std::forward<Q>(q).number()); return make_quantity<q.unit>(std::forward<Q>(q).value());
else else
return make_quantity<reference<ToQS, q.unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<ToQS, q.unit>{}>(std::forward<Q>(q).value());
} }
} // namespace mp_units } // namespace mp_units

View File

@@ -74,7 +74,7 @@ concept QuantityLike = requires(T q) {
requires RepresentationOf<typename quantity_like_traits<T>::rep, requires RepresentationOf<typename quantity_like_traits<T>::rep,
get_quantity_spec(quantity_like_traits<T>::reference).character>; get_quantity_spec(quantity_like_traits<T>::reference).character>;
{ {
quantity_like_traits<T>::number(q) quantity_like_traits<T>::value(q)
} -> std::convertible_to<typename quantity_like_traits<T>::rep>; } -> std::convertible_to<typename quantity_like_traits<T>::rep>;
}; };

View File

@@ -63,10 +63,10 @@ template<Quantity To, typename From>
if constexpr (q_unit == To::unit) { if constexpr (q_unit == To::unit) {
// no scaling of the number needed // no scaling of the number needed
return make_quantity<To::reference>(static_cast<MP_UNITS_TYPENAME To::rep>( return make_quantity<To::reference>(static_cast<MP_UNITS_TYPENAME To::rep>(
std::forward<From>(q).number())); // this is the only (and recommended) way to do std::forward<From>(q).value())); // this is the only (and recommended) way to do
// a truncating conversion on a number, so we are // a truncating conversion on a number, so we are
// using static_cast to suppress all the compiler // using static_cast to suppress all the compiler
// warnings on conversions // warnings on conversions
} else { } else {
// scale the number // scale the number
constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag; constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag;
@@ -78,7 +78,7 @@ template<Quantity To, typename From>
using multiplier_type = using multiplier_type =
conditional<treat_as_floating_point<c_rep_type>, std::common_type_t<c_mag_type, long double>, c_mag_type>; conditional<treat_as_floating_point<c_rep_type>, std::common_type_t<c_mag_type, long double>, c_mag_type>;
constexpr auto val = [](Magnitude auto m) { return get_value<multiplier_type>(m); }; constexpr auto val = [](Magnitude auto m) { return get_value<multiplier_type>(m); };
return static_cast<MP_UNITS_TYPENAME To::rep>(static_cast<c_rep_type>(std::forward<From>(q).number()) * val(num) / return static_cast<MP_UNITS_TYPENAME To::rep>(static_cast<c_rep_type>(std::forward<From>(q).value()) * val(num) /
val(den) * val(irr)) * val(den) * val(irr)) *
To::reference; To::reference;
} }

View File

@@ -136,7 +136,7 @@ struct quantity_values {
* @brief Provides support for external quantity-like types * @brief Provides support for external quantity-like types
* *
* The type trait should provide the @c reference object, a type alias @c rep, * The type trait should provide the @c reference object, a type alias @c rep,
* and a static member function @c number(T) that returns the raw value of the quantity. * and a static member function @c value(T) that returns the raw value of the quantity.
* *
* Usage example can be found in @c units/chrono.h header file. * Usage example can be found in @c units/chrono.h header file.
* *

View File

@@ -134,7 +134,7 @@ public:
template<detail::QuantityConvertibleTo<quantity> Q> template<detail::QuantityConvertibleTo<quantity> Q>
constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) : constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) :
number_(detail::sudo_cast<quantity>(q).number()) number_(detail::sudo_cast<quantity>(q).value())
{ {
} }
@@ -142,7 +142,7 @@ public:
requires detail::QuantityConvertibleTo< requires detail::QuantityConvertibleTo<
quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>, quantity> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>, quantity>
constexpr explicit quantity(const Q& q) : constexpr explicit quantity(const Q& q) :
quantity(make_quantity<quantity_like_traits<Q>::reference>(quantity_like_traits<Q>::number(q))) quantity(make_quantity<quantity_like_traits<Q>::reference>(quantity_like_traits<Q>::value(q)))
{ {
} }
@@ -152,22 +152,22 @@ public:
// data access // data access
#ifdef __cpp_explicit_this_parameter #ifdef __cpp_explicit_this_parameter
template<typename Self> template<typename Self>
[[nodiscard]] constexpr auto&& number(this Self&& self) noexcept [[nodiscard]] constexpr auto&& value(this Self&& self) noexcept
{ {
return std::forward<Self>(self).number_; return std::forward<Self>(self).number_;
} }
#else #else
[[nodiscard]] constexpr rep& number() & noexcept { return number_; } [[nodiscard]] constexpr rep& value() & noexcept { return number_; }
[[nodiscard]] constexpr const rep& number() const& noexcept { return number_; } [[nodiscard]] constexpr const rep& value() const& noexcept { return number_; }
[[nodiscard]] constexpr rep&& number() && noexcept { return std::move(number_); } [[nodiscard]] constexpr rep&& value() && noexcept { return std::move(number_); }
[[nodiscard]] constexpr const rep&& number() const&& noexcept { return std::move(number_); } [[nodiscard]] constexpr const rep&& value() const&& noexcept { return std::move(number_); }
#endif #endif
template<Unit U> template<Unit U>
requires requires(quantity q) { q.in(U{}); } requires requires(quantity q) { q.in(U{}); }
[[nodiscard]] constexpr rep number_in(U) const noexcept [[nodiscard]] constexpr rep value_in(U) const noexcept
{ {
return (*this).in(U{}).number(); return (*this).in(U{}).value();
} }
template<Unit U> template<Unit U>
@@ -185,7 +185,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(+number()); return make_quantity<reference>(+value());
} }
[[nodiscard]] constexpr Quantity auto operator-() const [[nodiscard]] constexpr Quantity auto operator-() const
@@ -195,7 +195,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(-number()); return make_quantity<reference>(-value());
} }
constexpr quantity& operator++() constexpr quantity& operator++()
@@ -247,7 +247,7 @@ public:
} -> std::same_as<rep&>; } -> std::same_as<rep&>;
} }
{ {
number_ += q.number(); number_ += q.value();
return *this; return *this;
} }
@@ -258,7 +258,7 @@ public:
} -> std::same_as<rep&>; } -> std::same_as<rep&>;
} }
{ {
number_ -= q.number(); number_ -= q.value();
return *this; return *this;
} }
@@ -282,7 +282,7 @@ public:
} }
constexpr quantity& operator*=(const Q& rhs) constexpr quantity& operator*=(const Q& rhs)
{ {
number_ *= rhs.number(); number_ *= rhs.value();
return *this; return *this;
} }
@@ -307,8 +307,8 @@ public:
} }
constexpr quantity& operator/=(const Q& rhs) constexpr quantity& operator/=(const Q& rhs)
{ {
gsl_ExpectsAudit(rhs.number() != quantity_values<typename Q::rep>::zero()); gsl_ExpectsAudit(rhs.value() != quantity_values<typename Q::rep>::zero());
number_ /= rhs.number(); number_ /= rhs.value();
return *this; return *this;
} }
@@ -319,8 +319,8 @@ public:
} -> std::same_as<rep&>; } -> std::same_as<rep&>;
} }
{ {
gsl_ExpectsAudit(q.number() != quantity_values<rep>::zero()); gsl_ExpectsAudit(q.value() != quantity_values<rep>::zero());
number_ %= q.number(); number_ %= q.value();
return *this; return *this;
} }
@@ -346,7 +346,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
[[nodiscard]] constexpr Quantity auto operator+(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator+(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
using ret = detail::common_quantity_for<std::plus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::plus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
return make_quantity<ret::reference>(ret(lhs).number() + ret(rhs).number()); return make_quantity<ret::reference>(ret(lhs).value() + ret(rhs).value());
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@@ -354,7 +354,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
[[nodiscard]] constexpr Quantity auto operator-(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator-(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
using ret = detail::common_quantity_for<std::minus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::minus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
return make_quantity<ret::reference>(ret(lhs).number() - ret(rhs).number()); return make_quantity<ret::reference>(ret(lhs).value() - ret(rhs).value());
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@@ -362,7 +362,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
Rep2> Rep2>
[[nodiscard]] constexpr Quantity auto operator*(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator*(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
return make_quantity<R1 * R2>(lhs.number() * rhs.number()); return make_quantity<R1 * R2>(lhs.value() * rhs.value());
} }
template<auto R, typename Rep, typename Value> template<auto R, typename Rep, typename Value>
@@ -370,7 +370,7 @@ template<auto R, typename Rep, typename Value>
detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, Rep, const Value&> detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, Rep, const Value&>
[[nodiscard]] constexpr Quantity auto operator*(const quantity<R, Rep>& q, const Value& v) [[nodiscard]] constexpr Quantity auto operator*(const quantity<R, Rep>& q, const Value& v)
{ {
return make_quantity<R>(q.number() * v); return make_quantity<R>(q.value() * v);
} }
template<typename Value, auto R, typename Rep> template<typename Value, auto R, typename Rep>
@@ -378,15 +378,15 @@ template<typename Value, auto R, typename Rep>
detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, const Value&, Rep> detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, const Value&, Rep>
[[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity<R, Rep>& q) [[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity<R, Rep>& q)
{ {
return make_quantity<R>(v * q.number()); return make_quantity<R>(v * q.value());
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires detail::InvokeResultOf<(get_quantity_spec(R1) / get_quantity_spec(R2)).character, std::divides<>, Rep1, Rep2> requires detail::InvokeResultOf<(get_quantity_spec(R1) / get_quantity_spec(R2)).character, std::divides<>, Rep1, Rep2>
[[nodiscard]] constexpr Quantity auto operator/(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator/(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
gsl_ExpectsAudit(rhs.number() != quantity_values<Rep2>::zero()); gsl_ExpectsAudit(rhs.value() != quantity_values<Rep2>::zero());
return make_quantity<R1 / R2>(lhs.number() / rhs.number()); return make_quantity<R1 / R2>(lhs.value() / rhs.value());
} }
template<auto R, typename Rep, typename Value> template<auto R, typename Rep, typename Value>
@@ -395,7 +395,7 @@ template<auto R, typename Rep, typename Value>
[[nodiscard]] constexpr Quantity auto operator/(const quantity<R, Rep>& q, const Value& v) [[nodiscard]] constexpr Quantity auto operator/(const quantity<R, Rep>& q, const Value& v)
{ {
gsl_ExpectsAudit(v != quantity_values<Value>::zero()); gsl_ExpectsAudit(v != quantity_values<Value>::zero());
return make_quantity<R>(q.number() / v); return make_quantity<R>(q.value() / v);
} }
template<typename Value, auto R, typename Rep> template<typename Value, auto R, typename Rep>
@@ -403,7 +403,7 @@ template<typename Value, auto R, typename Rep>
detail::InvokeResultOf<get_quantity_spec(R).character, std::divides<>, const Value&, Rep> detail::InvokeResultOf<get_quantity_spec(R).character, std::divides<>, const Value&, Rep>
[[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity<R, Rep>& q) [[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity<R, Rep>& q)
{ {
return make_quantity<::mp_units::one / R>(v / q.number()); return make_quantity<::mp_units::one / R>(v / q.value());
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@@ -411,9 +411,9 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
detail::InvocableQuantities<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>> detail::InvocableQuantities<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>
[[nodiscard]] constexpr Quantity auto operator%(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator%(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
gsl_ExpectsAudit(rhs.number() != quantity_values<Rep1>::zero()); gsl_ExpectsAudit(rhs.value() != quantity_values<Rep1>::zero());
using ret = detail::common_quantity_for<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
return make_quantity<ret::reference>(ret(lhs).number() % ret(rhs).number()); return make_quantity<ret::reference>(ret(lhs).value() % ret(rhs).value());
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@@ -422,7 +422,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
[[nodiscard]] constexpr bool operator==(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr bool operator==(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
using ct = std::common_type_t<quantity<R1, Rep1>, quantity<R2, Rep2>>; using ct = std::common_type_t<quantity<R1, Rep1>, quantity<R2, Rep2>>;
return ct(lhs).number() == ct(rhs).number(); return ct(lhs).value() == ct(rhs).value();
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@@ -431,7 +431,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
[[nodiscard]] constexpr auto operator<=>(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr auto operator<=>(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
using ct = std::common_type_t<quantity<R1, Rep1>, quantity<R2, Rep2>>; using ct = std::common_type_t<quantity<R1, Rep1>, quantity<R2, Rep2>>;
return ct(lhs).number() <=> ct(rhs).number(); return ct(lhs).value() <=> ct(rhs).value();
} }
// make_quantity // make_quantity

View File

@@ -115,7 +115,7 @@ struct quantity_spec_interface {
requires Quantity<std::remove_cvref_t<Q>> && requires Quantity<std::remove_cvref_t<Q>> &&
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self)) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self))
{ {
return make_quantity<reference<self, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<self, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).value());
} }
#else #else
template<typename Self_ = Self, UnitOf<Self_{}> U> template<typename Self_ = Self, UnitOf<Self_{}> U>
@@ -132,7 +132,7 @@ struct quantity_spec_interface {
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).value());
} }
#endif #endif
}; };
@@ -311,7 +311,7 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).number()); return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>(std::forward<Q>(q).value());
} }
#endif #endif
}; };

View File

@@ -64,7 +64,7 @@ template<typename Rep, typename Period>
struct quantity_like_traits<std::chrono::duration<Rep, Period>> { struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
static constexpr auto reference = detail::time_unit_from_chrono_period<Period>(); static constexpr auto reference = detail::time_unit_from_chrono_period<Period>();
using rep = Rep; using rep = Rep;
[[nodiscard]] static constexpr rep number(const std::chrono::duration<Rep, Period>& q) { return q.count(); } [[nodiscard]] static constexpr rep value(const std::chrono::duration<Rep, Period>& q) { return q.count(); }
}; };
template<typename C> template<typename C>
@@ -92,7 +92,7 @@ template<QuantityOf<isq::time> Q>
{ {
constexpr auto canonical = detail::get_canonical_unit(Q::unit); constexpr auto canonical = detail::get_canonical_unit(Q::unit);
constexpr ratio r = as_ratio(canonical.mag); constexpr ratio r = as_ratio(canonical.mag);
return std::chrono::duration<typename Q::rep, std::ratio<r.num, r.den>>{q.number()}; return std::chrono::duration<typename Q::rep, std::ratio<r.num, r.den>>{q.value()};
} }
template<QuantityPointOf<isq::time> QP> template<QuantityPointOf<isq::time> QP>

View File

@@ -54,7 +54,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto R, typename Rep>
requires detail::non_zero<Den> && requires detail::non_zero<Den> &&
requires { quantity_values<Rep>::one(); } requires { quantity_values<Rep>::one(); }
[[nodiscard]] constexpr quantity<pow<Num, Den>(R), Rep> pow(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<pow<Num, Den>(R), Rep> pow(const quantity<R, Rep>& q) noexcept
requires requires { pow(q.number(), 1.0); } || requires { std::pow(q.number(), 1.0); } requires requires { pow(q.value(), 1.0); } || requires { std::pow(q.value(), 1.0); }
{ {
if constexpr (Num == 0) { if constexpr (Num == 0) {
return quantity<pow<Num, Den>(R), Rep>::one(); return quantity<pow<Num, Den>(R), Rep>::one();
@@ -63,7 +63,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto R, typename Rep>
} else { } else {
using std::pow; using std::pow;
return make_quantity<pow<Num, Den>(R)>( return make_quantity<pow<Num, Den>(R)>(
static_cast<Rep>(pow(q.number(), static_cast<double>(Num) / static_cast<double>(Den)))); static_cast<Rep>(pow(q.value(), static_cast<double>(Num) / static_cast<double>(Den))));
} }
} }
@@ -77,10 +77,10 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto R, typename Rep>
*/ */
template<auto R, typename Rep> template<auto R, typename Rep>
[[nodiscard]] constexpr quantity<sqrt(R), Rep> sqrt(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<sqrt(R), Rep> sqrt(const quantity<R, Rep>& q) noexcept
requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); } requires requires { sqrt(q.value()); } || requires { std::sqrt(q.value()); }
{ {
using std::sqrt; using std::sqrt;
return make_quantity<sqrt(R)>(static_cast<Rep>(sqrt(q.number()))); return make_quantity<sqrt(R)>(static_cast<Rep>(sqrt(q.value())));
} }
/** /**
@@ -93,10 +93,10 @@ template<auto R, typename Rep>
*/ */
template<auto R, typename Rep> template<auto R, typename Rep>
[[nodiscard]] constexpr quantity<cbrt(R), Rep> cbrt(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<cbrt(R), Rep> cbrt(const quantity<R, Rep>& q) noexcept
requires requires { cbrt(q.number()); } || requires { std::cbrt(q.number()); } requires requires { cbrt(q.value()); } || requires { std::cbrt(q.value()); }
{ {
using std::cbrt; using std::cbrt;
return make_quantity<cbrt(R)>(static_cast<Rep>(cbrt(q.number()))); return make_quantity<cbrt(R)>(static_cast<Rep>(cbrt(q.value())));
} }
/** /**
@@ -109,11 +109,11 @@ template<auto R, typename Rep>
*/ */
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
[[nodiscard]] constexpr quantity<R, Rep> exp(const quantity<R, Rep>& q) [[nodiscard]] constexpr quantity<R, Rep> exp(const quantity<R, Rep>& q)
requires requires { exp(q.number()); } || requires { std::exp(q.number()); } requires requires { exp(q.value()); } || requires { std::exp(q.value()); }
{ {
using std::exp; using std::exp;
return value_cast<get_unit(R)>( return value_cast<get_unit(R)>(
make_quantity<detail::clone_reference_with<one>(R)>(static_cast<Rep>(exp(value_cast<one>(q).number())))); make_quantity<detail::clone_reference_with<one>(R)>(static_cast<Rep>(exp(value_cast<one>(q).value()))));
} }
/** /**
@@ -124,10 +124,10 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
*/ */
template<auto R, typename Rep> template<auto R, typename Rep>
[[nodiscard]] constexpr quantity<R, Rep> abs(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<R, Rep> abs(const quantity<R, Rep>& q) noexcept
requires requires { abs(q.number()); } || requires { std::abs(q.number()); } requires requires { abs(q.value()); } || requires { std::abs(q.value()); }
{ {
using std::abs; using std::abs;
return make_quantity<R>(static_cast<Rep>(abs(q.number()))); return make_quantity<R>(static_cast<Rep>(abs(q.value())));
} }
/** /**
@@ -153,8 +153,7 @@ template<Representation Rep, Reference R>
*/ */
template<Unit auto To, auto R, typename Rep> template<Unit auto To, auto R, typename Rep>
[[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> floor(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> floor(const quantity<R, Rep>& q) noexcept
requires((!treat_as_floating_point<Rep>) || requires { floor(q.number()); } || requires((!treat_as_floating_point<Rep>) || requires { floor(q.value()); } || requires { std::floor(q.value()); }) &&
requires { std::floor(q.number()); }) &&
(To == get_unit(R) || requires { (To == get_unit(R) || requires {
::mp_units::value_cast<To>(q); ::mp_units::value_cast<To>(q);
quantity_values<Rep>::one(); quantity_values<Rep>::one();
@@ -169,10 +168,10 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::floor; using std::floor;
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
return make_quantity<detail::clone_reference_with<To>(R)>(static_cast<Rep>(floor(q.number()))); return make_quantity<detail::clone_reference_with<To>(R)>(static_cast<Rep>(floor(q.value())));
} else { } else {
return handle_signed_results(make_quantity<detail::clone_reference_with<To>(q.reference)>( return handle_signed_results(make_quantity<detail::clone_reference_with<To>(q.reference)>(
static_cast<Rep>(floor(value_cast<To>(q).number())))); static_cast<Rep>(floor(value_cast<To>(q).value()))));
} }
} else { } else {
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
@@ -191,7 +190,7 @@ template<Unit auto To, auto R, typename Rep>
*/ */
template<Unit auto To, auto R, typename Rep> template<Unit auto To, auto R, typename Rep>
[[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> ceil(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> ceil(const quantity<R, Rep>& q) noexcept
requires((!treat_as_floating_point<Rep>) || requires { ceil(q.number()); } || requires { std::ceil(q.number()); }) && requires((!treat_as_floating_point<Rep>) || requires { ceil(q.value()); } || requires { std::ceil(q.value()); }) &&
(To == get_unit(R) || requires { (To == get_unit(R) || requires {
::mp_units::value_cast<To>(q); ::mp_units::value_cast<To>(q);
quantity_values<Rep>::one(); quantity_values<Rep>::one();
@@ -206,10 +205,10 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::ceil; using std::ceil;
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
return make_quantity<detail::clone_reference_with<To>(q.reference)>(static_cast<Rep>(ceil(q.number()))); return make_quantity<detail::clone_reference_with<To>(q.reference)>(static_cast<Rep>(ceil(q.value())));
} else { } else {
return handle_signed_results(make_quantity<detail::clone_reference_with<To>(q.reference)>( return handle_signed_results(make_quantity<detail::clone_reference_with<To>(q.reference)>(
static_cast<Rep>(ceil(value_cast<To>(q).number())))); static_cast<Rep>(ceil(value_cast<To>(q).value()))));
} }
} else { } else {
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
@@ -230,8 +229,7 @@ template<Unit auto To, auto R, typename Rep>
*/ */
template<Unit auto To, auto R, typename Rep> template<Unit auto To, auto R, typename Rep>
[[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> round(const quantity<R, Rep>& q) noexcept [[nodiscard]] constexpr quantity<detail::clone_reference_with<To>(R), Rep> round(const quantity<R, Rep>& q) noexcept
requires((!treat_as_floating_point<Rep>) || requires { round(q.number()); } || requires((!treat_as_floating_point<Rep>) || requires { round(q.value()); } || requires { std::round(q.value()); }) &&
requires { std::round(q.number()); }) &&
(To == get_unit(R) || requires { (To == get_unit(R) || requires {
::mp_units::floor<To>(q); ::mp_units::floor<To>(q);
quantity_values<Rep>::one(); quantity_values<Rep>::one();
@@ -240,7 +238,7 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::round; using std::round;
return make_quantity<detail::clone_reference_with<To>(q.reference)>(static_cast<Rep>(round(q.number()))); return make_quantity<detail::clone_reference_with<To>(q.reference)>(static_cast<Rep>(round(q.value())));
} else { } else {
return value_cast<To>(q); return value_cast<To>(q);
} }
@@ -250,7 +248,7 @@ template<Unit auto To, auto R, typename Rep>
const auto diff0 = q - res_low; const auto diff0 = q - res_low;
const auto diff1 = res_high - q; const auto diff1 = res_high - q;
if (diff0 == diff1) { if (diff0 == diff1) {
if (static_cast<int>(res_low.number()) & 1) { if (static_cast<int>(res_low.value()) & 1) {
return res_high; return res_high;
} }
return res_low; return res_low;
@@ -271,12 +269,12 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y) noexcept const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y) noexcept
requires requires { common_reference(R1, R2); } && requires requires { common_reference(R1, R2); } &&
( (
requires { hypot(x.number(), y.number()); } || requires { std::hypot(x.number(), y.number()); }) requires { hypot(x.value(), y.value()); } || requires { std::hypot(x.value(), y.value()); })
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return make_quantity<ref>(hypot(x.number_in(unit), y.number_in(unit))); return make_quantity<ref>(hypot(x.value_in(unit), y.value_in(unit)));
} }
/** /**
@@ -287,13 +285,13 @@ template<auto R1, typename Rep1, auto R2, typename Rep2, auto R3, typename Rep3>
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(common_reference(R1, R2, R3))> auto hypot( [[nodiscard]] constexpr QuantityOf<get_quantity_spec(common_reference(R1, R2, R3))> auto hypot(
const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y, const quantity<R3, Rep3>& z) noexcept const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y, const quantity<R3, Rep3>& z) noexcept
requires requires { common_reference(R1, R2, R3); } && ( requires requires { common_reference(R1, R2, R3); } && (
requires { hypot(x.number(), y.number(), z.number()); } || requires { hypot(x.value(), y.value(), z.value()); } ||
requires { std::hypot(x.number(), y.number(), z.number()); }) requires { std::hypot(x.value(), y.value(), z.value()); })
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return make_quantity<ref>(hypot(x.number_in(unit), y.number_in(unit), z.number_in(unit))); return make_quantity<ref>(hypot(x.value_in(unit), y.value_in(unit), z.value_in(unit)));
} }
namespace isq { namespace isq {
@@ -301,55 +299,55 @@ namespace isq {
template<ReferenceOf<angular_measure> auto R, typename Rep> template<ReferenceOf<angular_measure> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> sin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> sin(const quantity<R, Rep>& q) noexcept
requires requires { sin(q.number()); } || requires { std::sin(q.number()); } requires requires { sin(q.value()); } || requires { std::sin(q.value()); }
{ {
using std::sin; using std::sin;
return make_quantity<one>(static_cast<Rep>(sin(q.in(si::radian).number()))); return make_quantity<one>(static_cast<Rep>(sin(q.in(si::radian).value())));
} }
template<ReferenceOf<angular_measure> auto R, typename Rep> template<ReferenceOf<angular_measure> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> cos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> cos(const quantity<R, Rep>& q) noexcept
requires requires { cos(q.number()); } || requires { std::cos(q.number()); } requires requires { cos(q.value()); } || requires { std::cos(q.value()); }
{ {
using std::cos; using std::cos;
return make_quantity<one>(static_cast<Rep>(cos(q.in(si::radian).number()))); return make_quantity<one>(static_cast<Rep>(cos(q.in(si::radian).value())));
} }
template<ReferenceOf<angular_measure> auto R, typename Rep> template<ReferenceOf<angular_measure> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> tan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> tan(const quantity<R, Rep>& q) noexcept
requires requires { tan(q.number()); } || requires { std::tan(q.number()); } requires requires { tan(q.value()); } || requires { std::tan(q.value()); }
{ {
using std::tan; using std::tan;
return make_quantity<one>(static_cast<Rep>(tan(q.in(si::radian).number()))); return make_quantity<one>(static_cast<Rep>(tan(q.in(si::radian).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<si::radian, Rep> asin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<si::radian, Rep> asin(const quantity<R, Rep>& q) noexcept
requires requires { asin(q.number()); } || requires { std::asin(q.number()); } requires requires { asin(q.value()); } || requires { std::asin(q.value()); }
{ {
using std::asin; using std::asin;
return make_quantity<si::radian>(static_cast<Rep>(asin(value_cast<one>(q).number()))); return make_quantity<si::radian>(static_cast<Rep>(asin(value_cast<one>(q).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<si::radian, Rep> acos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<si::radian, Rep> acos(const quantity<R, Rep>& q) noexcept
requires requires { acos(q.number()); } || requires { std::acos(q.number()); } requires requires { acos(q.value()); } || requires { std::acos(q.value()); }
{ {
using std::acos; using std::acos;
return make_quantity<si::radian>(static_cast<Rep>(acos(value_cast<one>(q).number()))); return make_quantity<si::radian>(static_cast<Rep>(acos(value_cast<one>(q).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<si::radian, Rep> atan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<si::radian, Rep> atan(const quantity<R, Rep>& q) noexcept
requires requires { atan(q.number()); } || requires { std::atan(q.number()); } requires requires { atan(q.value()); } || requires { std::atan(q.value()); }
{ {
using std::atan; using std::atan;
return make_quantity<si::radian>(static_cast<Rep>(atan(value_cast<one>(q).number()))); return make_quantity<si::radian>(static_cast<Rep>(atan(value_cast<one>(q).value())));
} }
} // namespace isq } // namespace isq
@@ -359,55 +357,55 @@ namespace angular {
template<ReferenceOf<angle> auto R, typename Rep> template<ReferenceOf<angle> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> sin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> sin(const quantity<R, Rep>& q) noexcept
requires requires { sin(q.number()); } || requires { std::sin(q.number()); } requires requires { sin(q.value()); } || requires { std::sin(q.value()); }
{ {
using std::sin; using std::sin;
return make_quantity<one>(static_cast<Rep>(sin(q.in(radian).number()))); return make_quantity<one>(static_cast<Rep>(sin(q.in(radian).value())));
} }
template<ReferenceOf<angle> auto R, typename Rep> template<ReferenceOf<angle> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> cos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> cos(const quantity<R, Rep>& q) noexcept
requires requires { cos(q.number()); } || requires { std::cos(q.number()); } requires requires { cos(q.value()); } || requires { std::cos(q.value()); }
{ {
using std::cos; using std::cos;
return make_quantity<one>(static_cast<Rep>(cos(q.in(radian).number()))); return make_quantity<one>(static_cast<Rep>(cos(q.in(radian).value())));
} }
template<ReferenceOf<angle> auto R, typename Rep> template<ReferenceOf<angle> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<one, Rep> tan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<one, Rep> tan(const quantity<R, Rep>& q) noexcept
requires requires { tan(q.number()); } || requires { std::tan(q.number()); } requires requires { tan(q.value()); } || requires { std::tan(q.value()); }
{ {
using std::tan; using std::tan;
return make_quantity<one>(static_cast<Rep>(tan(q.in(radian).number()))); return make_quantity<one>(static_cast<Rep>(tan(q.in(radian).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<radian, Rep> asin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<radian, Rep> asin(const quantity<R, Rep>& q) noexcept
requires requires { asin(q.number()); } || requires { std::asin(q.number()); } requires requires { asin(q.value()); } || requires { std::asin(q.value()); }
{ {
using std::asin; using std::asin;
return make_quantity<radian>(static_cast<Rep>(asin(value_cast<one>(q).number()))); return make_quantity<radian>(static_cast<Rep>(asin(value_cast<one>(q).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<radian, Rep> acos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<radian, Rep> acos(const quantity<R, Rep>& q) noexcept
requires requires { acos(q.number()); } || requires { std::acos(q.number()); } requires requires { acos(q.value()); } || requires { std::acos(q.value()); }
{ {
using std::acos; using std::acos;
return make_quantity<radian>(static_cast<Rep>(acos(value_cast<one>(q).number()))); return make_quantity<radian>(static_cast<Rep>(acos(value_cast<one>(q).value())));
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires treat_as_floating_point<Rep> requires treat_as_floating_point<Rep>
[[nodiscard]] inline quantity<radian, Rep> atan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline quantity<radian, Rep> atan(const quantity<R, Rep>& q) noexcept
requires requires { atan(q.number()); } || requires { std::atan(q.number()); } requires requires { atan(q.value()); } || requires { std::atan(q.value()); }
{ {
using std::atan; using std::atan;
return make_quantity<radian>(static_cast<Rep>(atan(value_cast<one>(q).number()))); return make_quantity<radian>(static_cast<Rep>(atan(value_cast<one>(q).value())));
} }
} // namespace angular } // namespace angular

View File

@@ -35,7 +35,7 @@ static std::vector<typename Q::rep> i_qty_to_rep(InputIt first, InputIt last)
std::vector<typename Q::rep> intervals_rep; std::vector<typename Q::rep> intervals_rep;
intervals_rep.reserve(static_cast<size_t>(std::distance(first, last))); intervals_rep.reserve(static_cast<size_t>(std::distance(first, last)));
for (auto itr = first; itr != last; ++itr) { for (auto itr = first; itr != last; ++itr) {
intervals_rep.push_back(itr->number()); intervals_rep.push_back(itr->value());
} }
return intervals_rep; return intervals_rep;
} }
@@ -46,7 +46,7 @@ static std::vector<typename Q::rep> bl_qty_to_rep(std::initializer_list<Q>& bl)
std::vector<typename Q::rep> bl_rep; std::vector<typename Q::rep> bl_rep;
bl_rep.reserve(bl.size()); bl_rep.reserve(bl.size());
for (const Q& qty : bl) { for (const Q& qty : bl) {
bl_rep.push_back(qty.number()); bl_rep.push_back(qty.value());
} }
return bl_rep; return bl_rep;
} }
@@ -88,7 +88,7 @@ struct uniform_int_distribution : public std::uniform_int_distribution<typename
using base = MP_UNITS_TYPENAME std::uniform_int_distribution<rep>; using base = MP_UNITS_TYPENAME std::uniform_int_distribution<rep>;
uniform_int_distribution() : base() {} uniform_int_distribution() : base() {}
uniform_int_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {} uniform_int_distribution(const Q& a, const Q& b) : base(a.value(), b.value()) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -110,7 +110,7 @@ struct uniform_real_distribution : public std::uniform_real_distribution<typenam
using base = MP_UNITS_TYPENAME std::uniform_real_distribution<rep>; using base = MP_UNITS_TYPENAME std::uniform_real_distribution<rep>;
uniform_real_distribution() : base() {} uniform_real_distribution() : base() {}
uniform_real_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {} uniform_real_distribution(const Q& a, const Q& b) : base(a.value(), b.value()) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -132,7 +132,7 @@ struct binomial_distribution : public std::binomial_distribution<typename Q::rep
using base = MP_UNITS_TYPENAME std::binomial_distribution<rep>; using base = MP_UNITS_TYPENAME std::binomial_distribution<rep>;
binomial_distribution() : base() {} binomial_distribution() : base() {}
binomial_distribution(const Q& t, double p) : base(t.number(), p) {} binomial_distribution(const Q& t, double p) : base(t.value(), p) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -153,7 +153,7 @@ struct negative_binomial_distribution : public std::negative_binomial_distributi
using base = MP_UNITS_TYPENAME std::negative_binomial_distribution<rep>; using base = MP_UNITS_TYPENAME std::negative_binomial_distribution<rep>;
negative_binomial_distribution() : base() {} negative_binomial_distribution() : base() {}
negative_binomial_distribution(const Q& k, double p) : base(k.number(), p) {} negative_binomial_distribution(const Q& k, double p) : base(k.value(), p) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -269,7 +269,7 @@ struct extreme_value_distribution : public std::extreme_value_distribution<typen
using base = MP_UNITS_TYPENAME std::extreme_value_distribution<rep>; using base = MP_UNITS_TYPENAME std::extreme_value_distribution<rep>;
extreme_value_distribution() : base() {} extreme_value_distribution() : base() {}
extreme_value_distribution(const Q& a, const rep& b) : base(a.number(), b) {} extreme_value_distribution(const Q& a, const rep& b) : base(a.value(), b) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -290,7 +290,7 @@ struct normal_distribution : public std::normal_distribution<typename Q::rep> {
using base = MP_UNITS_TYPENAME std::normal_distribution<rep>; using base = MP_UNITS_TYPENAME std::normal_distribution<rep>;
normal_distribution() : base() {} normal_distribution() : base() {}
normal_distribution(const Q& mean, const Q& stddev) : base(mean.number(), stddev.number()) {} normal_distribution(const Q& mean, const Q& stddev) : base(mean.value(), stddev.value()) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -312,7 +312,7 @@ struct lognormal_distribution : public std::lognormal_distribution<typename Q::r
using base = MP_UNITS_TYPENAME std::lognormal_distribution<rep>; using base = MP_UNITS_TYPENAME std::lognormal_distribution<rep>;
lognormal_distribution() : base() {} lognormal_distribution() : base() {}
lognormal_distribution(const Q& m, const Q& s) : base(m.number(), s.number()) {} lognormal_distribution(const Q& m, const Q& s) : base(m.value(), s.value()) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -353,7 +353,7 @@ struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep> {
using base = MP_UNITS_TYPENAME std::cauchy_distribution<rep>; using base = MP_UNITS_TYPENAME std::cauchy_distribution<rep>;
cauchy_distribution() : base() {} cauchy_distribution() : base() {}
cauchy_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {} cauchy_distribution(const Q& a, const Q& b) : base(a.value(), b.value()) {}
template<typename Generator> template<typename Generator>
Q operator()(Generator& g) Q operator()(Generator& g)
@@ -470,7 +470,7 @@ public:
template<typename UnaryOperation> template<typename UnaryOperation>
piecewise_constant_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) : piecewise_constant_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(val * Q::reference); }) base(nw, xmin.value(), xmax.value(), [fw](rep val) { return fw(val * Q::reference); })
{ {
} }
@@ -528,7 +528,7 @@ public:
template<typename UnaryOperation> template<typename UnaryOperation>
piecewise_linear_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) : piecewise_linear_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(val * Q::reference); }) base(nw, xmin.value(), xmax.value(), [fw](rep val) { return fw(val * Q::reference); })
{ {
} }

View File

@@ -36,8 +36,8 @@ struct AlmostEqualsMatcher : Catch::Matchers::MatcherGenericBase {
{ {
using std::abs; using std::abs;
using common = std::common_type_t<T, U>; using common = std::common_type_t<T, U>;
const auto x = common(target_).number(); const auto x = common(target_).value();
const auto y = common(other).number(); const auto y = common(other).value();
const auto maxXYOne = std::max({typename T::rep{1}, abs(x), abs(y)}); const auto maxXYOne = std::max({typename T::rep{1}, abs(x), abs(y)});
return abs(x - y) <= std::numeric_limits<typename T::rep>::epsilon() * maxXYOne; return abs(x - y) <= std::numeric_limits<typename T::rep>::epsilon() * maxXYOne;
} }

View File

@@ -559,7 +559,7 @@ TEST_CASE("piecewise_constant_distribution")
3.0 * isq::length[si::metre]}; 3.0 * isq::length[si::metre]};
auto stl_dist = std::piecewise_constant_distribution<rep>(intervals_rep, [](rep val) { return val; }); auto stl_dist = std::piecewise_constant_distribution<rep>(intervals_rep, [](rep val) { return val; });
auto units_dist = mp_units::piecewise_constant_distribution<q>(intervals_qty, [](q qty) { return qty.number(); }); auto units_dist = mp_units::piecewise_constant_distribution<q>(intervals_qty, [](q qty) { return qty.value(); });
CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.intervals() == intervals_qty_vec);
CHECK(units_dist.densities() == stl_dist.densities()); CHECK(units_dist.densities() == stl_dist.densities());
@@ -573,7 +573,7 @@ TEST_CASE("piecewise_constant_distribution")
auto stl_dist = std::piecewise_constant_distribution<rep>(nw, xmin_rep, xmax_rep, [](rep val) { return val; }); auto stl_dist = std::piecewise_constant_distribution<rep>(nw, xmin_rep, xmax_rep, [](rep val) { return val; });
auto units_dist = auto units_dist =
mp_units::piecewise_constant_distribution<q>(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); mp_units::piecewise_constant_distribution<q>(nw, xmin_qty, xmax_qty, [](q qty) { return qty.value(); });
CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.intervals() == intervals_qty_vec);
CHECK(units_dist.densities() == stl_dist.densities()); CHECK(units_dist.densities() == stl_dist.densities());
@@ -626,7 +626,7 @@ TEST_CASE("piecewise_linear_distribution")
3.0 * isq::length[si::metre]}; 3.0 * isq::length[si::metre]};
auto stl_dist = std::piecewise_linear_distribution<rep>(intervals_rep, [](rep val) { return val; }); auto stl_dist = std::piecewise_linear_distribution<rep>(intervals_rep, [](rep val) { return val; });
auto units_dist = mp_units::piecewise_linear_distribution<q>(intervals_qty, [](q qty) { return qty.number(); }); auto units_dist = mp_units::piecewise_linear_distribution<q>(intervals_qty, [](q qty) { return qty.value(); });
CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.intervals() == intervals_qty_vec);
CHECK(units_dist.densities() == stl_dist.densities()); CHECK(units_dist.densities() == stl_dist.densities());
@@ -640,7 +640,7 @@ TEST_CASE("piecewise_linear_distribution")
auto stl_dist = std::piecewise_linear_distribution<rep>(nw, xmin_rep, xmax_rep, [](rep val) { return val; }); auto stl_dist = std::piecewise_linear_distribution<rep>(nw, xmin_rep, xmax_rep, [](rep val) { return val; });
auto units_dist = auto units_dist =
mp_units::piecewise_linear_distribution<q>(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); mp_units::piecewise_linear_distribution<q>(nw, xmin_qty, xmax_qty, [](q qty) { return qty.value(); });
CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.intervals() == intervals_qty_vec);
CHECK(units_dist.densities() == stl_dist.densities()); CHECK(units_dist.densities() == stl_dist.densities());

View File

@@ -71,7 +71,7 @@ template<Quantity Q1, Quantity Q2>
requires(typename Q1::rep v1, typename Q2::rep v2) { cross_product(v1, v2); } requires(typename Q1::rep v1, typename Q2::rep v2) { cross_product(v1, v2); }
[[nodiscard]] QuantityOf<Q1::quantity_spec * Q2::quantity_spec> auto cross_product(const Q1& q1, const Q2& q2) [[nodiscard]] QuantityOf<Q1::quantity_spec * Q2::quantity_spec> auto cross_product(const Q1& q1, const Q2& q2)
{ {
return cross_product(q1.number(), q2.number()) * (Q1::reference * Q2::reference); return cross_product(q1.value(), q2.value()) * (Q1::reference * Q2::reference);
} }
} // namespace } // namespace
@@ -83,21 +83,21 @@ TEST_CASE("vector quantity", "[la]")
SECTION("non-truncating") SECTION("non-truncating")
{ {
const auto v = vector<int>{3, 2, 1} * isq::position_vector[km]; const auto v = vector<int>{3, 2, 1} * isq::position_vector[km];
CHECK(v.in(m).number() == vector<int>{3000, 2000, 1000}); CHECK(v.in(m).value() == vector<int>{3000, 2000, 1000});
} }
SECTION("truncating") SECTION("truncating")
{ {
const auto v = vector<int>{1001, 1002, 1003} * isq::position_vector[m]; const auto v = vector<int>{1001, 1002, 1003} * isq::position_vector[m];
CHECK(value_cast<km>(v).number() == vector<int>{1, 1, 1}); CHECK(value_cast<km>(v).value() == vector<int>{1, 1, 1});
} }
} }
SECTION("to scalar magnitude") SECTION("to scalar magnitude")
{ {
const auto v = vector<int>{2, 3, 6} * isq::velocity[km / h]; const auto v = vector<int>{2, 3, 6} * isq::velocity[km / h];
const auto speed = get_magnitude(v.number()) * isq::speed[v.unit]; // TODO can we do better here? const auto speed = get_magnitude(v.value()) * isq::speed[v.unit]; // TODO can we do better here?
CHECK(speed.number() == 7); CHECK(speed.value() == 7);
} }
SECTION("multiply by scalar value") SECTION("multiply by scalar value")
@@ -106,14 +106,14 @@ TEST_CASE("vector quantity", "[la]")
SECTION("integral") SECTION("integral")
{ {
SECTION("scalar on LHS") { CHECK((2 * v).number() == vector<int>{2, 4, 6}); } SECTION("scalar on LHS") { CHECK((2 * v).value() == vector<int>{2, 4, 6}); }
SECTION("scalar on RHS") { CHECK((v * 2).number() == vector<int>{2, 4, 6}); } SECTION("scalar on RHS") { CHECK((v * 2).value() == vector<int>{2, 4, 6}); }
} }
SECTION("floating-point") SECTION("floating-point")
{ {
SECTION("scalar on LHS") { CHECK((0.5 * v).number() == vector<double>{0.5, 1., 1.5}); } SECTION("scalar on LHS") { CHECK((0.5 * v).value() == vector<double>{0.5, 1., 1.5}); }
SECTION("scalar on RHS") { CHECK((v * 0.5).number() == vector<double>{0.5, 1., 1.5}); } SECTION("scalar on RHS") { CHECK((v * 0.5).value() == vector<double>{0.5, 1., 1.5}); }
} }
} }
@@ -121,8 +121,8 @@ TEST_CASE("vector quantity", "[la]")
{ {
const auto v = vector<int>{2, 4, 6} * isq::position_vector[m]; const auto v = vector<int>{2, 4, 6} * isq::position_vector[m];
SECTION("integral") { CHECK((v / 2).number() == vector<int>{1, 2, 3}); } SECTION("integral") { CHECK((v / 2).value() == vector<int>{1, 2, 3}); }
SECTION("floating-point") { CHECK((v / 0.5).number() == vector<double>{4., 8., 12.}); } SECTION("floating-point") { CHECK((v / 0.5).value() == vector<double>{4., 8., 12.}); }
} }
SECTION("add") SECTION("add")
@@ -132,12 +132,12 @@ TEST_CASE("vector quantity", "[la]")
SECTION("same unit") SECTION("same unit")
{ {
const auto u = vector<int>{3, 2, 1} * isq::position_vector[m]; const auto u = vector<int>{3, 2, 1} * isq::position_vector[m];
CHECK((v + u).number() == vector<int>{4, 4, 4}); CHECK((v + u).value() == vector<int>{4, 4, 4});
} }
SECTION("different units") SECTION("different units")
{ {
const auto u = vector<int>{3, 2, 1} * isq::position_vector[km]; const auto u = vector<int>{3, 2, 1} * isq::position_vector[km];
CHECK((v + u).number() == vector<int>{3001, 2002, 1003}); CHECK((v + u).value() == vector<int>{3001, 2002, 1003});
} }
} }
@@ -148,12 +148,12 @@ TEST_CASE("vector quantity", "[la]")
SECTION("same unit") SECTION("same unit")
{ {
const auto u = vector<int>{3, 2, 1} * isq::position_vector[m]; const auto u = vector<int>{3, 2, 1} * isq::position_vector[m];
CHECK((v - u).number() == vector<int>{-2, 0, 2}); CHECK((v - u).value() == vector<int>{-2, 0, 2});
} }
SECTION("different units") SECTION("different units")
{ {
const auto u = vector<int>{3, 2, 1} * isq::position_vector[km]; const auto u = vector<int>{3, 2, 1} * isq::position_vector[km];
CHECK((v - u).number() == vector<int>{-2999, -1998, -997}); CHECK((v - u).value() == vector<int>{-2999, -1998, -997});
} }
} }
@@ -167,25 +167,25 @@ TEST_CASE("vector quantity", "[la]")
SECTION("derived_quantity_spec") SECTION("derived_quantity_spec")
{ {
SECTION("scalar on LHS") { CHECK((mass * v).number() == vector<int>{2, 4, 6}); } SECTION("scalar on LHS") { CHECK((mass * v).value() == vector<int>{2, 4, 6}); }
SECTION("scalar on RHS") { CHECK((v * mass).number() == vector<int>{2, 4, 6}); } SECTION("scalar on RHS") { CHECK((v * mass).value() == vector<int>{2, 4, 6}); }
} }
SECTION("quantity_cast to momentum") SECTION("quantity_cast to momentum")
{ {
SECTION("scalar on LHS") { CHECK(quantity_cast<isq::momentum>(mass * v).number() == vector<int>{2, 4, 6}); } SECTION("scalar on LHS") { CHECK(quantity_cast<isq::momentum>(mass * v).value() == vector<int>{2, 4, 6}); }
SECTION("scalar on RHS") { CHECK(quantity_cast<isq::momentum>(v * mass).number() == vector<int>{2, 4, 6}); } SECTION("scalar on RHS") { CHECK(quantity_cast<isq::momentum>(v * mass).value() == vector<int>{2, 4, 6}); }
} }
SECTION("quantity of momentum") SECTION("quantity of momentum")
{ {
SECTION("scalar on LHS") SECTION("scalar on LHS")
{ {
const quantity<isq::momentum[N * s], vector<int>> momentum = mass * v; const quantity<isq::momentum[N * s], vector<int>> momentum = mass * v;
CHECK(momentum.number() == vector<int>{2, 4, 6}); CHECK(momentum.value() == vector<int>{2, 4, 6});
} }
SECTION("scalar on RHS") SECTION("scalar on RHS")
{ {
const quantity<isq::momentum[N * s], vector<int>> momentum = v * mass; const quantity<isq::momentum[N * s], vector<int>> momentum = v * mass;
CHECK(momentum.number() == vector<int>{2, 4, 6}); CHECK(momentum.value() == vector<int>{2, 4, 6});
} }
} }
} }
@@ -196,18 +196,18 @@ TEST_CASE("vector quantity", "[la]")
SECTION("derived_quantity_spec") SECTION("derived_quantity_spec")
{ {
SECTION("scalar on LHS") { CHECK((mass * v).number() == vector<double>{0.5, 1., 1.5}); } SECTION("scalar on LHS") { CHECK((mass * v).value() == vector<double>{0.5, 1., 1.5}); }
SECTION("scalar on RHS") { CHECK((v * mass).number() == vector<double>{0.5, 1., 1.5}); } SECTION("scalar on RHS") { CHECK((v * mass).value() == vector<double>{0.5, 1., 1.5}); }
} }
SECTION("quantity_cast to momentum") SECTION("quantity_cast to momentum")
{ {
SECTION("scalar on LHS") SECTION("scalar on LHS")
{ {
CHECK(quantity_cast<isq::momentum>(mass * v).number() == vector<double>{0.5, 1., 1.5}); CHECK(quantity_cast<isq::momentum>(mass * v).value() == vector<double>{0.5, 1., 1.5});
} }
SECTION("scalar on RHS") SECTION("scalar on RHS")
{ {
CHECK(quantity_cast<isq::momentum>(v * mass).number() == vector<double>{0.5, 1., 1.5}); CHECK(quantity_cast<isq::momentum>(v * mass).value() == vector<double>{0.5, 1., 1.5});
} }
} }
SECTION("quantity of momentum") SECTION("quantity of momentum")
@@ -215,12 +215,12 @@ TEST_CASE("vector quantity", "[la]")
SECTION("scalar on LHS") SECTION("scalar on LHS")
{ {
const quantity<isq::momentum[N * s], vector<double>> momentum = mass * v; const quantity<isq::momentum[N * s], vector<double>> momentum = mass * v;
CHECK(momentum.number() == vector<double>{0.5, 1., 1.5}); CHECK(momentum.value() == vector<double>{0.5, 1., 1.5});
} }
SECTION("scalar on RHS") SECTION("scalar on RHS")
{ {
const quantity<isq::momentum[N * s], vector<double>> momentum = v * mass; const quantity<isq::momentum[N * s], vector<double>> momentum = v * mass;
CHECK(momentum.number() == vector<double>{0.5, 1., 1.5}); CHECK(momentum.value() == vector<double>{0.5, 1., 1.5});
} }
} }
} }
@@ -234,15 +234,15 @@ TEST_CASE("vector quantity", "[la]")
{ {
const auto dur = 2 * isq::duration[h]; const auto dur = 2 * isq::duration[h];
SECTION("derived_quantity_spec") { CHECK((pos / dur).number() == vector<int>{15, 10, 5}); } SECTION("derived_quantity_spec") { CHECK((pos / dur).value() == vector<int>{15, 10, 5}); }
SECTION("quantity_cast to velocity") SECTION("quantity_cast to velocity")
{ {
CHECK(quantity_cast<isq::velocity>(pos / dur).number() == vector<int>{15, 10, 5}); CHECK(quantity_cast<isq::velocity>(pos / dur).value() == vector<int>{15, 10, 5});
} }
SECTION("quantity of velocity") SECTION("quantity of velocity")
{ {
const quantity<isq::velocity[km / h], vector<int>> v = pos / dur; const quantity<isq::velocity[km / h], vector<int>> v = pos / dur;
CHECK(v.number() == vector<int>{15, 10, 5}); CHECK(v.value() == vector<int>{15, 10, 5});
} }
} }
@@ -250,15 +250,15 @@ TEST_CASE("vector quantity", "[la]")
{ {
const auto dur = 0.5 * isq::duration[h]; const auto dur = 0.5 * isq::duration[h];
SECTION("derived_quantity_spec") { CHECK((pos / dur).number() == vector<double>{60, 40, 20}); } SECTION("derived_quantity_spec") { CHECK((pos / dur).value() == vector<double>{60, 40, 20}); }
SECTION("quantity_cast to velocity") SECTION("quantity_cast to velocity")
{ {
CHECK(quantity_cast<isq::velocity>(pos / dur).number() == vector<double>{60, 40, 20}); CHECK(quantity_cast<isq::velocity>(pos / dur).value() == vector<double>{60, 40, 20});
} }
SECTION("quantity of velocity") SECTION("quantity of velocity")
{ {
const quantity<isq::velocity[km / h], vector<double>> v = pos / dur; const quantity<isq::velocity[km / h], vector<double>> v = pos / dur;
CHECK(v.number() == vector<double>{60, 40, 20}); CHECK(v.value() == vector<double>{60, 40, 20});
} }
} }
} }
@@ -294,8 +294,8 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("to scalar magnitude") SECTION("to scalar magnitude")
{ {
const vector<quantity<isq::velocity[km / h], int>> v = {2 * (km / h), 3 * (km / h), 6 * (km / h)}; const vector<quantity<isq::velocity[km / h], int>> v = {2 * (km / h), 3 * (km / h), 6 * (km / h)};
const auto speed = get_magnitude(v).number() * isq::speed[v(0).unit]; // TODO can we do better here? const auto speed = get_magnitude(v).value() * isq::speed[v(0).unit]; // TODO can we do better here?
CHECK(speed.number() == 7); CHECK(speed.value() == 7);
} }
SECTION("multiply by scalar value") SECTION("multiply by scalar value")

View File

@@ -90,12 +90,12 @@ TEST_CASE("numeric_limits functions", "[limits]")
{ {
SECTION("'epsilon' works as expected using default floating type") SECTION("'epsilon' works as expected using default floating type")
{ {
REQUIRE(epsilon<double>(isq::length[m]).number() == REQUIRE(epsilon<double>(isq::length[m]).value() ==
std::numeric_limits<decltype(1. * isq::length[m])::rep>::epsilon()); std::numeric_limits<decltype(1. * isq::length[m])::rep>::epsilon());
} }
SECTION("'epsilon' works as expected using integers") SECTION("'epsilon' works as expected using integers")
{ {
REQUIRE(epsilon<int>(isq::length[m]).number() == std::numeric_limits<decltype(1 * isq::length[m])::rep>::epsilon()); REQUIRE(epsilon<int>(isq::length[m]).value() == std::numeric_limits<decltype(1 * isq::length[m])::rep>::epsilon());
} }
} }

View File

@@ -241,16 +241,16 @@ static_assert(
// static member functions // static member functions
//////////////////////////// ////////////////////////////
static_assert(quantity_point<isq::height[m], mean_sea_level>::zero().quantity_from_origin().number() == 0); static_assert(quantity_point<isq::height[m], mean_sea_level>::zero().quantity_from_origin().value() == 0);
static_assert(quantity_point<isq::height[m], mean_sea_level>::min().quantity_from_origin().number() == static_assert(quantity_point<isq::height[m], mean_sea_level>::min().quantity_from_origin().value() ==
std::numeric_limits<double>::lowest()); std::numeric_limits<double>::lowest());
static_assert(quantity_point<isq::height[m], mean_sea_level>::max().quantity_from_origin().number() == static_assert(quantity_point<isq::height[m], mean_sea_level>::max().quantity_from_origin().value() ==
std::numeric_limits<double>::max()); std::numeric_limits<double>::max());
static_assert(quantity_point<isq::height[m], ground_level, int>::zero().quantity_from_origin().number() == 0); static_assert(quantity_point<isq::height[m], ground_level, int>::zero().quantity_from_origin().value() == 0);
static_assert(quantity_point<isq::height[m], ground_level, int>::min().quantity_from_origin().number() == static_assert(quantity_point<isq::height[m], ground_level, int>::min().quantity_from_origin().value() ==
std::numeric_limits<int>::lowest()); std::numeric_limits<int>::lowest());
static_assert(quantity_point<isq::height[m], ground_level, int>::max().quantity_from_origin().number() == static_assert(quantity_point<isq::height[m], ground_level, int>::max().quantity_from_origin().value() ==
std::numeric_limits<int>::max()); std::numeric_limits<int>::max());
@@ -576,15 +576,15 @@ static_assert(is_of_type<(ground_level + isq::height(short(42) * m)).point_for(m
// converting to a different unit // converting to a different unit
/////////////////////////////////// ///////////////////////////////////
static_assert((mean_sea_level + 2. * km).in(km).quantity_from_origin().number() == 2.); static_assert((mean_sea_level + 2. * km).in(km).quantity_from_origin().value() == 2.);
static_assert((mean_sea_level + 2. * km).in(m).quantity_from_origin().number() == 2000.); static_assert((mean_sea_level + 2. * km).in(m).quantity_from_origin().value() == 2000.);
static_assert((mean_sea_level + 2000. * m).in(km).quantity_from_origin().number() == 2.); static_assert((mean_sea_level + 2000. * m).in(km).quantity_from_origin().value() == 2.);
static_assert((ground_level + 2. * km).in(km).quantity_from_origin().number() == 2.); static_assert((ground_level + 2. * km).in(km).quantity_from_origin().value() == 2.);
static_assert((ground_level + 2. * km).in(m).quantity_from_origin().number() == 2000.); static_assert((ground_level + 2. * km).in(m).quantity_from_origin().value() == 2000.);
static_assert((ground_level + 2000. * m).in(km).quantity_from_origin().number() == 2.); static_assert((ground_level + 2000. * m).in(km).quantity_from_origin().value() == 2.);
static_assert((tower_peak + 2. * km).in(km).quantity_from_origin().number() == 2.); static_assert((tower_peak + 2. * km).in(km).quantity_from_origin().value() == 2.);
static_assert((tower_peak + 2. * km).in(m).quantity_from_origin().number() == 2000.); static_assert((tower_peak + 2. * km).in(m).quantity_from_origin().value() == 2000.);
static_assert((tower_peak + 2000. * m).in(km).quantity_from_origin().number() == 2.); static_assert((tower_peak + 2000. * m).in(km).quantity_from_origin().value() == 2.);
#if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, auto, typename> typename QP> template<template<auto, auto, typename> typename QP>
@@ -657,14 +657,14 @@ static_assert([](auto v) {
//////////////////////// ////////////////////////
// same type // same type
static_assert((mean_sea_level + 1 * m += 1 * m).quantity_from_origin().number() == 2); static_assert((mean_sea_level + 1 * m += 1 * m).quantity_from_origin().value() == 2);
static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_from_origin().number() == 1); static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_from_origin().value() == 1);
// different types // different types
static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_from_origin().number() == 5.5); static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_from_origin().value() == 5.5);
static_assert((mean_sea_level + 123 * m += 1 * km).quantity_from_origin().number() == 1123); static_assert((mean_sea_level + 123 * m += 1 * km).quantity_from_origin().value() == 1123);
static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_from_origin().number() == 2.5); static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_from_origin().value() == 2.5);
static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_from_origin().number() == 123); static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_from_origin().value() == 123);
template<template<auto, auto, typename> typename QP> template<template<auto, auto, typename> typename QP>
@@ -930,24 +930,24 @@ static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + other_ground_level), qu
// check for integral types promotion // check for integral types promotion
static_assert( static_assert(
is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) + std::uint8_t(0) * m).quantity_from_origin().number()), is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) + std::uint8_t(0) * m).quantity_from_origin().value()),
int&&>); int&&>);
static_assert( static_assert(
is_same_v<decltype((std::uint8_t(0) * m + (mean_sea_level + std::uint8_t(0) * m)).quantity_from_origin().number()), is_same_v<decltype((std::uint8_t(0) * m + (mean_sea_level + std::uint8_t(0) * m)).quantity_from_origin().value()),
int&&>); int&&>);
static_assert( static_assert(
is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(0) * m).quantity_from_origin().number()), is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(0) * m).quantity_from_origin().value()),
int&&>); int&&>);
static_assert( static_assert(
is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(0) * m)).number()), is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(0) * m)).value()),
int&&>); int&&>);
static_assert(((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m).quantity_from_origin().number() == static_assert(((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m).quantity_from_origin().value() ==
std::uint8_t(128) + std::uint8_t(128)); std::uint8_t(128) + std::uint8_t(128));
static_assert((std::uint8_t(128) * m + (mean_sea_level + std::uint8_t(128) * m)).quantity_from_origin().number() == static_assert((std::uint8_t(128) * m + (mean_sea_level + std::uint8_t(128) * m)).quantity_from_origin().value() ==
std::uint8_t(128) + std::uint8_t(128)); std::uint8_t(128) + std::uint8_t(128));
static_assert(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(1) * m).quantity_from_origin().number() == static_assert(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(1) * m).quantity_from_origin().value() ==
std::uint8_t(0) - std::uint8_t(1)); std::uint8_t(0) - std::uint8_t(1));
static_assert(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(1) * m)).number() == static_assert(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(1) * m)).value() ==
std::uint8_t(0) - std::uint8_t(1)); std::uint8_t(0) - std::uint8_t(1));
// different representation types // different representation types
@@ -1002,39 +1002,39 @@ static_assert(is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + 1. * m),
static_assert(is_of_type<(mean_sea_level + 1. * km) - (mean_sea_level + 1. * m), quantity<si::metre, double>>); static_assert(is_of_type<(mean_sea_level + 1. * km) - (mean_sea_level + 1. * m), quantity<si::metre, double>>);
static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from_origin().number() == 2); static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from_origin().value() == 2);
static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 2); static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from_origin().value() == 2);
static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from_origin().number() == 1001); static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from_origin().value() == 1001);
static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from_origin().number() == 1001); static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from_origin().value() == 1001);
static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from_origin().number() == 1001); static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from_origin().value() == 1001);
static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 1001); static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from_origin().value() == 1001);
static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from_origin().number() == 1); static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from_origin().value() == 1);
static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from_origin().number() == 999); static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from_origin().value() == 999);
static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from_origin().number() == 2.5); static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from_origin().value() == 2.5);
static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 2.5); static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from_origin().value() == 2.5);
static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from_origin().number() == 1001.5); static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from_origin().value() == 1001.5);
static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from_origin().number() == 1001.5); static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from_origin().value() == 1001.5);
static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from_origin().number() == 1501); static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from_origin().value() == 1501);
static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 1501); static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from_origin().value() == 1501);
static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from_origin().number() == 1.5); static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from_origin().value() == 1.5);
static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from_origin().number() == 1499); static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from_origin().value() == 1499);
static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from_origin().number() == 2.5); static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from_origin().value() == 2.5);
static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from_origin().number() == 2.5); static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from_origin().value() == 2.5);
static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from_origin().number() == 1501); static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from_origin().value() == 1501);
static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from_origin().number() == 1501); static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from_origin().value() == 1501);
static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from_origin().number() == 1001.5); static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from_origin().value() == 1001.5);
static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from_origin().number() == 1001.5); static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from_origin().value() == 1001.5);
static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from_origin().number() == 0.5); static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from_origin().value() == 0.5);
static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from_origin().number() == 998.5); static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from_origin().value() == 998.5);
static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1 * m)).number() == 1); static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1 * m)).value() == 1);
static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1 * m)).number() == 999); static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1 * m)).value() == 999);
static_assert(((mean_sea_level + 2.5 * m) - (mean_sea_level + 1 * m)).number() == 1.5); static_assert(((mean_sea_level + 2.5 * m) - (mean_sea_level + 1 * m)).value() == 1.5);
static_assert(((mean_sea_level + 1.5 * km) - (mean_sea_level + 1 * m)).number() == 1499); static_assert(((mean_sea_level + 1.5 * km) - (mean_sea_level + 1 * m)).value() == 1499);
static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1.5 * m)).number() == 0.5); static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1.5 * m)).value() == 0.5);
static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1.5 * m)).number() == 998.5); static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1.5 * m)).value() == 998.5);
static_assert((mean_sea_level + 42 * m) - (ground_level + 42 * m) == -42 * m); static_assert((mean_sea_level + 42 * m) - (ground_level + 42 * m) == -42 * m);
static_assert((ground_level + 42 * m) - (mean_sea_level + 42 * m) == 42 * m); static_assert((ground_level + 42 * m) - (mean_sea_level + 42 * m) == 42 * m);

View File

@@ -112,12 +112,12 @@ static_assert(is_same_v<quantity<isq::length[m], int>::rep, int>);
// static member functions // static member functions
//////////////////////////// ////////////////////////////
static_assert(quantity<isq::length[m], int>::zero().number() == 0); static_assert(quantity<isq::length[m], int>::zero().value() == 0);
static_assert(quantity<isq::length[m], int>::min().number() == std::numeric_limits<int>::lowest()); static_assert(quantity<isq::length[m], int>::min().value() == std::numeric_limits<int>::lowest());
static_assert(quantity<isq::length[m], int>::max().number() == std::numeric_limits<int>::max()); static_assert(quantity<isq::length[m], int>::max().value() == std::numeric_limits<int>::max());
static_assert(quantity<isq::length[m], double>::zero().number() == 0.0); static_assert(quantity<isq::length[m], double>::zero().value() == 0.0);
static_assert(quantity<isq::length[m], double>::min().number() == std::numeric_limits<double>::lowest()); static_assert(quantity<isq::length[m], double>::min().value() == std::numeric_limits<double>::lowest());
static_assert(quantity<isq::length[m], double>::max().number() == std::numeric_limits<double>::max()); static_assert(quantity<isq::length[m], double>::max().value() == std::numeric_limits<double>::max());
////////////////////////////// //////////////////////////////
@@ -188,21 +188,21 @@ static_assert(std::convertible_to<quantity<isq::length[m], int>, quantity<isq::l
// obtaining a number // obtaining a number
/////////////////////// ///////////////////////
static_assert(quantity<isq::length[m], int>(123 * m).number() == 123); static_assert(quantity<isq::length[m], int>(123 * m).value() == 123);
static_assert(quantity<isq::length[m], int>(2 * km).number() == 2000); static_assert(quantity<isq::length[m], int>(2 * km).value() == 2000);
static_assert(quantity<isq::length[km], int>(2 * km).number() == 2); static_assert(quantity<isq::length[km], int>(2 * km).value() == 2);
static_assert(quantity<isq::length[km]>(1500 * m).number() == 1.5); static_assert(quantity<isq::length[km]>(1500 * m).value() == 1.5);
/////////////////////////////////// ///////////////////////////////////
// converting to a different unit // converting to a different unit
/////////////////////////////////// ///////////////////////////////////
static_assert(quantity<isq::length[km]>(2. * km).in(km).number() == 2.); static_assert(quantity<isq::length[km]>(2. * km).in(km).value() == 2.);
static_assert(quantity<isq::length[km]>(2. * km).in(m).number() == 2000.); static_assert(quantity<isq::length[km]>(2. * km).in(m).value() == 2000.);
static_assert(quantity<isq::length[m]>(2000. * m).in(km).number() == 2.); static_assert(quantity<isq::length[m]>(2000. * m).in(km).value() == 2.);
static_assert(quantity<isq::length[km], int>(2 * km).in(km).number() == 2); static_assert(quantity<isq::length[km], int>(2 * km).in(km).value() == 2);
static_assert(quantity<isq::length[km], int>(2 * km).in(m).number() == 2000); static_assert(quantity<isq::length[km], int>(2 * km).in(m).value() == 2000);
#if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
@@ -213,17 +213,17 @@ concept invalid_unit_conversion = requires {
static_assert(invalid_unit_conversion<quantity>); static_assert(invalid_unit_conversion<quantity>);
#endif #endif
static_assert(quantity<isq::length[km]>(2. * km).number_in(km) == 2.); static_assert(quantity<isq::length[km]>(2. * km).value_in(km) == 2.);
static_assert(quantity<isq::length[km]>(2. * km).number_in(m) == 2000.); static_assert(quantity<isq::length[km]>(2. * km).value_in(m) == 2000.);
static_assert(quantity<isq::length[m]>(2000. * m).number_in(km) == 2.); static_assert(quantity<isq::length[m]>(2000. * m).value_in(km) == 2.);
static_assert(quantity<isq::length[km], int>(2 * km).number_in(km) == 2); static_assert(quantity<isq::length[km], int>(2 * km).value_in(km) == 2);
static_assert(quantity<isq::length[km], int>(2 * km).number_in(m) == 2000); static_assert(quantity<isq::length[km], int>(2 * km).value_in(m) == 2000);
#if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
concept invalid_getter_with_unit_conversion = requires { concept invalid_getter_with_unit_conversion = requires {
requires !requires { Q<isq::length[m], int>(2000 * m).number_in(km); }; // truncating conversion requires !requires { Q<isq::length[m], int>(2000 * m).value_in(km); }; // truncating conversion
requires !requires { Q<isq::length[m], int>(2 * m).number_in(s); }; // invalid unit requires !requires { Q<isq::length[m], int>(2 * m).value_in(s); }; // invalid unit
}; };
static_assert(invalid_getter_with_unit_conversion<quantity>); static_assert(invalid_getter_with_unit_conversion<quantity>);
#endif #endif
@@ -302,28 +302,28 @@ static_assert([] {
auto l1(1 * m), l2(2 * m); auto l1(1 * m), l2(2 * m);
return l2 = l1; return l2 = l1;
}() }()
.number() == 1); .value() == 1);
static_assert([] { static_assert([] {
const auto l1(1 * m); const auto l1(1 * m);
auto l2(2 * m); auto l2(2 * m);
return l2 = l1; return l2 = l1;
}() }()
.number() == 1); .value() == 1);
static_assert([]() { static_assert([]() {
auto l1(1 * m), l2(2 * m); auto l1(1 * m), l2(2 * m);
return l2 = std::move(l1); return l2 = std::move(l1);
}() }()
.number() == 1); .value() == 1);
//////////////////// ////////////////////
// unary operators // unary operators
//////////////////// ////////////////////
static_assert((+123 * m).number() == 123); static_assert((+123 * m).value() == 123);
static_assert((-123 * m).number() == -123); static_assert((-123 * m).value() == -123);
static_assert((+(-123 * m)).number() == -123); static_assert((+(-123 * m)).value() == -123);
static_assert((-(-123 * m)).number() == 123); static_assert((-(-123 * m)).value() == 123);
static_assert([](auto v) { static_assert([](auto v) {
auto vv = v++; auto vv = v++;
@@ -342,7 +342,7 @@ static_assert([](auto v) {
return std::pair(v, vv); return std::pair(v, vv);
}(123 * m) == std::pair(122 * m, 122 * m)); }(123 * m) == std::pair(122 * m, 122 * m));
static_assert(is_same_v<decltype((+(short{0} * m)).number()), int&&>); static_assert(is_same_v<decltype((+(short{0} * m)).value()), int&&>);
//////////////////////// ////////////////////////
@@ -350,29 +350,29 @@ static_assert(is_same_v<decltype((+(short{0} * m)).number()), int&&>);
//////////////////////// ////////////////////////
// same type // same type
static_assert((1 * m += 1 * m).number() == 2); static_assert((1 * m += 1 * m).value() == 2);
static_assert((2 * m -= 1 * m).number() == 1); static_assert((2 * m -= 1 * m).value() == 1);
static_assert((1 * m *= 2).number() == 2); static_assert((1 * m *= 2).value() == 2);
static_assert((2 * m /= 2).number() == 1); static_assert((2 * m /= 2).value() == 1);
static_assert((1 * m *= 2 * one).number() == 2); static_assert((1 * m *= 2 * one).value() == 2);
static_assert((2 * m /= 2 * one).number() == 1); static_assert((2 * m /= 2 * one).value() == 1);
static_assert((7 * m %= 2 * m).number() == 1); static_assert((7 * m %= 2 * m).value() == 1);
// different types // different types
static_assert((2.5 * m += 3 * m).number() == 5.5); static_assert((2.5 * m += 3 * m).value() == 5.5);
static_assert((123 * m += 1 * km).number() == 1123); static_assert((123 * m += 1 * km).value() == 1123);
static_assert((5.5 * m -= 3 * m).number() == 2.5); static_assert((5.5 * m -= 3 * m).value() == 2.5);
static_assert((1123 * m -= 1 * km).number() == 123); static_assert((1123 * m -= 1 * km).value() == 123);
static_assert((2.5 * m *= 3).number() == 7.5); static_assert((2.5 * m *= 3).value() == 7.5);
static_assert((7.5 * m /= 3).number() == 2.5); static_assert((7.5 * m /= 3).value() == 2.5);
static_assert((2.5 * m *= 3 * one).number() == 7.5); static_assert((2.5 * m *= 3 * one).value() == 7.5);
static_assert((7.5 * m /= 3 * one).number() == 2.5); static_assert((7.5 * m /= 3 * one).value() == 2.5);
static_assert((3500 * m %= 1 * km).number() == 500); static_assert((3500 * m %= 1 * km).value() == 500);
// static_assert((std::uint8_t(255) * m %= 256 * m).number() != [] { std::uint8_t ui(255); return ui %= 256; }()); // // static_assert((std::uint8_t(255) * m %= 256 * m).value() != [] { std::uint8_t ui(255); return ui %= 256; }()); //
// UB // UB
// TODO: Fix // TODO: Fix
static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] { static_assert((std::uint8_t(255) * m %= 257 * m).value() != [] {
std::uint8_t ui(255); std::uint8_t ui(255);
return ui %= 257; return ui %= 257;
}()); }());
@@ -382,10 +382,10 @@ static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] {
#ifndef MP_UNITS_COMP_MSVC #ifndef MP_UNITS_COMP_MSVC
// next two lines trigger conversions warnings // next two lines trigger conversions warnings
// (warning disabled in CMake for this file) // (warning disabled in CMake for this file)
static_assert((22 * m *= 33.33).number() == 733); static_assert((22 * m *= 33.33).value() == 733);
static_assert((22 * m /= 3.33).number() == 6); static_assert((22 * m /= 3.33).value() == 6);
static_assert((22 * m *= 33.33 * one).number() == 733); static_assert((22 * m *= 33.33 * one).value() == 733);
static_assert((22 * m /= 3.33 * one).number() == 6); static_assert((22 * m /= 3.33 * one).value() == 6);
#endif #endif
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
@@ -510,12 +510,12 @@ static_assert(is_of_type<1 * km % (300 * m), quantity<si::metre, int>>);
static_assert(is_of_type<4 * one % (2 * one), quantity<one, int>>); static_assert(is_of_type<4 * one % (2 * one), quantity<one, int>>);
// check for integral types promotion // check for integral types promotion
static_assert(is_same_v<decltype((std::uint8_t(0) * m + std::uint8_t(0) * m).number()), int&&>); static_assert(is_same_v<decltype((std::uint8_t(0) * m + std::uint8_t(0) * m).value()), int&&>);
static_assert(is_same_v<decltype((std::uint8_t(0) * m - std::uint8_t(0) * m).number()), int&&>); static_assert(is_same_v<decltype((std::uint8_t(0) * m - std::uint8_t(0) * m).value()), int&&>);
static_assert((std::uint8_t(128) * m + std::uint8_t(128) * m).number() == std::uint8_t(128) + std::uint8_t(128)); static_assert((std::uint8_t(128) * m + std::uint8_t(128) * m).value() == std::uint8_t(128) + std::uint8_t(128));
static_assert((std::uint8_t(0) * m - std::uint8_t(1) * m).number() == std::uint8_t(0) - std::uint8_t(1)); static_assert((std::uint8_t(0) * m - std::uint8_t(1) * m).value() == std::uint8_t(0) - std::uint8_t(1));
static_assert(is_same_v<decltype(((std::uint8_t(0) * m) % (std::uint8_t(0) * m)).number()), static_assert(is_same_v<decltype(((std::uint8_t(0) * m) % (std::uint8_t(0) * m)).value()),
decltype(std::uint8_t(0) % std::uint8_t(0))&&>); decltype(std::uint8_t(0) % std::uint8_t(0))&&>);
// different representation types // different representation types
@@ -589,67 +589,67 @@ static_assert(is_of_type<1 * m / (1 * s), quantity<derived_unit<struct si::metre
static_assert(is_of_type<1 * m / (1 * min), quantity<derived_unit<struct si::metre, per<struct si::minute>>{}, int>>); static_assert(is_of_type<1 * m / (1 * min), quantity<derived_unit<struct si::metre, per<struct si::minute>>{}, int>>);
static_assert(is_of_type<1 * min / (1 * m), quantity<derived_unit<struct si::minute, per<struct si::metre>>{}, int>>); static_assert(is_of_type<1 * min / (1 * m), quantity<derived_unit<struct si::minute, per<struct si::metre>>{}, int>>);
static_assert((1 * m + 1 * m).number() == 2); static_assert((1 * m + 1 * m).value() == 2);
static_assert((1 * m + 1 * km).number() == 1001); static_assert((1 * m + 1 * km).value() == 1001);
static_assert((1 * km + 1 * m).number() == 1001); static_assert((1 * km + 1 * m).value() == 1001);
static_assert((2 * m - 1 * m).number() == 1); static_assert((2 * m - 1 * m).value() == 1);
static_assert((1 * km - 1 * m).number() == 999); static_assert((1 * km - 1 * m).value() == 999);
static_assert((2 * m * 2).number() == 4); static_assert((2 * m * 2).value() == 4);
static_assert((2 * m * (2 * one)).number() == 4); static_assert((2 * m * (2 * one)).value() == 4);
static_assert((2 * m * (2 * percent)).number() == 4); static_assert((2 * m * (2 * percent)).value() == 4);
static_assert((3 * 3 * m).number() == 9); static_assert((3 * 3 * m).value() == 9);
static_assert(((3 * one) * (3 * m)).number() == 9); static_assert(((3 * one) * (3 * m)).value() == 9);
static_assert(((3 * percent) * (3 * m)).number() == 9); static_assert(((3 * percent) * (3 * m)).value() == 9);
static_assert((4 * m / 2).number() == 2); static_assert((4 * m / 2).value() == 2);
static_assert((4 * m / (2 * one)).number() == 2); static_assert((4 * m / (2 * one)).value() == 2);
static_assert((4 * m / (2 * percent)).number() == 2); static_assert((4 * m / (2 * percent)).value() == 2);
static_assert((4 * km / (2 * m)).number() == 2); static_assert((4 * km / (2 * m)).value() == 2);
static_assert((4000 * m / (2 * m)).number() == 2000); static_assert((4000 * m / (2 * m)).value() == 2000);
static_assert((1.5 * m + 1 * m).number() == 2.5); static_assert((1.5 * m + 1 * m).value() == 2.5);
static_assert((1.5 * m + 1 * km).number() == 1001.5); static_assert((1.5 * m + 1 * km).value() == 1001.5);
static_assert((1.5 * km + 1 * m).number() == 1501); static_assert((1.5 * km + 1 * m).value() == 1501);
static_assert((2.5 * m - 1 * m).number() == 1.5); static_assert((2.5 * m - 1 * m).value() == 1.5);
static_assert((1.5 * km - 1 * m).number() == 1499); static_assert((1.5 * km - 1 * m).value() == 1499);
static_assert((2.5 * m * 2).number() == 5); static_assert((2.5 * m * 2).value() == 5);
static_assert((2.5 * m * (2 * one)).number() == 5); static_assert((2.5 * m * (2 * one)).value() == 5);
static_assert((2.5 * m * (2 * percent)).number() == 5); static_assert((2.5 * m * (2 * percent)).value() == 5);
static_assert((2.5L * (2 * m)).number() == 5); static_assert((2.5L * (2 * m)).value() == 5);
static_assert((2.5L * one * (2 * m)).number() == 5); static_assert((2.5L * one * (2 * m)).value() == 5);
static_assert((2.5L * percent * (2 * m)).number() == 5); static_assert((2.5L * percent * (2 * m)).value() == 5);
static_assert((5. * m / 2).number() == 2.5); static_assert((5. * m / 2).value() == 2.5);
static_assert((5. * m / (2 * one)).number() == 2.5); static_assert((5. * m / (2 * one)).value() == 2.5);
static_assert((5. * m / (2 * percent)).number() == 2.5); static_assert((5. * m / (2 * percent)).value() == 2.5);
static_assert((5. * km / (2 * m)).number() == 2.5); static_assert((5. * km / (2 * m)).value() == 2.5);
static_assert((5000. * m / (2 * m)).number() == 2500); static_assert((5000. * m / (2 * m)).value() == 2500);
static_assert((1 * m + 1.5 * m).number() == 2.5); static_assert((1 * m + 1.5 * m).value() == 2.5);
static_assert((1 * m + 1.5 * km).number() == 1501); static_assert((1 * m + 1.5 * km).value() == 1501);
static_assert((1 * km + 1.5 * m).number() == 1001.5); static_assert((1 * km + 1.5 * m).value() == 1001.5);
static_assert((2 * m - 1.5 * m).number() == 0.5); static_assert((2 * m - 1.5 * m).value() == 0.5);
static_assert((1 * km - 1.5 * m).number() == 998.5); static_assert((1 * km - 1.5 * m).value() == 998.5);
static_assert((2 * m * 2.5L).number() == 5); static_assert((2 * m * 2.5L).value() == 5);
static_assert((2 * m * (2.5L * one)).number() == 5); static_assert((2 * m * (2.5L * one)).value() == 5);
static_assert((2 * m * (2.5L * percent)).number() == 5); static_assert((2 * m * (2.5L * percent)).value() == 5);
static_assert((2 * 2.5 * m).number() == 5); static_assert((2 * 2.5 * m).value() == 5);
static_assert((2 * one * (2.5 * m)).number() == 5); static_assert((2 * one * (2.5 * m)).value() == 5);
static_assert((2 * percent * (2.5 * m)).number() == 5); static_assert((2 * percent * (2.5 * m)).value() == 5);
static_assert((5 * m / 2.5L).number() == 2); static_assert((5 * m / 2.5L).value() == 2);
static_assert((5 * m / (2.5L * one)).number() == 2); static_assert((5 * m / (2.5L * one)).value() == 2);
static_assert((5 * m / (2.5L * percent)).number() == 2); static_assert((5 * m / (2.5L * percent)).value() == 2);
static_assert((5 * km / (2.5 * m)).number() == 2); static_assert((5 * km / (2.5 * m)).value() == 2);
static_assert((5000 * m / (2.5 * m)).number() == 2000); static_assert((5000 * m / (2.5 * m)).value() == 2000);
static_assert((7 * m % (2 * m)).number() == 1); static_assert((7 * m % (2 * m)).value() == 1);
static_assert((7 * km % (2000 * m)).number() == 1000); static_assert((7 * km % (2000 * m)).value() == 1000);
static_assert((1300 * m % (1 * km)).number() == 300); static_assert((1300 * m % (1 * km)).value() == 300);
static_assert((7 * one % (2 * one)).number() == 1); static_assert((7 * one % (2 * one)).value() == 1);
static_assert((10 * m2 * (10 * m2)) / (50 * m2) == 2 * m2); static_assert((10 * m2 * (10 * m2)) / (50 * m2) == 2 * m2);
static_assert((10 * km / (5 * m)).number() == 2); static_assert((10 * km / (5 * m)).value() == 2);
static_assert((10 * km / (5 * m)).in(one).number() == 2000); static_assert((10 * km / (5 * m)).in(one).value() == 2000);
static_assert((10 * s * (2 * kHz)).number() == 20); static_assert((10 * s * (2 * kHz)).value() == 20);
// commutativity and associativity // commutativity and associativity
static_assert(10 * isq::length[si::metre] / (2 * isq::time[s]) + 5 * isq::speed[m / s] == 10 * isq::speed[m / s]); static_assert(10 * isq::length[si::metre] / (2 * isq::time[s]) + 5 * isq::speed[m / s] == 10 * isq::speed[m / s]);
@@ -733,12 +733,12 @@ static_assert(is_same_v<decltype(0.0 * one - 0 * one), decltype(0.0 * one)>);
static_assert(1 * one - 30 * percent == (100 - 30) * percent); static_assert(1 * one - 30 * percent == (100 - 30) * percent);
static_assert(1 * one + 30 * percent == (100 + 30) * percent); static_assert(1 * one + 30 * percent == (100 + 30) * percent);
static_assert(is_same_v<decltype((std::uint8_t(0) * one + std::uint8_t(0) * one).number()), int&&>); static_assert(is_same_v<decltype((std::uint8_t(0) * one + std::uint8_t(0) * one).value()), int&&>);
static_assert(is_same_v<decltype((std::uint8_t(0) * one - std::uint8_t(0) * one).number()), int&&>); static_assert(is_same_v<decltype((std::uint8_t(0) * one - std::uint8_t(0) * one).value()), int&&>);
static_assert((std::uint8_t(128) * one + std::uint8_t(128) * one).number() == std::uint8_t(128) + std::uint8_t(128)); static_assert((std::uint8_t(128) * one + std::uint8_t(128) * one).value() == std::uint8_t(128) + std::uint8_t(128));
static_assert((std::uint8_t(0) * one - std::uint8_t(1) * one).number() == std::uint8_t(0) - std::uint8_t(1)); static_assert((std::uint8_t(0) * one - std::uint8_t(1) * one).value() == std::uint8_t(0) - std::uint8_t(1));
static_assert(is_same_v<decltype((std::uint8_t(0) * one % (std::uint8_t(0) * one)).number()), static_assert(is_same_v<decltype((std::uint8_t(0) * one % (std::uint8_t(0) * one)).value()),
decltype(std::uint8_t(0) % std::uint8_t(0))&&>); decltype(std::uint8_t(0) % std::uint8_t(0))&&>);
static_assert(2 * one * (1 * m) == 2 * m); static_assert(2 * one * (1 * m) == 2 * m);
@@ -872,20 +872,20 @@ static_assert(!(123 * km >= 321'000 * m));
static_assert(is_of_type<10 * km / (5 * km), quantity<one, int>>); static_assert(is_of_type<10 * km / (5 * km), quantity<one, int>>);
static_assert((50. * m / (100. * m)).in(percent).number() == 50); static_assert((50. * m / (100. * m)).in(percent).value() == 50);
static_assert(50. * m / (100. * m) == 50 * percent); static_assert(50. * m / (100. * m) == 50 * percent);
static_assert((50. * percent).in(one).number() == 0.5); static_assert((50. * percent).in(one).value() == 0.5);
////////////////// //////////////////
// value_cast // value_cast
////////////////// //////////////////
static_assert(value_cast<m>(2 * km).number() == 2000); static_assert(value_cast<m>(2 * km).value() == 2000);
static_assert(value_cast<km>(2000 * m).number() == 2); static_assert(value_cast<km>(2000 * m).value() == 2);
static_assert(value_cast<int>(1.23 * m).number() == 1); static_assert(value_cast<int>(1.23 * m).value() == 1);
static_assert(value_cast<km / h>(2000.0 * m / (3600.0 * s)).number() == 2); static_assert(value_cast<km / h>(2000.0 * m / (3600.0 * s)).value() == 2);
////////////////// //////////////////
// quantity_cast // quantity_cast