mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
refactor: 💥 Magnitude
renamed to UnitMagnitude
and magnitude
to unit_magnitude
This commit is contained in:
@ -55,8 +55,6 @@ add_mp_units_module(
|
||||
include/mp-units/framework/dimension.h
|
||||
include/mp-units/framework/dimension_concepts.h
|
||||
include/mp-units/framework/expression_template.h
|
||||
include/mp-units/framework/magnitude.h
|
||||
include/mp-units/framework/magnitude_concepts.h
|
||||
include/mp-units/framework/quantity.h
|
||||
include/mp-units/framework/quantity_cast.h
|
||||
include/mp-units/framework/quantity_concepts.h
|
||||
@ -71,6 +69,8 @@ add_mp_units_module(
|
||||
include/mp-units/framework/system_reference.h
|
||||
include/mp-units/framework/unit.h
|
||||
include/mp-units/framework/unit_concepts.h
|
||||
include/mp-units/framework/unit_magnitude.h
|
||||
include/mp-units/framework/unit_magnitude_concepts.h
|
||||
include/mp-units/framework/unit_symbol_formatting.h
|
||||
include/mp-units/framework/value_cast.h
|
||||
include/mp-units/compat_macros.h
|
||||
|
@ -23,10 +23,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <mp-units/ext/type_traits.h>
|
||||
#include <mp-units/framework/magnitude.h>
|
||||
#include <mp-units/framework/quantity_concepts.h>
|
||||
#include <mp-units/framework/reference_concepts.h>
|
||||
#include <mp-units/framework/unit.h>
|
||||
#include <mp-units/framework/unit_magnitude.h>
|
||||
|
||||
namespace mp_units::detail {
|
||||
|
||||
@ -49,7 +49,7 @@ using maybe_common_type =
|
||||
* @tparam Rep1 first quantity representation type
|
||||
* @tparam Rep2 second quantity representation type
|
||||
*/
|
||||
template<Magnitude auto M, typename Rep1, typename Rep2>
|
||||
template<UnitMagnitude auto M, typename Rep1, typename Rep2>
|
||||
struct conversion_type_traits {
|
||||
using c_rep_type = maybe_common_type<Rep1, Rep2>;
|
||||
using c_mag_type = common_magnitude_type<M>;
|
||||
@ -74,11 +74,11 @@ struct conversion_type_traits {
|
||||
* @tparam M common magnitude between the two quantities
|
||||
* @tparam T common multiplier representation type
|
||||
*/
|
||||
template<Magnitude auto M, typename T>
|
||||
template<UnitMagnitude auto M, typename T>
|
||||
struct conversion_value_traits {
|
||||
static constexpr Magnitude auto num = _numerator(M);
|
||||
static constexpr Magnitude auto den = _denominator(M);
|
||||
static constexpr Magnitude auto irr = M * (den / num);
|
||||
static constexpr UnitMagnitude auto num = _numerator(M);
|
||||
static constexpr UnitMagnitude auto den = _denominator(M);
|
||||
static constexpr UnitMagnitude auto irr = M * (den / num);
|
||||
static constexpr T num_mult = _get_value<T>(num);
|
||||
static constexpr T den_mult = _get_value<T>(den);
|
||||
static constexpr T irr_mult = _get_value<T>(irr);
|
||||
@ -108,7 +108,7 @@ template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdF
|
||||
To::reference}; // this is the only (and recommended) way to do a truncating conversion on a number, so we
|
||||
// are using static_cast to suppress all the compiler warnings on conversions
|
||||
} else {
|
||||
constexpr Magnitude auto c_mag = get_canonical_unit(From::unit).mag / get_canonical_unit(To::unit).mag;
|
||||
constexpr UnitMagnitude auto c_mag = get_canonical_unit(From::unit).mag / get_canonical_unit(To::unit).mag;
|
||||
using type_traits = conversion_type_traits<c_mag, typename From::rep, typename To::rep>;
|
||||
using multiplier_type = typename type_traits::multiplier_type;
|
||||
// TODO the below crashed nearly every compiler I tried it on
|
||||
@ -170,7 +170,7 @@ template<QuantityPoint ToQP, typename FwdFromQP, QuantityPoint FromQP = std::rem
|
||||
// In the following, we carefully select the order of these three operations: each of (a) and (b) is scheduled
|
||||
// either before or after (c), such that (c) acts on the largest range possible among all combination of source
|
||||
// and target unit and representation.
|
||||
constexpr Magnitude auto c_mag = get_canonical_unit(FromQP::unit).mag / get_canonical_unit(ToQP::unit).mag;
|
||||
constexpr UnitMagnitude auto c_mag = get_canonical_unit(FromQP::unit).mag / get_canonical_unit(ToQP::unit).mag;
|
||||
using type_traits = conversion_type_traits<c_mag, typename FromQP::rep, typename ToQP::rep>;
|
||||
using value_traits = conversion_value_traits<c_mag, typename type_traits::multiplier_type>;
|
||||
using c_rep_type = typename type_traits::c_rep_type;
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include <mp-units/framework/dimension.h>
|
||||
#include <mp-units/framework/dimension_concepts.h>
|
||||
#include <mp-units/framework/expression_template.h>
|
||||
#include <mp-units/framework/magnitude.h>
|
||||
#include <mp-units/framework/magnitude_concepts.h>
|
||||
#include <mp-units/framework/unit_magnitude.h>
|
||||
#include <mp-units/framework/unit_magnitude_concepts.h>
|
||||
#include <mp-units/framework/quantity.h>
|
||||
#include <mp-units/framework/quantity_cast.h>
|
||||
#include <mp-units/framework/quantity_concepts.h>
|
||||
|
@ -34,11 +34,11 @@
|
||||
#include <mp-units/ext/type_name.h>
|
||||
#include <mp-units/ext/type_traits.h>
|
||||
#include <mp-units/framework/expression_template.h>
|
||||
#include <mp-units/framework/magnitude.h>
|
||||
#include <mp-units/framework/quantity_point_concepts.h>
|
||||
#include <mp-units/framework/quantity_spec_concepts.h>
|
||||
#include <mp-units/framework/symbol_text.h>
|
||||
#include <mp-units/framework/unit_concepts.h>
|
||||
#include <mp-units/framework/unit_magnitude.h>
|
||||
#include <mp-units/framework/unit_symbol_formatting.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
@ -61,7 +61,7 @@ namespace mp_units {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
template<UnitMagnitude auto M, Unit U>
|
||||
struct scaled_unit_impl;
|
||||
|
||||
template<typename T>
|
||||
@ -84,7 +84,7 @@ struct derived_unit_impl;
|
||||
* @tparam U a unit to use as a `reference_unit`
|
||||
* @tparam M a Magnitude representing an absolute scaling factor of this unit
|
||||
*/
|
||||
template<Magnitude M, Unit U>
|
||||
template<UnitMagnitude M, Unit U>
|
||||
struct canonical_unit {
|
||||
M mag;
|
||||
U reference_unit;
|
||||
@ -92,7 +92,7 @@ struct canonical_unit {
|
||||
|
||||
#if MP_UNITS_COMP_CLANG
|
||||
|
||||
template<Magnitude M, Unit U>
|
||||
template<UnitMagnitude M, Unit U>
|
||||
canonical_unit(M, U) -> canonical_unit<M, U>;
|
||||
|
||||
#endif
|
||||
@ -167,7 +167,7 @@ struct unit_interface {
|
||||
/**
|
||||
* Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned.
|
||||
*/
|
||||
template<Magnitude M, Unit U>
|
||||
template<UnitMagnitude M, Unit U>
|
||||
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(M, U u)
|
||||
{
|
||||
if constexpr (std::is_same_v<M, MP_UNITS_NONCONST_TYPE(mp_units::mag<1>)>)
|
||||
@ -181,7 +181,7 @@ struct unit_interface {
|
||||
return scaled_unit<M{}, U>{};
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval Unit auto operator*(Unit auto, Magnitude auto)
|
||||
[[nodiscard]] friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto)
|
||||
#if __cpp_deleted_function
|
||||
= delete("To scale a unit use `mag * unit` syntax");
|
||||
#else
|
||||
@ -191,7 +191,7 @@ struct unit_interface {
|
||||
/**
|
||||
* Returns the result of multiplication with an inverse unit.
|
||||
*/
|
||||
template<Magnitude M, Unit U>
|
||||
template<UnitMagnitude M, Unit U>
|
||||
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator/(M mag, U u)
|
||||
{
|
||||
return mag * inverse(u);
|
||||
@ -246,10 +246,10 @@ struct propagate_point_origin<U, true> {
|
||||
static constexpr auto _point_origin_ = U::_point_origin_;
|
||||
};
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
template<UnitMagnitude 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 UnitMagnitude auto _mag_ = M;
|
||||
static constexpr U _reference_unit_{};
|
||||
};
|
||||
|
||||
@ -264,8 +264,8 @@ struct scaled_unit_impl : detail::unit_interface, detail::propagate_point_origin
|
||||
* @note User should not instantiate this type! It is not exported from the C++ module. The library will
|
||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||
*/
|
||||
template<Magnitude auto M, Unit U>
|
||||
requires(M != magnitude<>{} && M != mag<1>)
|
||||
template<UnitMagnitude auto M, Unit U>
|
||||
requires(M != unit_magnitude<>{} && M != mag<1>)
|
||||
struct scaled_unit final : detail::scaled_unit_impl<M, U> {};
|
||||
|
||||
namespace detail {
|
||||
@ -425,7 +425,7 @@ struct named_unit<Symbol, U, QS, PO> : decltype(U)::_base_type_ {
|
||||
* @tparam M scaling factor of the prefix
|
||||
* @tparam U a named unit to be prefixed
|
||||
*/
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol, Magnitude auto M, PrefixableUnit auto U>
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U>
|
||||
requires(!Symbol.empty())
|
||||
struct prefixed_unit : decltype(M * U)::_base_type_ {
|
||||
using _base_type_ = prefixed_unit; // exposition only
|
||||
@ -594,9 +594,9 @@ template<typename T, typename F, int Num, int... Den>
|
||||
template<typename... Us>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(const type_list<Us...>&)
|
||||
{
|
||||
auto magnitude = (mp_units::mag<1> * ... * get_canonical_unit_impl(Us{}, Us{}).mag);
|
||||
auto unit_magnitude = (mp_units::mag<1> * ... * get_canonical_unit_impl(Us{}, Us{}).mag);
|
||||
auto u = (one * ... * get_canonical_unit_impl(Us{}, Us{}).reference_unit);
|
||||
return canonical_unit{magnitude, u};
|
||||
return canonical_unit{unit_magnitude, u};
|
||||
}
|
||||
|
||||
template<Unit T, typename... Expr>
|
||||
@ -810,7 +810,7 @@ template<typename... Us, Unit U>
|
||||
return mag<1>;
|
||||
};
|
||||
constexpr auto canonical_u = get_canonical_unit(u);
|
||||
constexpr Magnitude auto cmag = get_magnitude() / canonical_u.mag;
|
||||
constexpr UnitMagnitude auto cmag = get_magnitude() / canonical_u.mag;
|
||||
if constexpr (cmag == mag<1>)
|
||||
return u;
|
||||
else
|
||||
|
@ -25,9 +25,9 @@
|
||||
// IWYU pragma: private, include <mp-units/framework.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/framework/expression_template.h>
|
||||
#include <mp-units/framework/magnitude.h>
|
||||
#include <mp-units/framework/quantity_spec_concepts.h>
|
||||
#include <mp-units/framework/symbol_text.h>
|
||||
#include <mp-units/framework/unit_magnitude.h>
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
@ -45,8 +45,8 @@ struct unit_interface;
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
concept Unit = detail::SymbolicConstant<T> && std::derived_from<T, detail::unit_interface>;
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
requires(M != magnitude<>{} && M != mag<1>)
|
||||
template<UnitMagnitude auto M, Unit U>
|
||||
requires(M != unit_magnitude<>{} && M != mag<1>)
|
||||
struct scaled_unit;
|
||||
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
||||
|
@ -32,8 +32,8 @@
|
||||
#include <mp-units/ext/type_traits.h>
|
||||
#include <mp-units/framework/customization_points.h>
|
||||
#include <mp-units/framework/expression_template.h>
|
||||
#include <mp-units/framework/magnitude_concepts.h>
|
||||
#include <mp-units/framework/symbol_text.h>
|
||||
#include <mp-units/framework/unit_magnitude_concepts.h>
|
||||
#include <mp-units/framework/unit_symbol_formatting.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
@ -214,42 +214,42 @@ template<typename T>
|
||||
|
||||
// The largest integer which can be extracted from any magnitude with only a single basis vector.
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto integer_part(magnitude<M>);
|
||||
[[nodiscard]] consteval auto integer_part(unit_magnitude<M>);
|
||||
[[nodiscard]] consteval std::intmax_t integer_part(ratio r) { return r.num / r.den; }
|
||||
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto remove_positive_power(magnitude<M> m);
|
||||
[[nodiscard]] consteval auto remove_positive_power(unit_magnitude<M> m);
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto remove_mag_constants(magnitude<M> m);
|
||||
[[nodiscard]] consteval auto remove_mag_constants(unit_magnitude<M> m);
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto only_positive_mag_constants(magnitude<M> m);
|
||||
[[nodiscard]] consteval auto only_positive_mag_constants(unit_magnitude<M> m);
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto only_negative_mag_constants(magnitude<M> m);
|
||||
[[nodiscard]] consteval auto only_negative_mag_constants(unit_magnitude<M> m);
|
||||
|
||||
template<MagArg auto Base, int Num, int Den = 1>
|
||||
requires(detail::get_base_value(Base) > 0)
|
||||
[[nodiscard]] consteval Magnitude auto mag_power_lazy();
|
||||
[[nodiscard]] consteval UnitMagnitude auto mag_power_lazy();
|
||||
|
||||
template<typename T>
|
||||
struct magnitude_base {};
|
||||
|
||||
template<auto H, auto... T>
|
||||
struct magnitude_base<magnitude<H, T...>> {
|
||||
struct magnitude_base<unit_magnitude<H, T...>> {
|
||||
template<auto H2, auto... T2>
|
||||
[[nodiscard]] friend consteval Magnitude auto _multiply_impl(magnitude<H, T...>, magnitude<H2, T2...>)
|
||||
[[nodiscard]] friend consteval UnitMagnitude auto _multiply_impl(unit_magnitude<H, T...>, unit_magnitude<H2, T2...>)
|
||||
{
|
||||
if constexpr (mag_less(H, H2)) {
|
||||
if constexpr (sizeof...(T) == 0) {
|
||||
// Shortcut for the "pure prepend" case, which makes it easier to implement some of the other cases.
|
||||
return magnitude<H, H2, T2...>{};
|
||||
return unit_magnitude<H, H2, T2...>{};
|
||||
} else {
|
||||
return magnitude<H>{} * (magnitude<T...>{} * magnitude<H2, T2...>{});
|
||||
return unit_magnitude<H>{} * (unit_magnitude<T...>{} * unit_magnitude<H2, T2...>{});
|
||||
}
|
||||
} else if constexpr (mag_less(H2, H)) {
|
||||
return magnitude<H2>{} * (magnitude<H, T...>{} * magnitude<T2...>{});
|
||||
return unit_magnitude<H2>{} * (unit_magnitude<H, T...>{} * unit_magnitude<T2...>{});
|
||||
} else {
|
||||
if constexpr (is_same_v<decltype(get_base(H)), decltype(get_base(H2))>) {
|
||||
constexpr auto partial_product = magnitude<T...>{} * magnitude<T2...>{};
|
||||
constexpr auto partial_product = unit_magnitude<T...>{} * unit_magnitude<T2...>{};
|
||||
if constexpr (get_exponent(H) + get_exponent(H2) == 0) {
|
||||
return partial_product;
|
||||
} else {
|
||||
@ -259,7 +259,7 @@ struct magnitude_base<magnitude<H, T...>> {
|
||||
if constexpr (get_exponent(new_head) == 0) {
|
||||
return partial_product;
|
||||
} else {
|
||||
return magnitude<new_head>{} * partial_product;
|
||||
return unit_magnitude<new_head>{} * partial_product;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,30 +284,32 @@ struct magnitude_base<magnitude<H, T...>> {
|
||||
// Thus, we make the _simplest_ choice which reproduces the correct convention in the rational case: namely, taking
|
||||
// the minimum power for each base (where absent bases implicitly have a power of 0).
|
||||
template<auto H2, auto... T2>
|
||||
[[nodiscard]] friend consteval auto _common_magnitude(magnitude<H, T...>, magnitude<H2, T2...>)
|
||||
[[nodiscard]] friend consteval auto _common_magnitude(unit_magnitude<H, T...>, unit_magnitude<H2, T2...>)
|
||||
{
|
||||
using detail::remove_positive_power;
|
||||
|
||||
if constexpr (detail::get_base_value(H) < detail::get_base_value(H2)) {
|
||||
// When H1 has the smaller base, prepend to result from recursion.
|
||||
return remove_positive_power(magnitude<H>{}) * _common_magnitude(magnitude<T...>{}, magnitude<H2, T2...>{});
|
||||
return remove_positive_power(unit_magnitude<H>{}) *
|
||||
_common_magnitude(unit_magnitude<T...>{}, unit_magnitude<H2, T2...>{});
|
||||
} else if constexpr (detail::get_base_value(H2) < detail::get_base_value(H)) {
|
||||
// When H2 has the smaller base, prepend to result from recursion.
|
||||
return remove_positive_power(magnitude<H2>{}) * _common_magnitude(magnitude<H, T...>{}, magnitude<T2...>{});
|
||||
return remove_positive_power(unit_magnitude<H2>{}) *
|
||||
_common_magnitude(unit_magnitude<H, T...>{}, unit_magnitude<T2...>{});
|
||||
} else {
|
||||
// When the bases are equal, pick whichever has the lower power.
|
||||
constexpr auto common_tail = _common_magnitude(magnitude<T...>{}, magnitude<T2...>{});
|
||||
constexpr auto common_tail = _common_magnitude(unit_magnitude<T...>{}, unit_magnitude<T2...>{});
|
||||
if constexpr (detail::get_exponent(H) < detail::get_exponent(H2)) {
|
||||
return magnitude<H>{} * common_tail;
|
||||
return unit_magnitude<H>{} * common_tail;
|
||||
} else {
|
||||
return magnitude<H2>{} * common_tail;
|
||||
return unit_magnitude<H2>{} * common_tail;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<auto... Ms>
|
||||
[[nodiscard]] consteval std::size_t magnitude_list_size(magnitude<Ms...>)
|
||||
[[nodiscard]] consteval std::size_t magnitude_list_size(unit_magnitude<Ms...>)
|
||||
{
|
||||
return sizeof...(Ms);
|
||||
}
|
||||
@ -329,13 +331,13 @@ constexpr Out print_separator(Out out, const unit_symbol_formatting& fmt)
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, auto... Ms>
|
||||
requires(sizeof...(Ms) == 0)
|
||||
[[nodiscard]] constexpr auto mag_constants_text(Out out, magnitude<Ms...>, const unit_symbol_formatting&, bool)
|
||||
[[nodiscard]] constexpr auto mag_constants_text(Out out, unit_magnitude<Ms...>, const unit_symbol_formatting&, bool)
|
||||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, auto M, auto... Rest>
|
||||
[[nodiscard]] constexpr auto mag_constants_text(Out out, magnitude<M, Rest...>, const unit_symbol_formatting& fmt,
|
||||
[[nodiscard]] constexpr auto mag_constants_text(Out out, unit_magnitude<M, Rest...>, const unit_symbol_formatting& fmt,
|
||||
bool negative_power)
|
||||
{
|
||||
auto to_symbol = [&]<typename T>(T v) {
|
||||
@ -346,8 +348,8 @@ template<typename CharT, std::output_iterator<CharT> Out, auto M, auto... Rest>
|
||||
return (to_symbol(M), ..., (print_separator<CharT>(out, fmt), to_symbol(Rest)));
|
||||
}
|
||||
|
||||
template<typename CharT, Magnitude auto Num, Magnitude auto Den, Magnitude auto NumConstants,
|
||||
Magnitude auto DenConstants, std::intmax_t Exp10, std::output_iterator<CharT> Out>
|
||||
template<typename CharT, UnitMagnitude auto Num, UnitMagnitude auto Den, UnitMagnitude auto NumConstants,
|
||||
UnitMagnitude auto DenConstants, std::intmax_t Exp10, std::output_iterator<CharT> Out>
|
||||
constexpr Out magnitude_symbol_impl(Out out, const unit_symbol_formatting& fmt)
|
||||
{
|
||||
bool numerator = false;
|
||||
@ -419,31 +421,40 @@ constexpr Out magnitude_symbol_impl(Out out, const unit_symbol_formatting& fmt)
|
||||
* rational powers, and compare for equality.
|
||||
*/
|
||||
template<auto... Ms>
|
||||
struct magnitude : detail::magnitude_base<magnitude<Ms...>> {
|
||||
template<Magnitude M>
|
||||
[[nodiscard]] friend consteval Magnitude auto operator*(magnitude lhs, M rhs)
|
||||
struct unit_magnitude : detail::magnitude_base<unit_magnitude<Ms...>> {
|
||||
template<UnitMagnitude M>
|
||||
[[nodiscard]] friend consteval UnitMagnitude auto operator*(unit_magnitude lhs, M rhs)
|
||||
{
|
||||
if constexpr (sizeof...(Ms) == 0)
|
||||
return rhs;
|
||||
else if constexpr (is_same_v<M, magnitude<>>)
|
||||
else if constexpr (is_same_v<M, unit_magnitude<>>)
|
||||
return lhs;
|
||||
else
|
||||
return _multiply_impl(lhs, rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval auto operator/(magnitude lhs, Magnitude auto rhs) { return lhs * _pow<-1>(rhs); }
|
||||
|
||||
template<Magnitude Rhs>
|
||||
[[nodiscard]] friend consteval bool operator==(magnitude, Rhs)
|
||||
[[nodiscard]] friend consteval auto operator/(unit_magnitude lhs, UnitMagnitude auto rhs)
|
||||
{
|
||||
return is_same_v<magnitude, Rhs>;
|
||||
return lhs * _pow<-1>(rhs);
|
||||
}
|
||||
|
||||
template<UnitMagnitude Rhs>
|
||||
[[nodiscard]] friend consteval bool operator==(unit_magnitude, Rhs)
|
||||
{
|
||||
return is_same_v<unit_magnitude, Rhs>;
|
||||
}
|
||||
|
||||
private:
|
||||
// all below functions should in fact be in a `detail` namespace but are placed here to benefit from the ADL
|
||||
[[nodiscard]] friend consteval bool _is_integral(const magnitude&) { return (detail::is_integral_impl(Ms) && ...); }
|
||||
[[nodiscard]] friend consteval bool _is_rational(const magnitude&) { return (detail::is_rational_impl(Ms) && ...); }
|
||||
[[nodiscard]] friend consteval bool _is_positive_integral_power(const magnitude&)
|
||||
[[nodiscard]] friend consteval bool _is_integral(const unit_magnitude&)
|
||||
{
|
||||
return (detail::is_integral_impl(Ms) && ...);
|
||||
}
|
||||
[[nodiscard]] friend consteval bool _is_rational(const unit_magnitude&)
|
||||
{
|
||||
return (detail::is_rational_impl(Ms) && ...);
|
||||
}
|
||||
[[nodiscard]] friend consteval bool _is_positive_integral_power(const unit_magnitude&)
|
||||
{
|
||||
return (detail::is_positive_integral_power_impl(Ms) && ...);
|
||||
}
|
||||
@ -453,7 +464,7 @@ private:
|
||||
*/
|
||||
template<typename T>
|
||||
requires((detail::is_integral_impl(Ms) && ...)) || treat_as_floating_point<T>
|
||||
[[nodiscard]] friend consteval T _get_value(const magnitude&)
|
||||
[[nodiscard]] friend consteval T _get_value(const unit_magnitude&)
|
||||
{
|
||||
// Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow.
|
||||
constexpr T result = detail::checked_static_cast<T>((detail::compute_base_power<T>(Ms) * ... * T{1}));
|
||||
@ -463,55 +474,57 @@ private:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Magnitude rational powers implementation.
|
||||
template<int Num, int Den = 1>
|
||||
[[nodiscard]] friend consteval auto _pow(magnitude)
|
||||
[[nodiscard]] friend consteval auto _pow(unit_magnitude)
|
||||
{
|
||||
if constexpr (Num == 0) {
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
} else {
|
||||
return magnitude<
|
||||
return unit_magnitude<
|
||||
detail::power_v_or_T<detail::get_base(Ms), detail::get_exponent(Ms) * detail::ratio{Num, Den}>()...>{};
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Magnitude numerator and denominator implementation.
|
||||
[[nodiscard]] friend consteval auto _numerator(magnitude)
|
||||
[[nodiscard]] friend consteval auto _numerator(unit_magnitude)
|
||||
{
|
||||
return (detail::integer_part(magnitude<Ms>{}) * ... * magnitude<>{});
|
||||
return (detail::integer_part(unit_magnitude<Ms>{}) * ... * unit_magnitude<>{});
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval auto _denominator(magnitude) { return _numerator(_pow<-1>(magnitude{})); }
|
||||
[[nodiscard]] friend consteval auto _denominator(unit_magnitude) { return _numerator(_pow<-1>(unit_magnitude{})); }
|
||||
|
||||
[[nodiscard]] friend consteval auto _remove_positive_powers(magnitude)
|
||||
[[nodiscard]] friend consteval auto _remove_positive_powers(unit_magnitude)
|
||||
{
|
||||
return (magnitude<>{} * ... * detail::remove_positive_power(magnitude<Ms>{}));
|
||||
return (unit_magnitude<>{} * ... * detail::remove_positive_power(unit_magnitude<Ms>{}));
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval auto _common_magnitude_type_impl(magnitude)
|
||||
[[nodiscard]] friend consteval auto _common_magnitude_type_impl(unit_magnitude)
|
||||
{
|
||||
return (std::intmax_t{} * ... * decltype(detail::get_base_value(Ms)){});
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval auto _extract_components(magnitude)
|
||||
[[nodiscard]] friend consteval auto _extract_components(unit_magnitude)
|
||||
{
|
||||
constexpr auto ratio = (magnitude<>{} * ... * detail::remove_mag_constants(magnitude<Ms>{}));
|
||||
if constexpr (ratio == magnitude{})
|
||||
return std::tuple{ratio, magnitude<>{}, magnitude<>{}};
|
||||
constexpr auto ratio = (unit_magnitude<>{} * ... * detail::remove_mag_constants(unit_magnitude<Ms>{}));
|
||||
if constexpr (ratio == unit_magnitude{})
|
||||
return std::tuple{ratio, unit_magnitude<>{}, unit_magnitude<>{}};
|
||||
else {
|
||||
constexpr auto num_constants = (magnitude<>{} * ... * detail::only_positive_mag_constants(magnitude<Ms>{}));
|
||||
constexpr auto den_constants = (magnitude<>{} * ... * detail::only_negative_mag_constants(magnitude<Ms>{}));
|
||||
constexpr auto num_constants =
|
||||
(unit_magnitude<>{} * ... * detail::only_positive_mag_constants(unit_magnitude<Ms>{}));
|
||||
constexpr auto den_constants =
|
||||
(unit_magnitude<>{} * ... * detail::only_negative_mag_constants(unit_magnitude<Ms>{}));
|
||||
return std::tuple{ratio, num_constants, den_constants};
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] friend consteval detail::ratio _get_power([[maybe_unused]] T base, magnitude)
|
||||
[[nodiscard]] friend consteval detail::ratio _get_power([[maybe_unused]] T base, unit_magnitude)
|
||||
{
|
||||
return ((detail::get_base_value(Ms) == base ? detail::get_exponent(Ms) : detail::ratio{0}) + ... +
|
||||
detail::ratio{0});
|
||||
}
|
||||
|
||||
[[nodiscard]] friend consteval std::intmax_t _extract_power_of_10(magnitude m)
|
||||
[[nodiscard]] friend consteval std::intmax_t _extract_power_of_10(unit_magnitude m)
|
||||
{
|
||||
const auto power_of_2 = _get_power(2, m);
|
||||
const auto power_of_5 = _get_power(5, m);
|
||||
@ -522,29 +535,29 @@ private:
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out>
|
||||
friend constexpr Out _magnitude_symbol(Out out, magnitude, const unit_symbol_formatting& fmt)
|
||||
friend constexpr Out _magnitude_symbol(Out out, unit_magnitude, const unit_symbol_formatting& fmt)
|
||||
{
|
||||
if constexpr (magnitude{} == magnitude<1>{}) {
|
||||
if constexpr (unit_magnitude{} == unit_magnitude<1>{}) {
|
||||
return out;
|
||||
} else {
|
||||
constexpr auto extract_res = _extract_components(magnitude{});
|
||||
constexpr Magnitude auto ratio = std::get<0>(extract_res);
|
||||
constexpr Magnitude auto num_constants = std::get<1>(extract_res);
|
||||
constexpr Magnitude auto den_constants = std::get<2>(extract_res);
|
||||
constexpr auto extract_res = _extract_components(unit_magnitude{});
|
||||
constexpr UnitMagnitude auto ratio = std::get<0>(extract_res);
|
||||
constexpr UnitMagnitude auto num_constants = std::get<1>(extract_res);
|
||||
constexpr UnitMagnitude auto den_constants = std::get<2>(extract_res);
|
||||
constexpr std::intmax_t exp10 = _extract_power_of_10(ratio);
|
||||
if constexpr (detail::abs(exp10) < 3) {
|
||||
// print the value as a regular number (without exponent)
|
||||
constexpr Magnitude auto num = _numerator(magnitude{});
|
||||
constexpr Magnitude auto den = _denominator(magnitude{});
|
||||
constexpr UnitMagnitude auto num = _numerator(unit_magnitude{});
|
||||
constexpr UnitMagnitude auto den = _denominator(unit_magnitude{});
|
||||
// TODO address the below
|
||||
static_assert(ratio == num / den, "Printing rational powers not yet supported");
|
||||
return detail::magnitude_symbol_impl<CharT, num, den, num_constants, den_constants, 0>(out, fmt);
|
||||
} else {
|
||||
// print the value as a number with exponent
|
||||
// if user wanted a regular number for this magnitude then probably a better scaled unit should be used
|
||||
constexpr Magnitude auto base = ratio / detail::mag_power_lazy<10, exp10>();
|
||||
constexpr Magnitude auto num = _numerator(base);
|
||||
constexpr Magnitude auto den = _denominator(base);
|
||||
constexpr UnitMagnitude auto base = ratio / detail::mag_power_lazy<10, exp10>();
|
||||
constexpr UnitMagnitude auto num = _numerator(base);
|
||||
constexpr UnitMagnitude auto den = _denominator(base);
|
||||
|
||||
// TODO address the below
|
||||
static_assert(base == num / den, "Printing rational powers not yet supported");
|
||||
@ -554,67 +567,73 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] consteval auto _common_magnitude(magnitude<>, Magnitude auto m) { return _remove_positive_powers(m); }
|
||||
[[nodiscard]] consteval auto _common_magnitude(Magnitude auto m, magnitude<>) { return _remove_positive_powers(m); }
|
||||
[[nodiscard]] consteval auto _common_magnitude(magnitude<> m, magnitude<>) { return m; }
|
||||
[[nodiscard]] consteval auto _common_magnitude(unit_magnitude<>, UnitMagnitude auto m)
|
||||
{
|
||||
return _remove_positive_powers(m);
|
||||
}
|
||||
[[nodiscard]] consteval auto _common_magnitude(UnitMagnitude auto m, unit_magnitude<>)
|
||||
{
|
||||
return _remove_positive_powers(m);
|
||||
}
|
||||
[[nodiscard]] consteval auto _common_magnitude(unit_magnitude<> m, unit_magnitude<>) { return m; }
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
// The largest integer which can be extracted from any magnitude with only a single basis vector.
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto integer_part(magnitude<M>)
|
||||
[[nodiscard]] consteval auto integer_part(unit_magnitude<M>)
|
||||
{
|
||||
constexpr auto power_num = get_exponent(M).num;
|
||||
constexpr auto power_den = get_exponent(M).den;
|
||||
|
||||
if constexpr (std::is_integral_v<decltype(get_base(M))> && (power_num >= power_den)) {
|
||||
// largest integer power
|
||||
return magnitude<power_v_or_T<get_base(M), power_num / power_den>()>{}; // Note: integer division intended
|
||||
return unit_magnitude<power_v_or_T<get_base(M), power_num / power_den>()>{}; // Note: integer division intended
|
||||
} else {
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
}
|
||||
}
|
||||
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto remove_positive_power(magnitude<M> m)
|
||||
[[nodiscard]] consteval auto remove_positive_power(unit_magnitude<M> m)
|
||||
{
|
||||
if constexpr (get_exponent(M).num < 0) {
|
||||
return m;
|
||||
} else {
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
}
|
||||
}
|
||||
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto remove_mag_constants(magnitude<M> m)
|
||||
[[nodiscard]] consteval auto remove_mag_constants(unit_magnitude<M> m)
|
||||
{
|
||||
if constexpr (MagConstant<decltype(get_base(M))>)
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
else
|
||||
return m;
|
||||
}
|
||||
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto only_positive_mag_constants(magnitude<M> m)
|
||||
[[nodiscard]] consteval auto only_positive_mag_constants(unit_magnitude<M> m)
|
||||
{
|
||||
if constexpr (MagConstant<decltype(get_base(M))> && get_exponent(M) >= 0)
|
||||
return m;
|
||||
else
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
}
|
||||
|
||||
template<auto M>
|
||||
[[nodiscard]] consteval auto only_negative_mag_constants(magnitude<M> m)
|
||||
[[nodiscard]] consteval auto only_negative_mag_constants(unit_magnitude<M> m)
|
||||
{
|
||||
if constexpr (MagConstant<decltype(get_base(M))> && get_exponent(M) < 0)
|
||||
return m;
|
||||
else
|
||||
return magnitude<>{};
|
||||
return unit_magnitude<>{};
|
||||
}
|
||||
|
||||
// Returns the most precise type to express the magnitude factor
|
||||
template<Magnitude auto M>
|
||||
template<UnitMagnitude auto M>
|
||||
using common_magnitude_type = decltype(_common_magnitude_type_impl(M));
|
||||
|
||||
} // namespace detail
|
||||
@ -643,23 +662,23 @@ struct prime_factorization {
|
||||
static constexpr std::intmax_t remainder = remove_power(first_base, first_power, N);
|
||||
|
||||
static constexpr auto value =
|
||||
magnitude<power_v_or_T<first_base, ratio{first_power}>()>{} * prime_factorization<remainder>::value;
|
||||
unit_magnitude<power_v_or_T<first_base, ratio{first_power}>()>{} * prime_factorization<remainder>::value;
|
||||
};
|
||||
|
||||
// Specialization for the prime factorization of 1 (base case).
|
||||
template<>
|
||||
struct prime_factorization<1> {
|
||||
static constexpr magnitude<> value{};
|
||||
static constexpr unit_magnitude<> value{};
|
||||
};
|
||||
|
||||
template<std::intmax_t N>
|
||||
constexpr auto prime_factorization_v = prime_factorization<N>::value;
|
||||
|
||||
template<MagArg auto V>
|
||||
[[nodiscard]] consteval Magnitude auto make_magnitude()
|
||||
[[nodiscard]] consteval UnitMagnitude auto make_magnitude()
|
||||
{
|
||||
if constexpr (MagConstant<MP_UNITS_REMOVE_CONST(decltype(V))>)
|
||||
return magnitude<V>{};
|
||||
return unit_magnitude<V>{};
|
||||
else
|
||||
return prime_factorization_v<V>;
|
||||
}
|
||||
@ -670,18 +689,18 @@ MP_UNITS_EXPORT_BEGIN
|
||||
|
||||
template<detail::MagArg auto V>
|
||||
requires(detail::get_base_value(V) > 0)
|
||||
constexpr Magnitude auto mag = detail::make_magnitude<V>();
|
||||
constexpr UnitMagnitude auto mag = detail::make_magnitude<V>();
|
||||
|
||||
template<std::intmax_t N, std::intmax_t D>
|
||||
requires detail::gt_zero<N>
|
||||
constexpr Magnitude auto mag_ratio = detail::prime_factorization_v<N> / detail::prime_factorization_v<D>;
|
||||
constexpr UnitMagnitude auto mag_ratio = detail::prime_factorization_v<N> / detail::prime_factorization_v<D>;
|
||||
|
||||
/**
|
||||
* @brief Create a Magnitude which is some rational number raised to a rational power.
|
||||
*/
|
||||
template<detail::MagArg auto Base, int Num, int Den = 1>
|
||||
requires(detail::get_base_value(Base) > 0)
|
||||
constexpr Magnitude auto mag_power = _pow<Num, Den>(mag<Base>);
|
||||
constexpr UnitMagnitude auto mag_power = _pow<Num, Den>(mag<Base>);
|
||||
|
||||
/**
|
||||
* @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number.
|
||||
@ -696,16 +715,16 @@ inline constexpr struct pi final :
|
||||
} pi;
|
||||
inline constexpr auto π /* U+03C0 GREEK SMALL LETTER PI */ = pi;
|
||||
|
||||
[[deprecated("Use `mag<pi>` instead")]] inline constexpr Magnitude auto mag_pi = mag<pi>;
|
||||
[[deprecated("Use `mag<pi>` instead")]] inline constexpr UnitMagnitude auto mag_pi = mag<pi>;
|
||||
|
||||
MP_UNITS_EXPORT_END
|
||||
|
||||
namespace detail {
|
||||
|
||||
// This is introduced to break the dependency cycle between `magnitude::_magnitude_text` and `prime_factorization`
|
||||
// This is introduced to break the dependency cycle between `unit_magnitude::_magnitude_text` and `prime_factorization`
|
||||
template<MagArg auto Base, int Num, int Den>
|
||||
requires(detail::get_base_value(Base) > 0)
|
||||
[[nodiscard]] consteval Magnitude auto mag_power_lazy()
|
||||
[[nodiscard]] consteval UnitMagnitude auto mag_power_lazy()
|
||||
{
|
||||
return _pow<Num, Den>(mag<Base>);
|
||||
}
|
@ -50,12 +50,12 @@ MP_UNITS_EXPORT template<typename T>
|
||||
concept MagConstant = detail::SymbolicConstant<T> && is_derived_from_specialization_of_v<T, mag_constant>;
|
||||
|
||||
template<auto... Ms>
|
||||
struct magnitude;
|
||||
struct unit_magnitude;
|
||||
|
||||
/**
|
||||
* @brief Concept to detect whether T is a valid Magnitude.
|
||||
* @brief Concept to detect whether T is a valid UnitMagnitude.
|
||||
*/
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
concept Magnitude = is_specialization_of_v<T, magnitude>;
|
||||
concept UnitMagnitude = is_specialization_of_v<T, unit_magnitude>;
|
||||
|
||||
} // namespace mp_units
|
@ -122,7 +122,7 @@ struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::durati
|
||||
|
||||
namespace detail {
|
||||
|
||||
[[nodiscard]] constexpr auto as_ratio(Magnitude auto m)
|
||||
[[nodiscard]] constexpr auto as_ratio(UnitMagnitude auto m)
|
||||
requires(_is_rational(m))
|
||||
{
|
||||
return std::ratio<_get_value<std::intmax_t>(_numerator(m)), _get_value<std::intmax_t>(_denominator(m))>{};
|
||||
|
@ -47,7 +47,6 @@ add_library(
|
||||
international_test.cpp
|
||||
isq_test.cpp
|
||||
isq_angle_test.cpp
|
||||
# magnitude_test.cpp
|
||||
natural_test.cpp
|
||||
prime_test.cpp
|
||||
quantity_point_test.cpp
|
||||
@ -58,8 +57,9 @@ add_library(
|
||||
symbol_text_test.cpp
|
||||
type_list_test.cpp
|
||||
typographic_test.cpp
|
||||
unit_test.cpp
|
||||
# unit_magnitude_test.cpp
|
||||
unit_symbol_test.cpp
|
||||
unit_test.cpp
|
||||
usc_test.cpp
|
||||
)
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
#ifdef MP_UNITS_MODULES
|
||||
import mp_units;
|
||||
#else
|
||||
#include <units/bits/magnitude.h>
|
||||
#include <units/bits/ratio.h>
|
||||
#include <units/bits/unit_magnitude.h>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
@ -60,7 +60,7 @@ namespace {
|
||||
// template<ratio R>
|
||||
// void check_ratio_round_trip_is_identity()
|
||||
// {
|
||||
// constexpr Magnitude auto m = mag<R>();
|
||||
// constexpr UnitMagnitude auto m = mag<R>();
|
||||
// constexpr ratio round_trip = ratio{
|
||||
// get_value<std::intmax_t>(numerator(m)),
|
||||
// get_value<std::intmax_t>(denominator(m)),
|
||||
@ -68,16 +68,16 @@ namespace {
|
||||
// CHECK(round_trip == R);
|
||||
// }
|
||||
|
||||
inline constexpr struct mag_2_ : magnitude<2> {
|
||||
inline constexpr struct mag_2_ : unit_magnitude<2> {
|
||||
} mag_2;
|
||||
// inline constexpr struct mag_2_other : magnitude<2> {
|
||||
// inline constexpr struct mag_2_other : unit_magnitude<2> {
|
||||
// } mag_2_other;
|
||||
// inline constexpr struct mag_3 : magnitude<2> {
|
||||
// inline constexpr struct mag_3 : unit_magnitude<2> {
|
||||
// } mag_3;
|
||||
|
||||
// concepts verification
|
||||
static_assert(Magnitude<decltype(mag<2>)>);
|
||||
static_assert(Magnitude<mag_2_>);
|
||||
static_assert(UnitMagnitude<decltype(mag<2>)>);
|
||||
static_assert(UnitMagnitude<mag_2_>);
|
||||
|
||||
// is_named_magnitude
|
||||
static_assert(!is_named_magnitude<decltype(mag<2>)>);
|
||||
@ -162,15 +162,15 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
// {
|
||||
// SECTION("Performs prime factorization when denominator is 1")
|
||||
// {
|
||||
// CHECK(mag<1>() == magnitude<>{});
|
||||
// CHECK(mag<2>() == magnitude<base_power{2}>{});
|
||||
// CHECK(mag<3>() == magnitude<base_power{3}>{});
|
||||
// CHECK(mag<4>() == magnitude<base_power{2, 2}>{});
|
||||
// CHECK(mag<1>() == unit_magnitude<>{});
|
||||
// CHECK(mag<2>() == unit_magnitude<base_power{2}>{});
|
||||
// CHECK(mag<3>() == unit_magnitude<base_power{3}>{});
|
||||
// CHECK(mag<4>() == unit_magnitude<base_power{2, 2}>{});
|
||||
|
||||
// CHECK(mag<792>() == magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{});
|
||||
// CHECK(mag<792>() == unit_magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{});
|
||||
// }
|
||||
|
||||
// SECTION("Supports fractions") { CHECK(mag_ratio<5, 8>() == magnitude<base_power{2, -3}, base_power{5}>{}); }
|
||||
// SECTION("Supports fractions") { CHECK(mag_ratio<5, 8>() == unit_magnitude<base_power{2, -3}, base_power{5}>{}); }
|
||||
|
||||
// SECTION("Can handle prime factor which would be large enough to overflow int")
|
||||
// {
|
||||
@ -179,7 +179,7 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
// mag_ratio<16'605'390'666'050, 10'000'000'000'000>();
|
||||
// }
|
||||
|
||||
// TEST_CASE("magnitude converts to numerical value")
|
||||
// TEST_CASE("unit_magnitude converts to numerical value")
|
||||
// {
|
||||
// SECTION("Positive integer powers of integer bases give integer values")
|
||||
// {
|
||||
@ -267,14 +267,14 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
|
||||
// TEST_CASE("Multiplication works for magnitudes")
|
||||
// {
|
||||
// SECTION("Reciprocals reduce to null magnitude") { CHECK(mag_ratio<3, 4>() * mag_ratio<4, 3>() == mag<1>()); }
|
||||
// SECTION("Reciprocals reduce to null unit_magnitude") { CHECK(mag_ratio<3, 4>() * mag_ratio<4, 3>() == mag<1>()); }
|
||||
|
||||
// SECTION("Products work as expected") { CHECK(mag_ratio<4, 5>() * mag_ratio<4, 3>() == mag_ratio<16, 15>()); }
|
||||
|
||||
// SECTION("Products handle pi correctly")
|
||||
// {
|
||||
// CHECK(pi_to_the<1>() * mag_ratio<2, 3>() * pi_to_the<ratio{-1, 2}>() ==
|
||||
// magnitude<base_power{2}, base_power{3, -1}, base_power<pi_base>{ratio{1, 2}}>{});
|
||||
// unit_magnitude<base_power{2}, base_power{3, -1}, base_power<pi_base>{ratio{1, 2}}>{});
|
||||
// }
|
||||
|
||||
// SECTION("Supports constexpr")
|
||||
@ -307,7 +307,7 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
|
||||
// TEST_CASE("Division works for magnitudes")
|
||||
// {
|
||||
// SECTION("Dividing anything by itself reduces to null magnitude")
|
||||
// SECTION("Dividing anything by itself reduces to null unit_magnitude")
|
||||
// {
|
||||
// CHECK(mag_ratio<3, 4>() / mag_ratio<3, 4>() == mag<1>());
|
||||
// CHECK(mag<15>() / mag<15>() == mag<1>());
|
||||
@ -350,11 +350,11 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
// {
|
||||
// SECTION("Integer magnitudes are integral and rational")
|
||||
// {
|
||||
// auto check_rational_and_integral = [](Magnitude auto m) {
|
||||
// auto check_rational_and_integral = [](UnitMagnitude auto m) {
|
||||
// CHECK(is_integral(m));
|
||||
// CHECK(is_rational(m));
|
||||
// };
|
||||
// check_rational_and_integral(magnitude<>{});
|
||||
// check_rational_and_integral(unit_magnitude<>{});
|
||||
// check_rational_and_integral(mag<1>());
|
||||
// check_rational_and_integral(mag<3>());
|
||||
// check_rational_and_integral(mag<8>());
|
||||
@ -364,7 +364,7 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
|
||||
// SECTION("Fractional magnitudes are rational, but not integral")
|
||||
// {
|
||||
// auto check_rational_but_not_integral = [](Magnitude auto m) {
|
||||
// auto check_rational_but_not_integral = [](UnitMagnitude auto m) {
|
||||
// CHECK(!is_integral(m));
|
||||
// CHECK(is_rational(m));
|
||||
// };
|
||||
@ -373,7 +373,7 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
// }
|
||||
// }
|
||||
|
||||
// TEST_CASE("Constructing ratio from rational magnitude")
|
||||
// TEST_CASE("Constructing ratio from rational unit_magnitude")
|
||||
// {
|
||||
// SECTION("Round trip is identity")
|
||||
// {
|
||||
@ -427,27 +427,27 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
// {
|
||||
// SECTION("integer_part of non-integer base is identity magnitude")
|
||||
// {
|
||||
// CHECK(integer_part(pi_to_the<1>()) == magnitude<>{});
|
||||
// CHECK(integer_part(pi_to_the<-8>()) == magnitude<>{});
|
||||
// CHECK(integer_part(pi_to_the<ratio{3, 4}>()) == magnitude<>{});
|
||||
// CHECK(integer_part(pi_to_the<1>()) == unit_magnitude<>{});
|
||||
// CHECK(integer_part(pi_to_the<-8>()) == unit_magnitude<>{});
|
||||
// CHECK(integer_part(pi_to_the<ratio{3, 4}>()) == unit_magnitude<>{});
|
||||
// }
|
||||
|
||||
// SECTION("integer_part of integer base to negative power is identity magnitude")
|
||||
// {
|
||||
// CHECK(integer_part(magnitude<base_power{2, -8}>{}) == magnitude<>{});
|
||||
// CHECK(integer_part(magnitude<base_power{11, -1}>{}) == magnitude<>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{2, -8}>{}) == unit_magnitude<>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{11, -1}>{}) == unit_magnitude<>{});
|
||||
// }
|
||||
|
||||
// SECTION("integer_part of integer base to fractional power is identity magnitude")
|
||||
// {
|
||||
// CHECK(integer_part(magnitude<base_power{2, ratio{1, 2}}>{}) == magnitude<>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{2, ratio{1, 2}}>{}) == unit_magnitude<>{});
|
||||
// }
|
||||
|
||||
// SECTION("integer_part of integer base to power at least one takes integer part")
|
||||
// {
|
||||
// CHECK(integer_part(magnitude<base_power{2, 1}>{}) == magnitude<base_power{2, 1}>{});
|
||||
// CHECK(integer_part(magnitude<base_power{2, ratio{19, 10}}>{}) == magnitude<base_power{2, 1}>{});
|
||||
// CHECK(integer_part(magnitude<base_power{11, ratio{97, 9}}>{}) == magnitude<base_power{11, 10}>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{2, 1}>{}) == unit_magnitude<base_power{2, 1}>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{2, ratio{19, 10}}>{}) == unit_magnitude<base_power{2, 1}>{});
|
||||
// CHECK(integer_part(unit_magnitude<base_power{11, ratio{97, 9}}>{}) == unit_magnitude<base_power{11, 10}>{});
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -470,22 +470,22 @@ static_assert(std::is_same_v<decltype(get_base(power_v<mag_2, 5, 8>{})), mag_2_>
|
||||
|
||||
// TEST_CASE("Prime factorization")
|
||||
// {
|
||||
// SECTION("1 factors into the null magnitude") { CHECK(prime_factorization_v<1> == magnitude<>{}); }
|
||||
// SECTION("1 factors into the null unit_magnitude") { CHECK(prime_factorization_v<1> == unit_magnitude<>{}); }
|
||||
|
||||
// SECTION("Prime numbers factor into themselves")
|
||||
// {
|
||||
// CHECK(prime_factorization_v<2> == magnitude<base_power{2}>{});
|
||||
// CHECK(prime_factorization_v<3> == magnitude<base_power{3}>{});
|
||||
// CHECK(prime_factorization_v<5> == magnitude<base_power{5}>{});
|
||||
// CHECK(prime_factorization_v<7> == magnitude<base_power{7}>{});
|
||||
// CHECK(prime_factorization_v<11> == magnitude<base_power{11}>{});
|
||||
// CHECK(prime_factorization_v<2> == unit_magnitude<base_power{2}>{});
|
||||
// CHECK(prime_factorization_v<3> == unit_magnitude<base_power{3}>{});
|
||||
// CHECK(prime_factorization_v<5> == unit_magnitude<base_power{5}>{});
|
||||
// CHECK(prime_factorization_v<7> == unit_magnitude<base_power{7}>{});
|
||||
// CHECK(prime_factorization_v<11> == unit_magnitude<base_power{11}>{});
|
||||
|
||||
// CHECK(prime_factorization_v<41> == magnitude<base_power{41}>{});
|
||||
// CHECK(prime_factorization_v<41> == unit_magnitude<base_power{41}>{});
|
||||
// }
|
||||
|
||||
// SECTION("Prime factorization finds factors and multiplicities")
|
||||
// {
|
||||
// CHECK(prime_factorization_v<792> == magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{});
|
||||
// CHECK(prime_factorization_v<792> == unit_magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{});
|
||||
// }
|
||||
// }
|
||||
|
Reference in New Issue
Block a user