mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
refactor: 💥 tag types should not expose their members
This commit is contained in:
@ -63,7 +63,7 @@ inline constexpr auto JPY = japanese_jen;
|
||||
static_assert(!std::equality_comparable_with<quantity<euro, int>, quantity<us_dollar, int>>);
|
||||
|
||||
|
||||
#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
|
||||
#if 0 || !MP_UNITS_API_STRING_VIEW_RET // NOLINT(readability-avoid-unconditional-preprocessor-if)
|
||||
|
||||
// if you have only a few currencies to handle
|
||||
template<Unit auto From, Unit auto To>
|
||||
@ -77,8 +77,6 @@ template<Unit auto From, Unit auto To>
|
||||
|
||||
#else
|
||||
|
||||
[[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.portable().c_str(); }
|
||||
|
||||
template<Unit auto From, Unit auto To>
|
||||
[[nodiscard]] double exchange_rate(std::chrono::sys_seconds timestamp)
|
||||
{
|
||||
@ -88,7 +86,7 @@ template<Unit auto From, Unit auto To>
|
||||
// ...
|
||||
};
|
||||
|
||||
return rates.at(std::make_pair(to_string_view(From), to_string_view(To)));
|
||||
return rates.at(std::make_pair(unit_symbol(From), unit_symbol(To)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -51,10 +51,10 @@ template<typename... Nums, typename... Dens>
|
||||
template<AssociatedUnit U>
|
||||
[[nodiscard]] consteval auto all_are_kinds(U)
|
||||
{
|
||||
if constexpr (requires { U::quantity_spec; })
|
||||
return QuantityKindSpec<std::remove_const_t<decltype(U::quantity_spec)>>;
|
||||
else if constexpr (requires { U::reference_unit; })
|
||||
return all_are_kinds(U::reference_unit);
|
||||
if constexpr (requires { U::_quantity_spec_; })
|
||||
return QuantityKindSpec<std::remove_const_t<decltype(U::_quantity_spec_)>>;
|
||||
else if constexpr (requires { U::_reference_unit_; })
|
||||
return all_are_kinds(U::_reference_unit_);
|
||||
else if constexpr (requires { typename U::_num_; }) {
|
||||
return all_are_kinds(typename U::_num_{}, typename U::_den_{});
|
||||
}
|
||||
@ -75,10 +75,10 @@ template<typename... Us>
|
||||
template<AssociatedUnit U>
|
||||
[[nodiscard]] consteval auto get_associated_quantity_impl(U u)
|
||||
{
|
||||
if constexpr (requires { U::quantity_spec; })
|
||||
return remove_kind(U::quantity_spec);
|
||||
else if constexpr (requires { U::reference_unit; })
|
||||
return get_associated_quantity_impl(U::reference_unit);
|
||||
if constexpr (requires { U::_quantity_spec_; })
|
||||
return remove_kind(U::_quantity_spec_);
|
||||
else if constexpr (requires { U::_reference_unit_; })
|
||||
return get_associated_quantity_impl(U::_reference_unit_);
|
||||
else if constexpr (requires { typename U::_num_; }) {
|
||||
return expr_map<to_quantity_spec, derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(u);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ struct dimension_interface {
|
||||
*/
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol>
|
||||
struct base_dimension : detail::dimension_interface {
|
||||
static constexpr auto symbol = Symbol; ///< Unique base dimension identifier
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique base dimension identifier
|
||||
};
|
||||
|
||||
/**
|
||||
@ -229,10 +229,10 @@ MP_UNITS_EXPORT_END
|
||||
namespace detail {
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, Dimension D>
|
||||
requires requires { D::symbol; }
|
||||
requires requires { D::_symbol_; }
|
||||
constexpr Out dimension_symbol_impl(Out out, D, const dimension_symbol_formatting& fmt, bool negative_power)
|
||||
{
|
||||
return copy_symbol<CharT>(D::symbol, fmt.encoding, negative_power, out);
|
||||
return copy_symbol<CharT>(D::_symbol_, fmt.encoding, negative_power, out);
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, typename F, int Num, int... Den>
|
||||
|
@ -52,14 +52,14 @@ template<PointOrigin PO>
|
||||
}
|
||||
|
||||
struct point_origin_interface {
|
||||
template<PointOrigin PO, typename FwdQ, QuantityOf<PO::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
template<PointOrigin PO, typename FwdQ, QuantityOf<PO::_quantity_spec_> Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
|
||||
operator+(PO, FwdQ&& q)
|
||||
{
|
||||
return quantity_point{std::forward<FwdQ>(q), PO{}};
|
||||
}
|
||||
|
||||
template<Quantity FwdQ, PointOrigin PO, QuantityOf<PO::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
template<Quantity FwdQ, PointOrigin PO, QuantityOf<PO::_quantity_spec_> Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
|
||||
operator+(FwdQ&& q, PO po)
|
||||
{
|
||||
@ -67,7 +67,7 @@ struct point_origin_interface {
|
||||
}
|
||||
|
||||
template<PointOrigin PO, Quantity Q>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::_quantity_spec_>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator-(PO po, const Q& q)
|
||||
requires requires { -q; }
|
||||
{
|
||||
@ -75,17 +75,17 @@ struct point_origin_interface {
|
||||
}
|
||||
|
||||
template<PointOrigin PO1, detail::SameAbsolutePointOriginAs<PO1{}> PO2>
|
||||
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::quantity_spec)>, PO2::quantity_spec> &&
|
||||
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::_quantity_spec_)>, PO2::_quantity_spec_> &&
|
||||
(is_derived_from_specialization_of_v<PO1, relative_point_origin> ||
|
||||
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(PO1 po1, PO2 po2)
|
||||
{
|
||||
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin>) {
|
||||
return po1 - po2.quantity_point;
|
||||
return po1 - po2._quantity_point_;
|
||||
} else if constexpr (is_derived_from_specialization_of_v<PO2, absolute_point_origin>) {
|
||||
return po1.quantity_point - po2;
|
||||
return po1._quantity_point_ - po2;
|
||||
} else {
|
||||
return po1.quantity_point - po2.quantity_point;
|
||||
return po1._quantity_point_ - po2._quantity_point_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,14 +95,14 @@ struct point_origin_interface {
|
||||
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin> &&
|
||||
is_derived_from_specialization_of_v<PO2, absolute_point_origin>)
|
||||
return is_same_v<PO1, PO2> || (detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) &&
|
||||
interconvertible(po1.quantity_spec, po2.quantity_spec));
|
||||
interconvertible(po1._quantity_spec_, po2._quantity_spec_));
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin> &&
|
||||
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||
return PO1::quantity_point == PO2::quantity_point;
|
||||
return PO1::_quantity_point_ == PO2::_quantity_point_;
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin>)
|
||||
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO1::quantity_point.quantity_from_zero());
|
||||
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO1::_quantity_point_.quantity_from_zero());
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO2::quantity_point.quantity_from_zero());
|
||||
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO2::_quantity_point_.quantity_from_zero());
|
||||
}
|
||||
};
|
||||
|
||||
@ -110,20 +110,20 @@ struct point_origin_interface {
|
||||
|
||||
MP_UNITS_EXPORT template<QuantitySpec auto QS>
|
||||
struct absolute_point_origin : detail::point_origin_interface {
|
||||
static constexpr QuantitySpec auto quantity_spec = QS;
|
||||
static constexpr QuantitySpec auto _quantity_spec_ = QS;
|
||||
};
|
||||
|
||||
MP_UNITS_EXPORT template<QuantityPoint auto QP>
|
||||
struct relative_point_origin : detail::point_origin_interface {
|
||||
static constexpr QuantityPoint auto quantity_point = QP;
|
||||
static constexpr QuantitySpec auto quantity_spec = []() {
|
||||
static constexpr QuantityPoint auto _quantity_point_ = QP;
|
||||
static constexpr QuantitySpec auto _quantity_spec_ = []() {
|
||||
// select the strongest of specs
|
||||
if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(QP.quantity_spec)>>)
|
||||
return QP.point_origin.quantity_spec;
|
||||
return QP.point_origin._quantity_spec_;
|
||||
else
|
||||
return QP.quantity_spec;
|
||||
}();
|
||||
static constexpr PointOrigin auto absolute_point_origin = QP.absolute_point_origin;
|
||||
static constexpr PointOrigin auto _absolute_point_origin_ = QP.absolute_point_origin;
|
||||
};
|
||||
|
||||
template<QuantitySpec auto QS>
|
||||
@ -143,8 +143,8 @@ constexpr bool is_specialization_of_zeroth_point_origin<zeroth_point_origin_<QS>
|
||||
MP_UNITS_EXPORT template<Reference R>
|
||||
[[nodiscard]] consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R)
|
||||
{
|
||||
if constexpr (requires { get_unit(R{}).point_origin; })
|
||||
return get_unit(R{}).point_origin;
|
||||
if constexpr (requires { get_unit(R{})._point_origin_; })
|
||||
return get_unit(R{})._point_origin_;
|
||||
else
|
||||
return zeroth_point_origin<get_quantity_spec(R{})>;
|
||||
}
|
||||
@ -157,7 +157,7 @@ template<PointOrigin PO>
|
||||
if constexpr (is_derived_from_specialization_of_v<PO, absolute_point_origin>)
|
||||
return po;
|
||||
else
|
||||
return po.quantity_point.absolute_point_origin;
|
||||
return po._quantity_point_.absolute_point_origin;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@ -220,7 +220,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
template<typename FwdQ, PointOrigin PO2, QuantityOf<PO2::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
template<typename FwdQ, PointOrigin PO2, QuantityOf<PO2::_quantity_spec_> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires std::constructible_from<quantity_type, FwdQ> && detail::SameAbsolutePointOriginAs<PO2, PO>
|
||||
constexpr quantity_point(FwdQ&& q, PO2) :
|
||||
quantity_point(
|
||||
@ -309,9 +309,9 @@ public:
|
||||
|
||||
[[nodiscard]] constexpr Quantity auto quantity_from_zero() const
|
||||
{
|
||||
if constexpr (requires { unit.point_origin; }) {
|
||||
if constexpr (requires { unit._point_origin_; }) {
|
||||
// original quantity point unit can be lost in the below operation
|
||||
const auto q = quantity_from(unit.point_origin);
|
||||
const auto q = quantity_from(unit._point_origin_);
|
||||
if constexpr (requires { q.in(unit); })
|
||||
// restore the unit if possible (non-truncating)
|
||||
return q.in(unit);
|
||||
@ -452,7 +452,7 @@ public:
|
||||
// binary operators on quantity points
|
||||
template<std::derived_from<quantity_point> QP, auto R2, typename Rep2>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R2)), PO.quantity_spec>
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R2)), PO._quantity_spec_>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q)
|
||||
requires requires { qp.quantity_ref_from(PO) + q; }
|
||||
{
|
||||
@ -464,7 +464,7 @@ public:
|
||||
|
||||
template<auto R1, typename Rep1, std::derived_from<quantity_point> QP>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R1)), PO.quantity_spec>
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R1)), PO._quantity_spec_>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator+(const quantity<R1, Rep1>& q, const QP& qp)
|
||||
requires requires { q + qp.quantity_ref_from(PO); }
|
||||
{
|
||||
@ -473,7 +473,7 @@ public:
|
||||
|
||||
template<std::derived_from<quantity_point> QP, auto R2, typename Rep2>
|
||||
// TODO simplify when gcc catches up
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R2)), PO.quantity_spec>
|
||||
requires ReferenceOf<MP_UNITS_REMOVE_CONST(decltype(R2)), PO._quantity_spec_>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q)
|
||||
requires requires { qp.quantity_ref_from(PO) - q; }
|
||||
{
|
||||
@ -497,7 +497,7 @@ public:
|
||||
|
||||
template<std::derived_from<quantity_point> QP, PointOrigin PO2>
|
||||
requires QuantityPointOf<quantity_point, PO2{}> &&
|
||||
ReferenceOf<std::remove_const_t<decltype(reference)>, PO2::quantity_spec>
|
||||
ReferenceOf<std::remove_const_t<decltype(reference)>, PO2::_quantity_spec_>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const QP& qp, PO2 po)
|
||||
{
|
||||
if constexpr (point_origin == po)
|
||||
@ -508,18 +508,19 @@ public:
|
||||
else
|
||||
return qp.quantity_ref_from(point_origin) + (qp.point_origin - qp.absolute_point_origin);
|
||||
} else {
|
||||
if constexpr (point_origin == po.quantity_point.point_origin)
|
||||
return qp.quantity_ref_from(point_origin) - po.quantity_point.quantity_ref_from(po.quantity_point.point_origin);
|
||||
if constexpr (point_origin == po._quantity_point_.point_origin)
|
||||
return qp.quantity_ref_from(point_origin) -
|
||||
po._quantity_point_.quantity_ref_from(po._quantity_point_.point_origin);
|
||||
else
|
||||
return qp.quantity_ref_from(point_origin) -
|
||||
po.quantity_point.quantity_ref_from(po.quantity_point.point_origin) +
|
||||
(qp.point_origin - po.quantity_point.point_origin);
|
||||
po._quantity_point_.quantity_ref_from(po._quantity_point_.point_origin) +
|
||||
(qp.point_origin - po._quantity_point_.point_origin);
|
||||
}
|
||||
}
|
||||
|
||||
template<PointOrigin PO1, std::derived_from<quantity_point> QP>
|
||||
requires QuantityPointOf<quantity_point, PO1{}> &&
|
||||
ReferenceOf<std::remove_const_t<decltype(reference)>, PO1::quantity_spec>
|
||||
ReferenceOf<std::remove_const_t<decltype(reference)>, PO1::_quantity_spec_>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(PO1 po, const QP& qp)
|
||||
{
|
||||
return -(qp - po);
|
||||
|
@ -73,7 +73,7 @@ concept PointOrigin = detail::TagType<T> && std::derived_from<T, detail::point_o
|
||||
* Satisfied by all quantity point origins that are defined using a provided quantity specification.
|
||||
*/
|
||||
MP_UNITS_EXPORT template<typename T, auto QS>
|
||||
concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<MP_UNITS_REMOVE_CONST(decltype(QS)), T::quantity_spec>;
|
||||
concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<MP_UNITS_REMOVE_CONST(decltype(QS)), T::_quantity_spec_>;
|
||||
|
||||
MP_UNITS_EXPORT template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
|
||||
RepresentationOf<get_quantity_spec(R).character> Rep>
|
||||
@ -100,11 +100,11 @@ template<PointOrigin PO1, PointOrigin PO2>
|
||||
return po1 == po2;
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin> &&
|
||||
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||
return po1.absolute_point_origin == po2.absolute_point_origin;
|
||||
return po1._absolute_point_origin_ == po2._absolute_point_origin_;
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin>)
|
||||
return po1.absolute_point_origin == po2;
|
||||
return po1._absolute_point_origin_ == po2;
|
||||
else if constexpr (is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||
return po1 == po2.absolute_point_origin;
|
||||
return po1 == po2._absolute_point_origin_;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -161,10 +161,10 @@ struct unit_interface {
|
||||
if constexpr (std::is_same_v<M, std::remove_const_t<decltype(mp_units::mag<1>)>>)
|
||||
return u;
|
||||
else if constexpr (is_specialization_of_scaled_unit<U>) {
|
||||
if constexpr (M{} * U::mag == mag<1>)
|
||||
return U::reference_unit;
|
||||
if constexpr (M{} * U::_mag_ == mag<1>)
|
||||
return U::_reference_unit_;
|
||||
else
|
||||
return scaled_unit<M{} * U::mag, std::remove_const_t<decltype(U::reference_unit)>>{};
|
||||
return scaled_unit<M{} * U::_mag_, std::remove_const_t<decltype(U::_reference_unit_)>>{};
|
||||
} else
|
||||
return scaled_unit<M{}, U>{};
|
||||
}
|
||||
@ -221,19 +221,19 @@ struct unit_interface {
|
||||
}
|
||||
};
|
||||
|
||||
template<Unit U, bool = requires { U::point_origin; }>
|
||||
template<Unit U, bool = requires { U::_point_origin_; }>
|
||||
struct propagate_point_origin {};
|
||||
|
||||
template<Unit U>
|
||||
struct propagate_point_origin<U, true> {
|
||||
static constexpr auto point_origin = U::point_origin;
|
||||
static constexpr auto _point_origin_ = U::_point_origin_;
|
||||
};
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
struct scaled_unit_impl : detail::unit_interface, detail::propagate_point_origin<U> {
|
||||
using _base_type_ = scaled_unit_impl; // exposition only
|
||||
static constexpr Magnitude auto mag = M;
|
||||
static constexpr U reference_unit{};
|
||||
static constexpr Magnitude auto _mag_ = M;
|
||||
static constexpr U _reference_unit_{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -306,18 +306,18 @@ struct named_unit;
|
||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS>
|
||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||
struct named_unit<Symbol, QS> : detail::unit_interface {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto _quantity_spec_ = QS;
|
||||
};
|
||||
|
||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||
struct named_unit<Symbol, QS, PO> : detail::unit_interface {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
static constexpr auto point_origin = PO;
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto _quantity_spec_ = QS;
|
||||
static constexpr auto _point_origin_ = PO;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -333,8 +333,8 @@ struct named_unit<Symbol, QS, PO> : detail::unit_interface {
|
||||
template<symbol_text Symbol>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol> : detail::unit_interface {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier
|
||||
};
|
||||
|
||||
/**
|
||||
@ -348,16 +348,16 @@ struct named_unit<Symbol> : detail::unit_interface {
|
||||
template<symbol_text Symbol, Unit auto U>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol, U> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique unit identifier
|
||||
};
|
||||
|
||||
template<symbol_text Symbol, Unit auto U, PointOrigin auto PO>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol, U, PO> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto point_origin = PO;
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto _point_origin_ = PO;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -372,18 +372,18 @@ struct named_unit<Symbol, U, PO> : decltype(U)::_base_type_ {
|
||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS>
|
||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||
struct named_unit<Symbol, U, QS> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto _quantity_spec_ = QS;
|
||||
};
|
||||
|
||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||
struct named_unit<Symbol, U, QS, PO> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
static constexpr auto point_origin = PO;
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto _symbol_ = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto _quantity_spec_ = QS;
|
||||
static constexpr auto _point_origin_ = PO;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -412,7 +412,7 @@ MP_UNITS_EXPORT template<symbol_text Symbol, Magnitude auto M, PrefixableUnit au
|
||||
requires(!Symbol.empty())
|
||||
struct prefixed_unit : decltype(M * U)::_base_type_ {
|
||||
using _base_type_ = prefixed_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol + U.symbol;
|
||||
static constexpr auto _symbol_ = Symbol + U._symbol_;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
@ -765,10 +765,10 @@ MP_UNITS_EXPORT_END
|
||||
namespace detail {
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, Unit U>
|
||||
requires requires { U::symbol; }
|
||||
requires requires { U::_symbol_; }
|
||||
constexpr Out unit_symbol_impl(Out out, U, const unit_symbol_formatting& fmt, bool negative_power)
|
||||
{
|
||||
return copy_symbol<CharT>(U::symbol, fmt.encoding, negative_power, out);
|
||||
return copy_symbol<CharT>(U::_symbol_, fmt.encoding, negative_power, out);
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, auto M, typename U>
|
||||
@ -777,8 +777,8 @@ constexpr Out unit_symbol_impl(Out out, const scaled_unit_impl<M, U>& u, const u
|
||||
{
|
||||
*out++ = '[';
|
||||
_magnitude_symbol<CharT>(out, M, fmt);
|
||||
if constexpr (space_before_unit_symbol<scaled_unit<M, U>::reference_unit>) *out++ = ' ';
|
||||
unit_symbol_impl<CharT>(out, u.reference_unit, fmt, negative_power);
|
||||
if constexpr (space_before_unit_symbol<scaled_unit<M, U>::_reference_unit_>) *out++ = ' ';
|
||||
unit_symbol_impl<CharT>(out, u._reference_unit_, fmt, negative_power);
|
||||
*out++ = ']';
|
||||
return out;
|
||||
}
|
||||
@ -787,8 +787,8 @@ template<typename... Us, Unit U>
|
||||
[[nodiscard]] consteval Unit auto get_common_unit_in(common_unit<Us...>, U u)
|
||||
{
|
||||
auto get_magnitude = [&]() {
|
||||
if constexpr (requires { common_unit<Us...>::mag; })
|
||||
return common_unit<Us...>::mag;
|
||||
if constexpr (requires { common_unit<Us...>::_mag_; })
|
||||
return common_unit<Us...>::_mag_;
|
||||
else
|
||||
return mag<1>;
|
||||
};
|
||||
|
@ -80,9 +80,9 @@ template<typename... Us>
|
||||
template<Unit U>
|
||||
[[nodiscard]] consteval bool has_associated_quantity(U)
|
||||
{
|
||||
if constexpr (requires { U::quantity_spec; }) return true;
|
||||
if constexpr (requires { U::reference_unit; })
|
||||
return has_associated_quantity(U::reference_unit);
|
||||
if constexpr (requires { U::_quantity_spec_; }) return true;
|
||||
if constexpr (requires { U::_reference_unit_; })
|
||||
return has_associated_quantity(U::_reference_unit_);
|
||||
else if constexpr (requires { typename U::_num_; })
|
||||
return has_associated_quantity(typename U::_num_{}) && has_associated_quantity(typename U::_den_{});
|
||||
else
|
||||
@ -131,7 +131,7 @@ concept UnitCompatibleWith =
|
||||
(!AssociatedUnit<U> || UnitOf<U, QS>) && detail::UnitConvertibleTo<FromU, U{}>;
|
||||
|
||||
template<typename T>
|
||||
concept OffsetUnit = Unit<T> && requires { T::point_origin; };
|
||||
concept OffsetUnit = Unit<T> && requires { T::_point_origin_; };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
@ -118,9 +118,9 @@ struct relative_po_ final : relative_point_origin<QP> {};
|
||||
template<auto QP>
|
||||
constexpr relative_po_<QP> relative_po;
|
||||
|
||||
static_assert(relative_po<absolute_po<isq::length> + isq::height(42 * m)>.quantity_spec == isq::height);
|
||||
static_assert(relative_po<absolute_po<kind_of<isq::length>> + isq::height(42 * m)>.quantity_spec == isq::height);
|
||||
static_assert(relative_po<absolute_po<isq::height> + 42 * m>.quantity_spec == isq::height);
|
||||
static_assert(relative_po<absolute_po<isq::length> + isq::height(42 * m)>._quantity_spec_ == isq::height);
|
||||
static_assert(relative_po<absolute_po<kind_of<isq::length>> + isq::height(42 * m)>._quantity_spec_ == isq::height);
|
||||
static_assert(relative_po<absolute_po<isq::height> + 42 * m>._quantity_spec_ == isq::height);
|
||||
|
||||
inline constexpr struct my_kelvin final : named_unit<"my_K", mag<10> * si::kelvin> {
|
||||
} my_kelvin;
|
||||
|
@ -191,7 +191,7 @@ static_assert(convertible(standard_gravity, standard_gravity));
|
||||
static_assert(convertible(standard_gravity, metre / square(second)));
|
||||
static_assert(standard_gravity == standard_gravity);
|
||||
static_assert(standard_gravity != metre / square(second)); // magnitude is different
|
||||
static_assert(standard_gravity.symbol == symbol_text{u8"g₀", "g_0"});
|
||||
static_assert(standard_gravity._symbol_ == symbol_text{u8"g₀", "g_0"});
|
||||
|
||||
// prefixed_unit
|
||||
static_assert(is_of_type<kilometre, std::remove_const_t<decltype(kilo<metre>)>>);
|
||||
@ -199,7 +199,7 @@ static_assert(is_of_type<get_canonical_unit(kilometre).reference_unit, metre_>);
|
||||
static_assert(get_canonical_unit(kilometre).mag == mag<1000>);
|
||||
static_assert(convertible(kilometre, metre));
|
||||
static_assert(kilometre != metre);
|
||||
static_assert(kilometre.symbol == "km");
|
||||
static_assert(kilometre._symbol_ == "km");
|
||||
|
||||
static_assert(is_of_type<kilojoule, std::remove_const_t<decltype(kilo<joule>)>>);
|
||||
static_assert(is_of_type<get_canonical_unit(kilojoule).reference_unit,
|
||||
@ -207,7 +207,7 @@ static_assert(is_of_type<get_canonical_unit(kilojoule).reference_unit,
|
||||
static_assert(get_canonical_unit(kilojoule).mag == mag<1'000'000>);
|
||||
static_assert(convertible(kilojoule, joule));
|
||||
static_assert(kilojoule != joule);
|
||||
static_assert(kilojoule.symbol == "kJ");
|
||||
static_assert(kilojoule._symbol_ == "kJ");
|
||||
|
||||
static_assert(is_of_type<kilo<metre>, kilo_<metre_>>);
|
||||
static_assert(is_of_type<kilo<joule>, kilo_<joule_>>);
|
||||
@ -217,30 +217,30 @@ static_assert(
|
||||
|
||||
|
||||
// prefixes
|
||||
static_assert(si::quecto<metre>.symbol == "qm");
|
||||
static_assert(si::ronto<metre>.symbol == "rm");
|
||||
static_assert(si::yocto<metre>.symbol == "ym");
|
||||
static_assert(si::zepto<metre>.symbol == "zm");
|
||||
static_assert(si::atto<metre>.symbol == "am");
|
||||
static_assert(si::femto<metre>.symbol == "fm");
|
||||
static_assert(si::pico<metre>.symbol == "pm");
|
||||
static_assert(si::nano<metre>.symbol == "nm");
|
||||
static_assert(si::micro<metre>.symbol == symbol_text{u8"µm", "um"});
|
||||
static_assert(si::milli<metre>.symbol == "mm");
|
||||
static_assert(si::centi<metre>.symbol == "cm");
|
||||
static_assert(si::deci<metre>.symbol == "dm");
|
||||
static_assert(si::deca<metre>.symbol == "dam");
|
||||
static_assert(si::hecto<metre>.symbol == "hm");
|
||||
static_assert(si::kilo<metre>.symbol == "km");
|
||||
static_assert(si::mega<metre>.symbol == "Mm");
|
||||
static_assert(si::giga<metre>.symbol == "Gm");
|
||||
static_assert(si::tera<metre>.symbol == "Tm");
|
||||
static_assert(si::peta<metre>.symbol == "Pm");
|
||||
static_assert(si::exa<metre>.symbol == "Em");
|
||||
static_assert(si::zetta<metre>.symbol == "Zm");
|
||||
static_assert(si::yotta<metre>.symbol == "Ym");
|
||||
static_assert(si::ronna<metre>.symbol == "Rm");
|
||||
static_assert(si::quetta<metre>.symbol == "Qm");
|
||||
static_assert(si::quecto<metre>._symbol_ == "qm");
|
||||
static_assert(si::ronto<metre>._symbol_ == "rm");
|
||||
static_assert(si::yocto<metre>._symbol_ == "ym");
|
||||
static_assert(si::zepto<metre>._symbol_ == "zm");
|
||||
static_assert(si::atto<metre>._symbol_ == "am");
|
||||
static_assert(si::femto<metre>._symbol_ == "fm");
|
||||
static_assert(si::pico<metre>._symbol_ == "pm");
|
||||
static_assert(si::nano<metre>._symbol_ == "nm");
|
||||
static_assert(si::micro<metre>._symbol_ == symbol_text{u8"µm", "um"});
|
||||
static_assert(si::milli<metre>._symbol_ == "mm");
|
||||
static_assert(si::centi<metre>._symbol_ == "cm");
|
||||
static_assert(si::deci<metre>._symbol_ == "dm");
|
||||
static_assert(si::deca<metre>._symbol_ == "dam");
|
||||
static_assert(si::hecto<metre>._symbol_ == "hm");
|
||||
static_assert(si::kilo<metre>._symbol_ == "km");
|
||||
static_assert(si::mega<metre>._symbol_ == "Mm");
|
||||
static_assert(si::giga<metre>._symbol_ == "Gm");
|
||||
static_assert(si::tera<metre>._symbol_ == "Tm");
|
||||
static_assert(si::peta<metre>._symbol_ == "Pm");
|
||||
static_assert(si::exa<metre>._symbol_ == "Em");
|
||||
static_assert(si::zetta<metre>._symbol_ == "Zm");
|
||||
static_assert(si::yotta<metre>._symbol_ == "Ym");
|
||||
static_assert(si::ronna<metre>._symbol_ == "Rm");
|
||||
static_assert(si::quetta<metre>._symbol_ == "Qm");
|
||||
|
||||
// scaled_unit
|
||||
constexpr auto m_1 = mag<1> * metre;
|
||||
|
Reference in New Issue
Block a user