@@ -413,22 +413,22 @@ NEW_UNIT(Luminosity, candela, 0, 0, 0, 0, 0, 0, 1, 0);
413
413
NEW_UNIT (Moles, mol, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
414
414
415
415
namespace units {
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; }
416
+ constexpr bool isNan ( double lhs) {
417
+ // Use the fact that NaN is not equal to itself
418
+ return lhs != lhs;
419
+ }
420
420
421
- template <isArithmetic Q> constexpr bool isNan (const Q& lhs) { return lhs != lhs ; }
421
+ template <isQuantity Q> constexpr bool isNan (const Q& lhs) { return isNan ( lhs. internal ()) ; }
422
422
423
- template <isArithmetic Q> constexpr Q abs (const Q& lhs) { return Q (std::abs (getInternal ( lhs))); }
423
+ template <isQuantity Q> constexpr Q abs (const Q& lhs) { return Q (std::abs (lhs. internal ( ))); }
424
424
425
- template <isArithmetic Q, isArithmetic R> constexpr Q max (const Q& lhs, const R& rhs)
425
+ template <isQuantity Q, isQuantity R> constexpr Q max (const Q& lhs, const R& rhs)
426
426
requires Isomorphic<Q, R>
427
427
{
428
428
return (lhs > rhs ? lhs : rhs);
429
429
}
430
430
431
- template <isArithmetic Q, isArithmetic R> constexpr Q min (const Q& lhs, const R& rhs)
431
+ template <isQuantity Q, isQuantity R> constexpr Q min (const Q& lhs, const R& rhs)
432
432
requires Isomorphic<Q, R>
433
433
{
434
434
return (lhs < rhs ? lhs : rhs);
@@ -440,77 +440,73 @@ constexpr double sgn(double lhs) {
440
440
return lhs;
441
441
}
442
442
443
- template <isArithmetic Q> constexpr double sgn (const Q& lhs) { return sgn (lhs.internal ()); }
443
+ template <isQuantity Q> constexpr double sgn (const Q& lhs) { return sgn (lhs.internal ()); }
444
444
445
- template <int R, isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<R>>> constexpr S pow (const Q& lhs) {
445
+ template <int R, isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<R>>> constexpr S pow (const Q& lhs) {
446
446
return S (std::pow (lhs.internal (), R));
447
447
}
448
448
449
- template <isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<2 >>> constexpr S square (const Q& lhs) {
449
+ template <isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<2 >>> constexpr S square (const Q& lhs) {
450
450
return pow<2 >(lhs);
451
451
}
452
452
453
- template <isArithmetic Q, isArithmetic S = Exponentiated<Q, std::ratio<3 >>> constexpr S cube (const Q& lhs) {
453
+ template <isQuantity Q, isQuantity S = Exponentiated<Q, std::ratio<3 >>> constexpr S cube (const Q& lhs) {
454
454
return pow<3 >(lhs);
455
455
}
456
456
457
- template <int R, isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<R>>> constexpr S root (const Q& lhs) {
457
+ template <int R, isQuantity Q, isQuantity S = Rooted<Q, std::ratio<R>>> constexpr S root (const Q& lhs) {
458
458
return S (std::pow (lhs.internal (), 1.0 / R));
459
459
}
460
460
461
- template <isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<2 >>> constexpr S sqrt (const Q& lhs) {
462
- return root<2 >(lhs);
463
- }
461
+ template <isQuantity Q, isQuantity S = Rooted<Q, std::ratio<2 >>> constexpr S sqrt (const Q& lhs) { return root<2 >(lhs); }
464
462
465
- template <isArithmetic Q, isArithmetic S = Rooted<Q, std::ratio<3 >>> constexpr S cbrt (const Q& lhs) {
466
- return root<3 >(lhs);
467
- }
463
+ template <isQuantity Q, isQuantity S = Rooted<Q, std::ratio<3 >>> constexpr S cbrt (const Q& lhs) { return root<3 >(lhs); }
468
464
469
- template <isArithmetic Q, isArithmetic R> constexpr Q hypot (const Q& lhs, const R& rhs)
465
+ template <isQuantity Q, isQuantity R> constexpr Q hypot (const Q& lhs, const R& rhs)
470
466
requires Isomorphic<Q, R>
471
467
{
472
468
return Q (std::hypot (lhs.internal (), rhs.internal ()));
473
469
}
474
470
475
- template <isArithmetic Q, isArithmetic R> constexpr Q mod (const Q& lhs, const R& rhs) {
471
+ template <isQuantity Q, isQuantity R> constexpr Q mod (const Q& lhs, const R& rhs) {
476
472
return Q (std::fmod (lhs.internal (), rhs.internal ()));
477
473
}
478
474
479
- template <isArithmetic Q, isArithmetic R> constexpr Q remainder (const Q& lhs, const R& rhs) {
475
+ template <isQuantity Q, isQuantity R> constexpr Q remainder (const Q& lhs, const R& rhs) {
480
476
return Q (std::remainder (lhs.internal (), rhs.internal ()));
481
477
}
482
478
483
- template <isArithmetic Q1, isArithmetic Q2> constexpr Q1 copysign (const Q1& lhs, const Q2& rhs) {
479
+ template <isQuantity Q1, isQuantity Q2> constexpr Q1 copysign (const Q1& lhs, const Q2& rhs) {
484
480
return Q1 (std::copysign (lhs.internal (), rhs.internal ()));
485
481
}
486
482
487
- template <isArithmetic Q> constexpr bool signbit (const Q& lhs) { return std::signbit (lhs.internal ()); }
483
+ template <isQuantity Q> constexpr bool signbit (const Q& lhs) { return std::signbit (lhs.internal ()); }
488
484
489
- template <isArithmetic Q, isArithmetic R, isArithmetic S> constexpr Q clamp (const Q& lhs, const R& lo, const S& hi)
485
+ template <isQuantity Q, isQuantity R, isQuantity S> constexpr Q clamp (const Q& lhs, const R& lo, const S& hi)
490
486
requires Isomorphic<Q, R, S>
491
487
{
492
488
return Q (std::clamp (lhs.internal (), lo.internal (), hi.internal ()));
493
489
}
494
490
495
- template <isArithmetic Q, isArithmetic R> constexpr Q ceil (const Q& lhs, const R& rhs)
491
+ template <isQuantity Q, isQuantity R> constexpr Q ceil (const Q& lhs, const R& rhs)
496
492
requires Isomorphic<Q, R>
497
493
{
498
494
return Q (std::ceil (lhs.internal () / rhs.internal ()) * rhs.internal ());
499
495
}
500
496
501
- template <isArithmetic Q, isArithmetic R> constexpr Q floor (const Q& lhs, const R& rhs)
497
+ template <isQuantity Q, isQuantity R> constexpr Q floor (const Q& lhs, const R& rhs)
502
498
requires Isomorphic<Q, R>
503
499
{
504
500
return Q (std::floor (lhs.internal () / rhs.internal ()) * rhs.internal ());
505
501
}
506
502
507
- template <isArithmetic Q, isArithmetic R> constexpr Q trunc (const Q& lhs, const R& rhs)
503
+ template <isQuantity Q, isQuantity R> constexpr Q trunc (const Q& lhs, const R& rhs)
508
504
requires Isomorphic<Q, R>
509
505
{
510
506
return Q (std::trunc (lhs.internal () / rhs.internal ()) * rhs.internal ());
511
507
}
512
508
513
- template <isArithmetic Q, isArithmetic R> constexpr Q round (const Q& lhs, const R& rhs)
509
+ template <isQuantity Q, isQuantity R> constexpr Q round (const Q& lhs, const R& rhs)
514
510
requires Isomorphic<Q, R>
515
511
{
516
512
return Q (std::round (lhs.internal () / rhs.internal ()) * rhs.internal ());
0 commit comments