operator% constrained to integral types only (resolves #16)

This commit is contained in:
Mateusz Pusz
2019-10-01 16:29:13 +02:00
parent 56679498b7
commit 12200f6f40
3 changed files with 22 additions and 7 deletions

View File

@@ -377,12 +377,17 @@ public:
Additional functions provide the support for operations that result in a different dimension type
than those of their arguments.
Another change comparing to `std::chrono::duration` is that the `duration` is using
`std::common_type_t<Rep1, Rep2>` to find a common representation for a calculation result. Such
a design was reported as problematic by numerics study group members as sometimes we want to provide
a different type in case of multiplication and different in case of division. `std::common_type` lacks
that additional information. That is why `units::quantity` uses the resulting type of a concrete operator
operation and provides it directly to `units::common_quantity_t` type trait.
Beside adding new elements a few other changes where applied compared to the `std::chrono::duration` class:
1. The `duration` is using `std::common_type_t<Rep1, Rep2>` to find a common representation
for a calculation result. Such a design was reported as problematic by numerics study group members
as sometimes we want to provide a different type in case of multiplication and different in case of
division. `std::common_type` lacks that additional information. That is why `units::quantity` uses
the resulting type of a concrete operator operation and provides it directly to `units::common_quantity_t`
type trait.
2. `operator %` is constrained with `treat_as_floating_point` type trait to limit the types to integral
representations only. Also `operator %(Rep)` takes `Rep` as a template argument to limit implicit
conversions.
#### `quantity_cast`

View File

@@ -242,13 +242,16 @@ namespace units {
return *this;
}
constexpr quantity& operator%=(const rep& rhs)
template<Scalar Rep2>
constexpr quantity& operator%=(const Rep2& rhs)
requires (!treat_as_floating_point<rep> && !treat_as_floating_point<Rep2>)
{
value_ %= rhs;
return *this;
}
constexpr quantity& operator%=(const quantity& q)
requires (!treat_as_floating_point<rep>)
{
value_ %= q.count();
return *this;

View File

@@ -187,6 +187,13 @@ namespace {
static_assert((2m /= 2).count() == 1);
static_assert((7m %= 2).count() == 1);
static_assert((7m %= 2m).count() == 1);
// static_assert((7.m %= 2.).count() == 1); // should not compile
// static_assert((7.m %= 2).count() == 1); // should not compile
// static_assert((7m %= 2.).count() == 1); // should not compile
static_assert((7m %= 2m).count() == 1);
// static_assert((7.m %= 2.m).count() == 1); // should not compile
// static_assert((7.m %= 2m).count() == 1); // should not compile
// static_assert((7m %= 2.m).count() == 1); // should not compile
// non-member arithmetic operators