xo-unit: restore constexpr quantity*quantity
This commit is contained in:
parent
be24d649eb
commit
be67f55c79
5 changed files with 66 additions and 35 deletions
|
|
@ -78,28 +78,6 @@ namespace xo {
|
||||||
// divide_by
|
// divide_by
|
||||||
// divide_into
|
// divide_into
|
||||||
|
|
||||||
/* parallel implementation to Quantity<Repr, Int>,
|
|
||||||
* but return type will have dimension computed at compile-time
|
|
||||||
*/
|
|
||||||
template <typename Quantity2>
|
|
||||||
static constexpr auto multiply(const quantity & x, const Quantity2 & y) {
|
|
||||||
using r_repr_type = std::common_type_t<typename quantity::repr_type,
|
|
||||||
typename Quantity2::repr_type>;
|
|
||||||
using r_int_type = std::common_type_t<typename quantity::ratio_int_type,
|
|
||||||
typename Quantity2::ratio_int_type>;
|
|
||||||
using r_int2x_type = std::common_type_t<typename quantity::ratio_int2x_type,
|
|
||||||
typename Quantity2::ratio_int2x_type>;
|
|
||||||
|
|
||||||
constexpr auto rr = detail::su_product<r_int_type, r_int2x_type>(x.unit(), y.unit());
|
|
||||||
|
|
||||||
r_repr_type r_scale = (::sqrt(rr.outer_scale_sq_)
|
|
||||||
* rr.outer_scale_factor_.template convert_to<r_repr_type>()
|
|
||||||
* static_cast<r_repr_type>(x.scale())
|
|
||||||
* static_cast<r_repr_type>(y.scale()));
|
|
||||||
|
|
||||||
return quantity<r_repr_type, r_int_type, rr.natural_unit_, r_int2x_type>(r_scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// divide
|
// divide
|
||||||
// add
|
// add
|
||||||
// subtract
|
// subtract
|
||||||
|
|
@ -127,6 +105,53 @@ namespace xo {
|
||||||
Repr scale_ = Repr{};
|
Repr scale_ = Repr{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct quantity_util {
|
||||||
|
/* parallel implementation to Quantity<Repr, Int>,
|
||||||
|
* but return type will have dimension computed at compile-time
|
||||||
|
*/
|
||||||
|
template <typename Q1, typename Q2>
|
||||||
|
requires (quantity_concept<Q1>
|
||||||
|
&& quantity_concept<Q2>
|
||||||
|
&& Q1::always_constexpr_unit
|
||||||
|
&& Q2::always_constexpr_unit)
|
||||||
|
static constexpr auto multiply(Q1 x, Q2 y) {
|
||||||
|
using r_repr_type = std::common_type_t<typename Q1::repr_type,
|
||||||
|
typename Q2::repr_type>;
|
||||||
|
using r_int_type = std::common_type_t<typename Q1::ratio_int_type,
|
||||||
|
typename Q2::ratio_int_type>;
|
||||||
|
using r_int2x_type = std::common_type_t<typename Q1::ratio_int2x_type,
|
||||||
|
typename Q2::ratio_int2x_type>;
|
||||||
|
|
||||||
|
constexpr auto rr = detail::su_product<r_int_type, r_int2x_type>(x.unit(), y.unit());
|
||||||
|
|
||||||
|
r_repr_type r_scale = (((rr.outer_scale_sq_ == 1.0)
|
||||||
|
? 1.0
|
||||||
|
: ::sqrt(rr.outer_scale_sq_))
|
||||||
|
* rr.outer_scale_factor_.template convert_to<r_repr_type>()
|
||||||
|
* static_cast<r_repr_type>(x.scale())
|
||||||
|
* static_cast<r_repr_type>(y.scale()));
|
||||||
|
|
||||||
|
return quantity<r_repr_type,
|
||||||
|
r_int_type,
|
||||||
|
rr.natural_unit_,
|
||||||
|
r_int2x_type
|
||||||
|
>(r_scale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr)
|
||||||
|
**/
|
||||||
|
template <typename Q1, typename Q2>
|
||||||
|
requires (quantity_concept<Q1>
|
||||||
|
&& quantity_concept<Q2>
|
||||||
|
&& Q1::always_constexpr_unit
|
||||||
|
&& Q2::always_constexpr_unit)
|
||||||
|
constexpr auto
|
||||||
|
operator* (const Q1 & x, const Q2 & y)
|
||||||
|
{
|
||||||
|
return quantity_util::multiply(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
namespace qty {
|
namespace qty {
|
||||||
// ----- mass -----
|
// ----- mass -----
|
||||||
|
|
||||||
|
|
@ -179,6 +204,8 @@ namespace xo {
|
||||||
inline constexpr auto volatility_250d(double x) { return quantity<double, std::int64_t, nu::volatility_250d>(x); }
|
inline constexpr auto volatility_250d(double x) { return quantity<double, std::int64_t, nu::volatility_250d>(x); }
|
||||||
inline constexpr auto volatility_360d(double x) { return quantity<double, std::int64_t, nu::volatility_360d>(x); }
|
inline constexpr auto volatility_360d(double x) { return quantity<double, std::int64_t, nu::volatility_360d>(x); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reminder: see [quantity_ops.hpp] for operator* etc */
|
||||||
} /*namespace qty*/
|
} /*namespace qty*/
|
||||||
} /*namespace xo*/
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "quantity_concept.hpp"
|
#include "quantity_concept.hpp"
|
||||||
//#include <cstdint>
|
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
namespace qty {
|
namespace qty {
|
||||||
/** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr)
|
|
||||||
**/
|
|
||||||
template <typename Quantity, typename Quantity2>
|
|
||||||
requires quantity_concept<Quantity> && quantity_concept<Quantity2>
|
|
||||||
constexpr auto
|
|
||||||
operator* (const Quantity & x, const Quantity2 & y)
|
|
||||||
{
|
|
||||||
return Quantity::multiply(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** note: does not require unit scaling, so constexpr with c++23 **/
|
/** note: does not require unit scaling, so constexpr with c++23 **/
|
||||||
template <typename Dimensionless, typename Quantity>
|
template <typename Dimensionless, typename Quantity>
|
||||||
requires std::is_arithmetic_v<Dimensionless> && quantity_concept<Quantity>
|
requires std::is_arithmetic_v<Dimensionless> && quantity_concept<Quantity>
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ namespace xo {
|
||||||
|
|
||||||
constexpr auto nanogram = detail::make_unit_rescale_result<std::int64_t>(nu::nanogram);
|
constexpr auto nanogram = detail::make_unit_rescale_result<std::int64_t>(nu::nanogram);
|
||||||
constexpr auto microgram = detail::make_unit_rescale_result<std::int64_t>(nu::microgram);
|
constexpr auto microgram = detail::make_unit_rescale_result<std::int64_t>(nu::microgram);
|
||||||
|
|
||||||
|
constexpr auto millisecond = detail::make_unit_rescale_result<std::int64_t>(nu::millisecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,8 @@ namespace xo {
|
||||||
template <typename Repr = double,
|
template <typename Repr = double,
|
||||||
typename Int = std::int64_t>
|
typename Int = std::int64_t>
|
||||||
inline constexpr xquantity<Repr, Int>
|
inline constexpr xquantity<Repr, Int>
|
||||||
unit_qty(const scaled_unit<Int> & u) {
|
unit_qty(const scaled_unit<Int> & u)
|
||||||
|
{
|
||||||
return xquantity<Repr, Int>
|
return xquantity<Repr, Int>
|
||||||
(u.outer_scale_factor_.template convert_to<double>() * ::sqrt(u.outer_scale_sq_),
|
(u.outer_scale_factor_.template convert_to<double>() * ::sqrt(u.outer_scale_sq_),
|
||||||
u.natural_unit_);
|
u.natural_unit_);
|
||||||
|
|
@ -245,6 +246,18 @@ namespace xo {
|
||||||
return xquantity<Repr, Int>(1.0, nu);
|
return xquantity<Repr, Int>(1.0, nu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr)
|
||||||
|
**/
|
||||||
|
template <typename Q1, typename Q2>
|
||||||
|
requires (quantity_concept<Q1>
|
||||||
|
&& quantity_concept<Q2>
|
||||||
|
&& (!Q1::always_constexpr_unit || !Q2::always_constexpr_unit))
|
||||||
|
constexpr auto
|
||||||
|
operator* (const Q1 & x, const Q2 & y)
|
||||||
|
{
|
||||||
|
return Q1::multiply(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr)
|
/** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr)
|
||||||
**/
|
**/
|
||||||
template <typename Quantity, typename Quantity2>
|
template <typename Quantity, typename Quantity2>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "xo/unit/quantity.hpp"
|
#include "xo/unit/quantity.hpp"
|
||||||
#include "xo/unit/quantity_iostream.hpp"
|
#include "xo/unit/quantity_iostream.hpp"
|
||||||
#include "xo/unit/quantity2_concept.hpp"
|
#include "xo/unit/quantity_concept.hpp"
|
||||||
#include "xo/indentlog/scope.hpp"
|
#include "xo/indentlog/scope.hpp"
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue