mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-05 13:14:29 +02:00
test: compile quantity_test.cpp with -DUNITS_DOWNCAST_MODE=0
This commit is contained in:
committed by
Mateusz Pusz
parent
b18061ab0e
commit
3002c5673d
2
src/include/units/bits/external/hacks.h
vendored
2
src/include/units/bits/external/hacks.h
vendored
@@ -60,7 +60,7 @@ namespace std {
|
|||||||
template<class T>
|
template<class T>
|
||||||
concept default_constructible = constructible_from<T>;
|
concept default_constructible = constructible_from<T>;
|
||||||
|
|
||||||
#elif COMP_CLANG
|
#elif !COMP_CLANG
|
||||||
|
|
||||||
// concepts
|
// concepts
|
||||||
using concepts::three_way_comparable;
|
using concepts::three_way_comparable;
|
||||||
|
@@ -82,9 +82,10 @@ struct one_rep {
|
|||||||
template<QuantityValue Rep>
|
template<QuantityValue Rep>
|
||||||
[[nodiscard]] friend constexpr Rep operator/(one_rep, const Rep&) = delete;
|
[[nodiscard]] friend constexpr Rep operator/(one_rep, const Rep&) = delete;
|
||||||
|
|
||||||
template<QuantityValue Rep>
|
template<typename Rep>
|
||||||
[[nodiscard]] constexpr operator Rep() const noexcept
|
[[nodiscard]] constexpr operator Rep() const noexcept
|
||||||
{
|
{
|
||||||
|
static_assert(QuantityValue<Rep>);
|
||||||
return quantity_values<Rep>::one();
|
return quantity_values<Rep>::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ template<typename QFrom, typename QTo>
|
|||||||
concept harmonic_ = // exposition only
|
concept harmonic_ = // exposition only
|
||||||
Quantity<QFrom> &&
|
Quantity<QFrom> &&
|
||||||
Quantity<QTo> &&
|
Quantity<QTo> &&
|
||||||
requires(QFrom from, QTo to) { requires is_integral(detail::quantity_ratio(from) / detail::quantity_ratio(to)); };
|
is_integral(detail::quantity_ratio<QFrom> / detail::quantity_ratio<QTo>);
|
||||||
|
|
||||||
template<typename QFrom, typename QTo>
|
template<typename QFrom, typename QTo>
|
||||||
concept safe_castable_to_ = // exposition only
|
concept safe_castable_to_ = // exposition only
|
||||||
@@ -136,6 +136,11 @@ public:
|
|||||||
constexpr explicit(!(is_same_v<dimension, dim_one> && is_same_v<unit, ::units::one>))
|
constexpr explicit(!(is_same_v<dimension, dim_one> && is_same_v<unit, ::units::one>))
|
||||||
quantity(const Value& v) : value_(v) {}
|
quantity(const Value& v) : value_(v) {}
|
||||||
|
|
||||||
|
template<safe_convertible_to_<rep> Value>
|
||||||
|
requires is_same_v<dimension, unknown_dimension<>>
|
||||||
|
constexpr explicit(!(is_same_v<dimension, unknown_dimension<>> && unit::ratio == ratio{1, 1, 0}))
|
||||||
|
quantity(const Value& v) : value_(v) {}
|
||||||
|
|
||||||
template<safe_castable_to_<quantity> Q>
|
template<safe_castable_to_<quantity> Q>
|
||||||
constexpr explicit(false) quantity(const Q& q) : value_(quantity_cast<quantity>(q).count()) {}
|
constexpr explicit(false) quantity(const Q& q) : value_(quantity_cast<quantity>(q).count()) {}
|
||||||
|
|
||||||
@@ -269,30 +274,30 @@ public:
|
|||||||
// Below friend functions are to be found via argument-dependent lookup only
|
// Below friend functions are to be found via argument-dependent lookup only
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
[[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const Value& rhs)
|
[[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const Value& rhs)
|
||||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>;
|
||||||
invoke_result_convertible_to_<rep, std::plus<>, rep, Value>
|
requires invoke_result_convertible_to_<rep, std::plus<>, rep, Value>; }
|
||||||
{
|
{
|
||||||
return units::quantity(lhs.count() + rhs);
|
return units::quantity(lhs.count() + rhs);
|
||||||
}
|
}
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
[[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const quantity& rhs)
|
[[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const quantity& rhs)
|
||||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>;
|
||||||
invoke_result_convertible_to_<rep, std::plus<>, Value, rep>
|
requires invoke_result_convertible_to_<rep, std::plus<>, Value, rep>; }
|
||||||
{
|
{
|
||||||
return units::quantity(lhs + rhs.count());
|
return units::quantity(lhs + rhs.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const Value& rhs)
|
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const Value& rhs)
|
||||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>;
|
||||||
invoke_result_convertible_to_<rep, std::minus<>, rep, Value>
|
requires invoke_result_convertible_to_<rep, std::minus<>, rep, Value>; }
|
||||||
{
|
{
|
||||||
return units::quantity(lhs.count() - rhs);
|
return units::quantity(lhs.count() - rhs);
|
||||||
}
|
}
|
||||||
template<typename Value>
|
template<typename Value>
|
||||||
[[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const quantity& rhs)
|
[[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const quantity& rhs)
|
||||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>;
|
||||||
invoke_result_convertible_to_<rep, std::minus<>, Value, rep>
|
requires invoke_result_convertible_to_<rep, std::minus<>, Value, rep>; }
|
||||||
{
|
{
|
||||||
return units::quantity(lhs - rhs.count());
|
return units::quantity(lhs - rhs.count());
|
||||||
}
|
}
|
||||||
|
@@ -50,8 +50,11 @@ class quantity_point_kind;
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr ratio quantity_ratio = std::enable_if_t<!Quantity<T>>{};
|
||||||
|
|
||||||
template<typename D, typename U, typename Rep>
|
template<typename D, typename U, typename Rep>
|
||||||
constexpr auto quantity_ratio(const quantity<D, U, Rep>&)
|
inline constexpr ratio quantity_ratio<quantity<D, U, Rep>> = []
|
||||||
{
|
{
|
||||||
if constexpr(BaseDimension<D>) {
|
if constexpr(BaseDimension<D>) {
|
||||||
return U::ratio;
|
return U::ratio;
|
||||||
@@ -59,18 +62,18 @@ constexpr auto quantity_ratio(const quantity<D, U, Rep>&)
|
|||||||
else {
|
else {
|
||||||
return D::base_units_ratio * U::ratio / D::coherent_unit::ratio;
|
return D::base_units_ratio * U::ratio / D::coherent_unit::ratio;
|
||||||
}
|
}
|
||||||
}
|
}();
|
||||||
|
|
||||||
template<typename Q1, typename Q2>
|
template<typename QFrom, typename QTo>
|
||||||
constexpr ratio cast_ratio(const Q1& from, const Q2& to)
|
constexpr ratio cast_ratio(const QFrom& from, const QTo& to)
|
||||||
{
|
{
|
||||||
using FromU = TYPENAME Q1::unit;
|
using FromU = TYPENAME QFrom::unit;
|
||||||
using ToU = TYPENAME Q2::unit;
|
using ToU = TYPENAME QTo::unit;
|
||||||
if constexpr(same_unit_reference<FromU, ToU>::value) {
|
if constexpr(same_unit_reference<FromU, ToU>::value) {
|
||||||
return FromU::ratio / ToU::ratio;
|
return FromU::ratio / ToU::ratio;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return quantity_ratio(from) / quantity_ratio(to);
|
return quantity_ratio<QFrom> / quantity_ratio<QTo>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,11 @@ using namespace unit_constants;
|
|||||||
|
|
||||||
constexpr auto cgs_cm = cgs::unit_constants::cm;
|
constexpr auto cgs_cm = cgs::unit_constants::cm;
|
||||||
|
|
||||||
|
#if UNITS_DOWNCAST_MODE == 0
|
||||||
|
template<typename T, typename U>
|
||||||
|
constexpr bool is_same_v = equivalent<T, U>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// quantity class invariants
|
// quantity class invariants
|
||||||
@@ -743,7 +748,7 @@ static_assert(quantity_cast<dim_speed, kilometre_per_hour>(2000.0_q_m / 3600.0_q
|
|||||||
static_assert(quantity_cast<dim_length>(1 * cgs_cm) == 1 * cm);
|
static_assert(quantity_cast<dim_length>(1 * cgs_cm) == 1 * cm);
|
||||||
|
|
||||||
static_assert(is_same_v<decltype(quantity_cast<litre>(2_q_dm3)), volume<litre, std::int64_t>>);
|
static_assert(is_same_v<decltype(quantity_cast<litre>(2_q_dm3)), volume<litre, std::int64_t>>);
|
||||||
static_assert(!is_same_v<decltype(quantity_cast<litre>(2_q_dm3)), volume<cubic_decimetre, std::int64_t>>);
|
static_assert(!std::same_as<decltype(quantity_cast<litre>(2_q_dm3)), volume<cubic_decimetre, std::int64_t>>);
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// downcasting
|
// downcasting
|
||||||
|
@@ -45,8 +45,10 @@ constexpr bool constructible_from(Vs...) {
|
|||||||
return std::constructible_from<T, Us..., Vs...>;
|
return std::constructible_from<T, Us..., Vs...>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> void convertible_from__(T);
|
||||||
|
|
||||||
template<typename T, typename... Us>
|
template<typename T, typename... Us>
|
||||||
concept convertible_from_ = requires(Us... us) { [](T) {}({us...}); };
|
concept convertible_from_ = requires(Us... us) { convertible_from__<T>({us...}); };
|
||||||
|
|
||||||
template<typename T, typename... Us, typename... Vs>
|
template<typename T, typename... Us, typename... Vs>
|
||||||
constexpr bool convertible_from(Vs...) {
|
constexpr bool convertible_from(Vs...) {
|
||||||
|
Reference in New Issue
Block a user