@@ -292,13 +292,13 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
292292 return os; \
293293 } \
294294 constexpr inline Name from_##suffix(double value) { return Name (value); } \
295+ constexpr inline Name from_##suffix(Number value) { return Name (value.internal ()); } \
295296 constexpr inline double to_##suffix(Name quantity) { return quantity.internal (); }
296297
297298#define NEW_UNIT_LITERAL (Name, suffix, multiple ) \
298299 [[maybe_unused]] constexpr Name suffix = multiple; \
299300 constexpr Name operator " " _##suffix(long double value) { return static_cast <double >(value) * multiple; } \
300301 constexpr Name operator " " _##suffix(unsigned long long value) { return static_cast <double >(value) * multiple; } \
301- constexpr inline Name from_##suffix(double value) { return value * multiple; } \
302302 constexpr inline Name from_##suffix(Number value) { return value.internal () * multiple; } \
303303 constexpr inline double to_##suffix(Name quantity) { return quantity.convert (multiple); }
304304
@@ -312,8 +312,48 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
312312 NEW_UNIT_LITERAL(Name, u##base, base / 1E6 ) \
313313 NEW_UNIT_LITERAL(Name, n##base, base / 1E9 )
314314
315- NEW_UNIT(Number, num, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
316- 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+
330+ template <> struct LookupName <Quantity<std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >,
331+ std::ratio<0 >, std::ratio<0 >, std::ratio<0 >>> {
332+ using Named = Number;
333+ };
334+
335+ [[maybe_unused]] constexpr Number num = Number(1.0 );
336+
337+ constexpr Number operator " " _num(long double value) {
338+ return Number (Quantity<std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >,
339+ std::ratio<0 >, std::ratio<0 >>(static_cast <double >(value)));
340+ }
341+
342+ constexpr Number operator " " _num(unsigned long long value) {
343+ return Number (Quantity<std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >, std::ratio<0 >,
344+ std::ratio<0 >, std::ratio<0 >>(static_cast <double >(value)));
345+ }
346+
347+ inline std::ostream& operator <<(std::ostream& os, const Number& quantity) {
348+ os << quantity.internal () << " " << num;
349+ return os;
350+ }
351+
352+ constexpr inline Number from_num (double value) { return Number (value); }
353+
354+ constexpr inline double to_num (Number quantity) { return quantity.internal (); }
355+
356+ NEW_UNIT_LITERAL (Number, percent, num / 100 )
317357
318358NEW_UNIT(Mass, kg, 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
319359NEW_UNIT_LITERAL(Mass, g, kg / 1000 )
0 commit comments