@@ -413,22 +413,22 @@ NEW_UNIT(Luminosity, candela, 0, 0, 0, 0, 0, 0, 1, 0);
413413NEW_UNIT (Moles, mol, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
414414
415415namespace units {
416- constexpr bool isNan ( double lhs) {
417- // Use the fact that NaN is not equal to itself
418- return lhs != lhs;
419- }
416+ // helper function for Quantity-Double compatibility
417+ template <isQuantity Q> constexpr double getInternal ( const Q& lhs) { return lhs. internal (); }
418+
419+ constexpr double getInternal ( double lhs) { return lhs; }
420420
421- template <isQuantity Q> constexpr bool isNan (const Q& lhs) { return isNan ( lhs. internal ()) ; }
421+ template <isArithmetic Q> constexpr bool isNan (const Q& lhs) { return lhs != lhs ; }
422422
423- template <isQuantity Q> constexpr Q abs (const Q& lhs) { return Q (std::abs (lhs. internal ( ))); }
423+ template <isArithmetic Q> constexpr Q abs (const Q& lhs) { return Q (std::abs (getInternal (lhs ))); }
424424
425- template <isQuantity Q, isQuantity R> constexpr Q max (const Q& lhs, const R& rhs)
425+ template <isArithmetic Q, isArithmetic R> constexpr Q max (const Q& lhs, const R& rhs)
426426 requires Isomorphic<Q, R>
427427{
428428 return (lhs > rhs ? lhs : rhs);
429429}
430430
431- template <isQuantity Q, isQuantity R> constexpr Q min (const Q& lhs, const R& rhs)
431+ template <isArithmetic Q, isArithmetic R> constexpr Q min (const Q& lhs, const R& rhs)
432432 requires Isomorphic<Q, R>
433433{
434434 return (lhs < rhs ? lhs : rhs);
@@ -440,73 +440,77 @@ constexpr double sgn(double lhs) {
440440 return lhs;
441441}
442442
443- template <isQuantity Q> constexpr double sgn (const Q& lhs) { return sgn (lhs.internal ()); }
443+ template <isArithmetic Q> constexpr double sgn (const Q& lhs) { return sgn (lhs.internal ()); }
444444
445- template <int R, isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<R>>> constexpr S pow (const Q& lhs) {
445+ template <int R, isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<R>>> constexpr S pow (const Q& lhs) {
446446 return S (std::pow (lhs.internal (), R));
447447}
448448
449- template <isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<2 >>> constexpr S square (const Q& lhs) {
449+ template <isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<2 >>> constexpr S square (const Q& lhs) {
450450 return pow<2 >(lhs);
451451}
452452
453- template <isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<3 >>> constexpr S cube (const Q& lhs) {
453+ template <isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<3 >>> constexpr S cube (const Q& lhs) {
454454 return pow<3 >(lhs);
455455}
456456
457- template <int R, isQuantity Q, isQuantity S = Rooted<Q, std::ratio<R>>> constexpr S root (const Q& lhs) {
457+ template <int R, isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<R>>> constexpr S root (const Q& lhs) {
458458 return S (std::pow (lhs.internal (), 1.0 / R));
459459}
460460
461- template <isQuantity Q, isQuantity S = Rooted<Q, std::ratio<2 >>> constexpr S sqrt (const Q& lhs) { return root<2 >(lhs); }
461+ template <isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<2 >>> constexpr S sqrt (const Q& lhs) {
462+ return root<2 >(lhs);
463+ }
462464
463- template <isQuantity Q, isQuantity S = Rooted<Q, std::ratio<3 >>> constexpr S cbrt (const Q& lhs) { return root<3 >(lhs); }
465+ template <isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<3 >>> constexpr S cbrt (const Q& lhs) {
466+ return root<3 >(lhs);
467+ }
464468
465- template <isQuantity Q, isQuantity R> constexpr Q hypot (const Q& lhs, const R& rhs)
469+ template <isArithmetic Q, isArithmetic R> constexpr Q hypot (const Q& lhs, const R& rhs)
466470 requires Isomorphic<Q, R>
467471{
468472 return Q (std::hypot (lhs.internal (), rhs.internal ()));
469473}
470474
471- template <isQuantity Q, isQuantity R> constexpr Q mod (const Q& lhs, const R& rhs) {
475+ template <isArithmetic Q, isArithmetic R> constexpr Q mod (const Q& lhs, const R& rhs) {
472476 return Q (std::fmod (lhs.internal (), rhs.internal ()));
473477}
474478
475- template <isQuantity Q, isQuantity R> constexpr Q remainder (const Q& lhs, const R& rhs) {
479+ template <isArithmetic Q, isArithmetic R> constexpr Q remainder (const Q& lhs, const R& rhs) {
476480 return Q (std::remainder (lhs.internal (), rhs.internal ()));
477481}
478482
479- template <isQuantity Q1, isQuantity Q2> constexpr Q1 copysign (const Q1& lhs, const Q2& rhs) {
483+ template <isArithmetic Q1, isArithmetic Q2> constexpr Q1 copysign (const Q1& lhs, const Q2& rhs) {
480484 return Q1 (std::copysign (lhs.internal (), rhs.internal ()));
481485}
482486
483- template <isQuantity Q> constexpr bool signbit (const Q& lhs) { return std::signbit (lhs.internal ()); }
487+ template <isArithmetic Q> constexpr bool signbit (const Q& lhs) { return std::signbit (lhs.internal ()); }
484488
485- template <isQuantity Q, isQuantity R, isQuantity S> constexpr Q clamp (const Q& lhs, const R& lo, const S& hi)
489+ template <isArithmetic Q, isArithmetic R, isArithmetic S> constexpr Q clamp (const Q& lhs, const R& lo, const S& hi)
486490 requires Isomorphic<Q, R, S>
487491{
488492 return Q (std::clamp (lhs.internal (), lo.internal (), hi.internal ()));
489493}
490494
491- template <isQuantity Q, isQuantity R> constexpr Q ceil (const Q& lhs, const R& rhs)
495+ template <isArithmetic Q, isArithmetic R> constexpr Q ceil (const Q& lhs, const R& rhs)
492496 requires Isomorphic<Q, R>
493497{
494498 return Q (std::ceil (lhs.internal () / rhs.internal ()) * rhs.internal ());
495499}
496500
497- template <isQuantity Q, isQuantity R> constexpr Q floor (const Q& lhs, const R& rhs)
501+ template <isArithmetic Q, isArithmetic R> constexpr Q floor (const Q& lhs, const R& rhs)
498502 requires Isomorphic<Q, R>
499503{
500504 return Q (std::floor (lhs.internal () / rhs.internal ()) * rhs.internal ());
501505}
502506
503- template <isQuantity Q, isQuantity R> constexpr Q trunc (const Q& lhs, const R& rhs)
507+ template <isArithmetic Q, isArithmetic R> constexpr Q trunc (const Q& lhs, const R& rhs)
504508 requires Isomorphic<Q, R>
505509{
506510 return Q (std::trunc (lhs.internal () / rhs.internal ()) * rhs.internal ());
507511}
508512
509- template <isQuantity Q, isQuantity R> constexpr Q round (const Q& lhs, const R& rhs)
513+ template <isArithmetic Q, isArithmetic R> constexpr Q round (const Q& lhs, const R& rhs)
510514 requires Isomorphic<Q, R>
511515{
512516 return Q (std::round (lhs.internal () / rhs.internal ()) * rhs.internal ());
0 commit comments