mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
refactor: 💥 SI-related trigonometric functions moved to the si
subnamespace
This commit is contained in:
@ -8,6 +8,7 @@
|
||||
- feat: `quantity_point` support added for `quantity_cast` and `value_cast`
|
||||
- feat: `value_cast<Unit, Representation>` added
|
||||
- (!) refactor: `zero_Fahrenheit` renamed to `zeroth_degree_Fahrenheit`
|
||||
- (!) refactor: SI-related trigonometric functions moved to the `si` subnamespace
|
||||
- refactor: `math.h` header file broke up to smaller pieces
|
||||
- refactor: math functions constraints refactored
|
||||
- fix: `QuantityLike` conversions required `Q::rep` instead of using one provided by `quantity_like_traits`
|
||||
|
@ -88,7 +88,7 @@ void print(const R& gliders)
|
||||
ratio,
|
||||
// TODO is it possible to make ADL work below (we need another set of trig
|
||||
// functions for strong angle in a different namespace)
|
||||
isq::asin(1 / ratio).force_in(si::degree));
|
||||
si::asin(1 / ratio).force_in(si::degree));
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ distance spherical_distance(position<T> from, position<T> to)
|
||||
using namespace mp_units;
|
||||
constexpr quantity earth_radius = 6'371 * isq::radius[si::kilo<si::metre>];
|
||||
|
||||
using isq::sin, isq::cos, isq::asin, isq::acos;
|
||||
using si::sin, si::cos, si::asin, si::acos;
|
||||
|
||||
const quantity from_lat = from.lat.quantity_from(equator);
|
||||
const quantity from_lon = from.lon.quantity_from(prime_meridian);
|
||||
|
@ -36,46 +36,46 @@
|
||||
|
||||
namespace mp_units::si {
|
||||
|
||||
template<ReferenceOf<angular_measure> auto R, typename Rep>
|
||||
template<ReferenceOf<isq::angular_measure> auto R, typename Rep>
|
||||
requires requires(Rep v) { sin(v); } || requires(Rep v) { std::sin(v); }
|
||||
[[nodiscard]] inline QuantityOf<dimensionless> auto sin(const quantity<R, Rep>& q) noexcept
|
||||
{
|
||||
using std::sin;
|
||||
if constexpr (!treat_as_floating_point<Rep>) {
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(sin(q.force_numerical_value_in(si::radian)));
|
||||
using rep = decltype(sin(q.force_numerical_value_in(radian)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{sin(value_cast<rep>(q).numerical_value_in(si::radian)), one};
|
||||
return quantity{sin(value_cast<rep>(q).numerical_value_in(radian)), one};
|
||||
} else
|
||||
return quantity{sin(q.numerical_value_in(si::radian)), one};
|
||||
return quantity{sin(q.numerical_value_in(radian)), one};
|
||||
}
|
||||
|
||||
template<ReferenceOf<angular_measure> auto R, typename Rep>
|
||||
template<ReferenceOf<isq::angular_measure> auto R, typename Rep>
|
||||
requires requires(Rep v) { cos(v); } || requires(Rep v) { std::cos(v); }
|
||||
[[nodiscard]] inline QuantityOf<dimensionless> auto cos(const quantity<R, Rep>& q) noexcept
|
||||
{
|
||||
using std::cos;
|
||||
if constexpr (!treat_as_floating_point<Rep>) {
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(cos(q.force_numerical_value_in(si::radian)));
|
||||
using rep = decltype(cos(q.force_numerical_value_in(radian)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{cos(value_cast<rep>(q).numerical_value_in(si::radian)), one};
|
||||
return quantity{cos(value_cast<rep>(q).numerical_value_in(radian)), one};
|
||||
} else
|
||||
return quantity{cos(q.numerical_value_in(si::radian)), one};
|
||||
return quantity{cos(q.numerical_value_in(radian)), one};
|
||||
}
|
||||
|
||||
template<ReferenceOf<angular_measure> auto R, typename Rep>
|
||||
template<ReferenceOf<isq::angular_measure> auto R, typename Rep>
|
||||
requires requires(Rep v) { tan(v); } || requires(Rep v) { std::tan(v); }
|
||||
[[nodiscard]] inline QuantityOf<dimensionless> auto tan(const quantity<R, Rep>& q) noexcept
|
||||
{
|
||||
using std::tan;
|
||||
if constexpr (!treat_as_floating_point<Rep>) {
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(tan(q.force_numerical_value_in(si::radian)));
|
||||
using rep = decltype(tan(q.force_numerical_value_in(radian)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{tan(value_cast<rep>(q).numerical_value_in(si::radian)), one};
|
||||
return quantity{tan(value_cast<rep>(q).numerical_value_in(radian)), one};
|
||||
} else
|
||||
return quantity{tan(q.numerical_value_in(si::radian)), one};
|
||||
return quantity{tan(q.numerical_value_in(radian)), one};
|
||||
}
|
||||
|
||||
template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
@ -87,9 +87,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(asin(q.force_numerical_value_in(one)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{asin(value_cast<rep>(q).numerical_value_in(one)), si::radian};
|
||||
return quantity{asin(value_cast<rep>(q).numerical_value_in(one)), radian};
|
||||
} else
|
||||
return quantity{asin(q.numerical_value_in(one)), si::radian};
|
||||
return quantity{asin(q.numerical_value_in(one)), radian};
|
||||
}
|
||||
|
||||
template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
@ -101,9 +101,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(acos(q.force_numerical_value_in(one)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{acos(value_cast<rep>(q).numerical_value_in(one)), si::radian};
|
||||
return quantity{acos(value_cast<rep>(q).numerical_value_in(one)), radian};
|
||||
} else
|
||||
return quantity{acos(q.numerical_value_in(one)), si::radian};
|
||||
return quantity{acos(q.numerical_value_in(one)), radian};
|
||||
}
|
||||
|
||||
template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
@ -115,9 +115,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
|
||||
// check what is the return type when called with the integral value
|
||||
using rep = decltype(atan(q.force_numerical_value_in(one)));
|
||||
// use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
|
||||
return quantity{atan(value_cast<rep>(q).numerical_value_in(one)), si::radian};
|
||||
return quantity{atan(value_cast<rep>(q).numerical_value_in(one)), radian};
|
||||
} else
|
||||
return quantity{atan(q.numerical_value_in(one)), si::radian};
|
||||
return quantity{atan(q.numerical_value_in(one)), radian};
|
||||
}
|
||||
|
||||
} // namespace mp_units::si
|
||||
|
@ -321,54 +321,54 @@ TEST_CASE("hypot functions", "[hypot]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ISQ trigonometric functions", "[trig][isq]")
|
||||
TEST_CASE("SI trigonometric functions", "[trig][si]")
|
||||
{
|
||||
SECTION("sin")
|
||||
{
|
||||
REQUIRE_THAT(isq::sin(0 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(isq::sin(90 * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(isq::sin(180 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(isq::sin(270 * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(si::sin(0 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::sin(90 * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(si::sin(180 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::sin(270 * deg), AlmostEquals(-1. * one));
|
||||
}
|
||||
|
||||
SECTION("cos")
|
||||
{
|
||||
REQUIRE_THAT(isq::cos(0 * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(isq::cos(90 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(isq::cos(180 * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(isq::cos(270 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::cos(0 * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(si::cos(90 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::cos(180 * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(si::cos(270 * deg), AlmostEquals(0. * one));
|
||||
}
|
||||
|
||||
SECTION("tan")
|
||||
{
|
||||
REQUIRE_THAT(isq::tan(0 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(isq::tan(45. * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(isq::tan(135. * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(isq::tan(180. * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::tan(0 * deg), AlmostEquals(0. * one));
|
||||
REQUIRE_THAT(si::tan(45. * deg), AlmostEquals(1. * one));
|
||||
REQUIRE_THAT(si::tan(135. * deg), AlmostEquals(-1. * one));
|
||||
REQUIRE_THAT(si::tan(180. * deg), AlmostEquals(0. * one));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ISQ inverse trigonometric functions", "[inv trig][isq]")
|
||||
TEST_CASE("SI inverse trigonometric functions", "[inv trig][si]")
|
||||
{
|
||||
SECTION("asin")
|
||||
{
|
||||
REQUIRE_THAT(isq::asin(-1 * one), AlmostEquals(-90. * deg));
|
||||
REQUIRE_THAT(isq::asin(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(isq::asin(1 * one), AlmostEquals(90. * deg));
|
||||
REQUIRE_THAT(si::asin(-1 * one), AlmostEquals(-90. * deg));
|
||||
REQUIRE_THAT(si::asin(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(si::asin(1 * one), AlmostEquals(90. * deg));
|
||||
}
|
||||
|
||||
SECTION("acos")
|
||||
{
|
||||
REQUIRE_THAT(isq::asin(-1 * one), AlmostEquals(-90. * deg));
|
||||
REQUIRE_THAT(isq::asin(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(isq::asin(1 * one), AlmostEquals(90. * deg));
|
||||
REQUIRE_THAT(si::asin(-1 * one), AlmostEquals(-90. * deg));
|
||||
REQUIRE_THAT(si::asin(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(si::asin(1 * one), AlmostEquals(90. * deg));
|
||||
}
|
||||
|
||||
SECTION("atan")
|
||||
{
|
||||
REQUIRE_THAT(isq::atan(-1 * one), AlmostEquals(-45. * deg));
|
||||
REQUIRE_THAT(isq::atan(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(isq::atan(1 * one), AlmostEquals(45. * deg));
|
||||
REQUIRE_THAT(si::atan(-1 * one), AlmostEquals(-45. * deg));
|
||||
REQUIRE_THAT(si::atan(0 * one), AlmostEquals(0. * deg));
|
||||
REQUIRE_THAT(si::atan(1 * one), AlmostEquals(45. * deg));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user