Feat: Overloads for floor and ceil accepting quantities (#314)

* feat: overloads for floor and ceil accepting quantities

* require same type for dim and rep

* be specific for msvc
This commit is contained in:
Markus Hofbauer
2021-11-15 12:23:28 +01:00
committed by GitHub
parent 3f28b55ab1
commit 50b9050d6b
3 changed files with 48 additions and 0 deletions

View File

@@ -187,6 +187,23 @@ template<Unit To, typename D, typename U, typename Rep>
} }
} }
/**
* @brief Overload of @c ::units::floor<Unit>() using the unit type of To
*
* @tparam q Quantity being the base of the operation
* @return Quantity The rounded quantity with unit type of quantity To
*/
template<Quantity To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr quantity<D, typename To::unit, Rep> floor(const quantity<D, U, Rep>& q) noexcept
requires std::same_as<typename To::dimension, D> &&
std::same_as<typename To::rep, Rep> &&
requires {
::units::floor<typename To::unit>(q);
}
{
return ::units::floor<typename To::unit>(q);
}
/** /**
* @brief Computes the smallest quantity with integer representation and unit type To with its number not less than q * @brief Computes the smallest quantity with integer representation and unit type To with its number not less than q
* *
@@ -227,4 +244,21 @@ template<Unit To, typename D, typename U, typename Rep>
} }
} }
/**
* @brief Overload of @c ::units::ceil<Unit>() using the unit type of To
*
* @tparam q Quantity being the base of the operation
* @return Quantity The rounded quantity with unit type of quantity To
*/
template<Quantity To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr quantity<D, typename To::unit, Rep> ceil(const quantity<D, U, Rep>& q) noexcept
requires std::same_as<typename To::dimension, D> &&
std::same_as<typename To::rep, Rep> &&
requires {
::units::ceil<typename To::unit>(q);
}
{
return ::units::ceil<typename To::unit>(q);
}
} // namespace units } // namespace units

View File

@@ -148,6 +148,10 @@ TEST_CASE("floor functions", "[floor]")
SECTION ("floor -999. milliseconds with target unit second should be -1 second") { SECTION ("floor -999. milliseconds with target unit second should be -1 second") {
REQUIRE(floor<si::second>(-999._q_ms) == -1_q_s); REQUIRE(floor<si::second>(-999._q_ms) == -1_q_s);
} }
SECTION ("floor 1 second with target quantity with unit type second should be 1 second") {
using showtime = si::time<si::second, int>;
REQUIRE(floor<showtime>(showtime::one()) == showtime::one());
}
} }
TEST_CASE("ceil functions", "[ceil]") TEST_CASE("ceil functions", "[ceil]")
@@ -189,6 +193,10 @@ TEST_CASE("ceil functions", "[ceil]")
SECTION ("ceil -999. milliseconds with target unit second should be 0 seconds") { SECTION ("ceil -999. milliseconds with target unit second should be 0 seconds") {
REQUIRE(ceil<si::second>(-999._q_ms) == 0_q_s); REQUIRE(ceil<si::second>(-999._q_ms) == 0_q_s);
} }
SECTION ("ceil 1 second with target quantity with unit type second should be 1 second") {
using showtime = si::time<si::second, int>;
REQUIRE(ceil<showtime>(showtime::one()) == showtime::one());
}
} }
TEMPLATE_TEST_CASE_SIG("pow<N>() implementation exponentiates values to power N", "[math][pow][exp]", TEMPLATE_TEST_CASE_SIG("pow<N>() implementation exponentiates values to power N", "[math][pow][exp]",

View File

@@ -78,6 +78,9 @@ static_assert(floor<si::second>(1999._q_ms) == 1_q_s);
static_assert(floor<si::second>(-1000._q_ms) == -1_q_s); static_assert(floor<si::second>(-1000._q_ms) == -1_q_s);
static_assert(floor<si::second>(-999._q_ms) == -1_q_s); static_assert(floor<si::second>(-999._q_ms) == -1_q_s);
// floor with quantity
static_assert(compare<decltype(floor<si::time<si::second>>(1_q_s)), decltype(1_q_s)>);
// ceil // ceil
// integral types // integral types
static_assert(compare<decltype(ceil<si::second>(1_q_s)), decltype(1_q_s)>); static_assert(compare<decltype(ceil<si::second>(1_q_s)), decltype(1_q_s)>);
@@ -97,6 +100,9 @@ static_assert(ceil<si::second>(1001._q_ms) == 2_q_s);
static_assert(ceil<si::second>(1999._q_ms) == 2_q_s); static_assert(ceil<si::second>(1999._q_ms) == 2_q_s);
static_assert(ceil<si::second>(-1000._q_ms) == -1_q_s); static_assert(ceil<si::second>(-1000._q_ms) == -1_q_s);
static_assert(ceil<si::second>(-999._q_ms) == 0_q_s); static_assert(ceil<si::second>(-999._q_ms) == 0_q_s);
// ceil with quantity
static_assert(compare<decltype(ceil<si::time<si::second>>(1_q_s)), decltype(1_q_s)>);
#endif #endif
} // namespace } // namespace