Skip to content

Commit 6803b03

Browse files
committed
make Number implicitly convertible to and from any arithmetic type
1 parent 0e72c48 commit 6803b03

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

include/units/units.hpp

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
261261
return (lhs.internal() > rhs.internal());
262262
}
263263

264-
#define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n, ...) \
264+
#define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n) \
265265
class Name : public Quantity<std::ratio<m>, std::ratio<l>, std::ratio<t>, std::ratio<i>, std::ratio<a>, \
266266
std::ratio<o>, std::ratio<j>, std::ratio<n>> { \
267267
public: \
@@ -273,7 +273,6 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
273273
value) \
274274
: Quantity<std::ratio<m>, std::ratio<l>, std::ratio<t>, std::ratio<i>, std::ratio<a>, std::ratio<o>, \
275275
std::ratio<j>, std::ratio<n>>(value) {}; \
276-
__VA_ARGS__ \
277276
}; \
278277
template <> struct LookupName<Quantity<std::ratio<m>, std::ratio<l>, std::ratio<t>, std::ratio<i>, std::ratio<a>, \
279278
std::ratio<o>, std::ratio<j>, std::ratio<n>>> { \
@@ -313,8 +312,60 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
313312
NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \
314313
NEW_UNIT_LITERAL(Name, n##base, base / 1E9)
315314

316-
NEW_UNIT(Number, num, 0, 0, 0, 0, 0, 0, 0, 0, constexpr operator double() { return this->value; })
317-
NEW_UNIT_LITERAL(Number, percent, num / 100.0);
315+
/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */
316+
class Number : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
317+
std::ratio<0>, std::ratio<0>> {
318+
public:
319+
template <typename T> constexpr Number(T value)
320+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
321+
std::ratio<0>, std::ratio<0>>(double(value)) {}
322+
323+
constexpr Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
324+
std::ratio<0>, std::ratio<0>, std::ratio<0>>
325+
value)
326+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
327+
std::ratio<0>, std::ratio<0>>(value) {};
328+
329+
template <typename T> constexpr operator T() const { return T(value); }
330+
};
331+
332+
template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
333+
std::ratio<0>, std::ratio<0>, std::ratio<0>>> {
334+
using Named = Number;
335+
};
336+
337+
[[maybe_unused]] constexpr Number num = Number(1.0);
338+
339+
constexpr Number operator""_num(long double value) {
340+
return Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
341+
std::ratio<0>, std::ratio<0>>(static_cast<double>(value)));
342+
}
343+
344+
constexpr Number operator""_num(unsigned long long value) {
345+
return Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
346+
std::ratio<0>, std::ratio<0>>(static_cast<double>(value)));
347+
}
348+
349+
inline std::ostream& operator<<(std::ostream& os, const Number& quantity) {
350+
os << quantity.internal() << " " << num;
351+
return os;
352+
}
353+
354+
constexpr inline Number from_num(double value) { return Number(value); }
355+
356+
constexpr inline double to_num(Number quantity) { return quantity.internal(); }
357+
358+
[[maybe_unused]] constexpr Number percent = num / 100.0;
359+
360+
constexpr Number operator""_percent(long double value) { return value / 100.0; }
361+
362+
constexpr Number operator""_percent(unsigned long long value) { return value / 100.0; }
363+
364+
constexpr inline Number from_percent(double value) { return value / 100.0; }
365+
366+
constexpr inline Number from_percent(Number value) { return value / 100.0; }
367+
368+
constexpr inline double to_percent(Number quantity) { return quantity.internal() * 100.0; }
318369

319370
NEW_UNIT(Mass, kg, 1, 0, 0, 0, 0, 0, 0, 0)
320371
NEW_UNIT_LITERAL(Mass, g, kg / 1000)

src/main.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ void initialize() {
4747
Length z = toLinear<Angle>(y, 2_cm);
4848
static_assert(Angle(5.1) >= Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
4949
std::ratio<0>, std::ratio<0>, std::ratio<0>>(5.0));
50-
units::clamp(2_cDeg, a.theta(), Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
51-
std::ratio<0>, std::ratio<0>, std::ratio<0>>(5.0));
52-
units::max(10_celsius, Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>,
53-
std::ratio<0>, std::ratio<0>>(1.0));
50+
units::clamp(2_cDeg, a.theta(),
51+
Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>, std::ratio<0>,
52+
std::ratio<0>, std::ratio<0>>(5.0));
53+
units::max(10_celsius, Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
54+
std::ratio<1>, std::ratio<0>, std::ratio<0>>(1.0));
5455
}
5556

5657
/**

0 commit comments

Comments
 (0)