Skip to content

Commit 04e3d08

Browse files
committed
fix: dimensionless quantitites truncation prevention fixed
1 parent c896e87 commit 04e3d08

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/core/include/mp-units/framework/quantity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ class quantity {
233233
{
234234
}
235235

236-
template<typename Value, Reference R2>
236+
template<typename Value>
237237
requires detail::ExplicitFromNumber<reference> && (!detail::ValuePreservingConstruction<rep, Value>)
238238
constexpr explicit(!std::convertible_to<Value, rep> || !implicitly_convertible(quantity_spec, dimensionless))
239239
quantity(Value val)

test/static/quantity_test.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,35 @@ static_assert(quantity<isq::length[m], double>::min().numerical_value_in(m) == s
183183
static_assert(quantity<isq::length[m], double>::max().numerical_value_in(m) == std::numeric_limits<double>::max());
184184

185185

186+
/////////////////////////////////////////////////
187+
// construction from value and a unit
188+
/////////////////////////////////////////////////
189+
190+
static_assert(std::constructible_from<quantity<si::metre>, double, struct si::metre>);
191+
static_assert(std::constructible_from<quantity<isq::length[m]>, double, decltype(isq::length[m])>);
192+
static_assert(std::constructible_from<quantity<si::metre>, double, si::kilo_<struct si::metre>>);
193+
static_assert(std::constructible_from<quantity<si::kilo<si::metre>>, double, struct si::metre>);
194+
195+
static_assert(std::constructible_from<quantity<si::metre, float>, double, struct si::metre>);
196+
static_assert(std::constructible_from<quantity<isq::length[m], float>, double, decltype(isq::length[m])>);
197+
static_assert(std::constructible_from<quantity<si::metre, float>, double, si::kilo_<struct si::metre>>);
198+
static_assert(std::constructible_from<quantity<si::kilo<si::metre>, float>, double, struct si::metre>);
199+
200+
static_assert(std::constructible_from<quantity<si::metre, int>, int, struct si::metre>);
201+
static_assert(std::constructible_from<quantity<isq::length[m], int>, int, decltype(isq::length[m])>);
202+
static_assert(std::constructible_from<quantity<si::metre, int>, int, si::kilo_<struct si::metre>>);
203+
static_assert(
204+
!std::constructible_from<quantity<si::kilo<si::metre>, int>, int, struct si::metre>); // truncating unit conversion
205+
206+
static_assert(std::constructible_from<quantity<si::metre>, int, struct si::metre>);
207+
static_assert(std::constructible_from<quantity<si::metre>, int, si::kilo_<struct si::metre>>);
208+
static_assert(std::constructible_from<quantity<si::kilo<si::metre>>, int, struct si::metre>);
209+
210+
// truncating representation conversion
211+
static_assert(!std::constructible_from<quantity<si::metre, int>, double, struct si::metre>);
212+
static_assert(!std::constructible_from<quantity<si::metre, int>, double, si::kilo_<struct si::metre>>);
213+
static_assert(!std::constructible_from<quantity<si::kilo<si::metre>, int>, double, struct si::metre>);
214+
186215
/////////////////////////////////////////////////
187216
// no construction from value (unless unit one)
188217
/////////////////////////////////////////////////
@@ -200,6 +229,9 @@ static_assert(std::convertible_to<double, quantity<one>>);
200229
static_assert(std::constructible_from<quantity<one>, int>);
201230
static_assert(std::convertible_to<int, quantity<one>>);
202231

232+
static_assert(!std::constructible_from<quantity<one, int>, double>); // truncating
233+
static_assert(!std::convertible_to<double, quantity<one, int>>); // truncating
234+
203235
static_assert(std::constructible_from<quantity<dimensionless[one]>, double>);
204236
static_assert(std::convertible_to<double, quantity<dimensionless[one]>>);
205237

0 commit comments

Comments
 (0)