Skip to content

Commit 363bcce

Browse files
committed
Fix compilation of abs() on MacOS (bug #67714)
This changeset works around the semantics of abs() and std::abs() for different data types, and allows compilation on MacOS again. * liboctave/numeric/mappers.h: Make wrappers named mappers_abs() and use them instead of abs() or std::abs(). * liboctave/operators/mx-inlines.cc: Use the mappers_abs() wrappers here as well.
1 parent f17f70b commit 363bcce

File tree

2 files changed

+96
-75
lines changed

2 files changed

+96
-75
lines changed

liboctave/numeric/mappers.h

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@
3636
#include "oct-cmplx.h"
3737
#include "oct-inttypes-fwd.h"
3838

39+
// Provides some commonly repeated, basic loop templates.
40+
41+
template <typename T>
42+
inline auto mappers_abs (const T& x)
43+
{
44+
if constexpr (std::is_unsigned_v<T>)
45+
return x; // abs doesn't make sense for unsigned types
46+
else
47+
return std::abs(x);
48+
}
49+
// Specialization for octave_int types
50+
template <typename T>
51+
inline auto mappers_abs (const octave_int<T>& x)
52+
{
53+
if constexpr (std::is_unsigned_v<T>)
54+
return x; // abs doesn't make sense for unsigned types
55+
else
56+
return abs(x.value());
57+
}
58+
59+
3960
OCTAVE_BEGIN_NAMESPACE(octave)
4061
OCTAVE_BEGIN_NAMESPACE(math)
4162

@@ -262,7 +283,7 @@ template <typename T>
262283
std::complex<T>
263284
signum (const std::complex<T>& x)
264285
{
265-
T tmp = abs (x);
286+
T tmp = mappers_abs (x);
266287

267288
return tmp == 0 ? 0.0 : x / tmp;
268289
}
@@ -524,15 +545,15 @@ max (float x, float y, const bool nanflag, const bool realabs)
524545
inline std::complex<double>
525546
min (const std::complex<double>& x, const std::complex<double>& y)
526547
{
527-
return isnan (y) ? x : (abs (x) < abs (y) ? x :
528-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
548+
return isnan (y) ? x : (mappers_abs (x) < mappers_abs (y) ? x :
549+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
529550
}
530551

531552
inline std::complex<double>
532553
max (const std::complex<double>& x, const std::complex<double>& y)
533554
{
534-
return isnan (y) ? x : (abs (x) > abs (y) ? x :
535-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
555+
return isnan (y) ? x : (mappers_abs (x) > mappers_abs (y) ? x :
556+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
536557
}
537558

538559
inline std::complex<double>
@@ -543,8 +564,8 @@ min (const std::complex<double>& x, const std::complex<double>& y,
543564
if (! nanflag && (isnan (x) || isnan (y)))
544565
out = NAN;
545566
else
546-
out = isnan (y) ? x : (abs (x) < abs (y) ? x :
547-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
567+
out = isnan (y) ? x : (mappers_abs (x) < mappers_abs (y) ? x :
568+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
548569
return out;
549570
}
550571

@@ -556,8 +577,8 @@ max (const std::complex<double>& x, const std::complex<double>& y,
556577
if (! nanflag && (isnan (x) || isnan (y)))
557578
out = NAN;
558579
else
559-
out = isnan (y) ? x : (abs (x) > abs (y) ? x :
560-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
580+
out = isnan (y) ? x : (mappers_abs (x) > mappers_abs (y) ? x :
581+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
561582
return out;
562583
}
563584

@@ -573,8 +594,8 @@ min (const std::complex<double>& x, const std::complex<double>& y,
573594
(std::real (x) == std::real (y) &&
574595
std::imag (x) <= std::imag (y) ? x : y));
575596
else
576-
out = isnan (y) ? x : (abs (x) < abs (y) ? x :
577-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
597+
out = isnan (y) ? x : (mappers_abs (x) < mappers_abs (y) ? x :
598+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
578599
return out;
579600
}
580601

@@ -590,23 +611,23 @@ max (const std::complex<double>& x, const std::complex<double>& y,
590611
(std::real (x) == std::real (y) &&
591612
std::imag (x) >= std::imag (y) ? x : y));
592613
else
593-
out = isnan (y) ? x : (abs (x) > abs (y) ? x :
594-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
614+
out = isnan (y) ? x : (mappers_abs (x) > mappers_abs (y) ? x :
615+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
595616
return out;
596617
}
597618

598619
inline std::complex<float>
599620
min (const std::complex<float>& x, const std::complex<float>& y)
600621
{
601622
return isnan (y) ? x : (abs (x) < abs (y) ? x :
602-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
623+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
603624
}
604625

605626
inline std::complex<float>
606627
max (const std::complex<float>& x, const std::complex<float>& y)
607628
{
608629
return isnan (y) ? x : (abs (x) > abs (y) ? x :
609-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
630+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
610631
}
611632

612633
inline std::complex<float>
@@ -617,8 +638,8 @@ min (const std::complex<float>& x, const std::complex<float>& y,
617638
if (! nanflag && (isnan (x) || isnan (y)))
618639
out = NAN;
619640
else
620-
out = isnan (y) ? x : (abs (x) < abs (y) ? x :
621-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
641+
out = isnan (y) ? x : (mappers_abs (x) < mappers_abs (y) ? x :
642+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
622643
return out;
623644
}
624645

@@ -630,8 +651,8 @@ max (const std::complex<float>& x, const std::complex<float>& y,
630651
if (! nanflag && (isnan (x) || isnan (y)))
631652
out = NAN;
632653
else
633-
out = isnan (y) ? x : (abs (x) > abs (y) ? x :
634-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
654+
out = isnan (y) ? x : (mappers_abs (x) > mappers_abs (y) ? x :
655+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
635656
return out;
636657
}
637658

@@ -647,8 +668,8 @@ min (const std::complex<float>& x, const std::complex<float>& y,
647668
(std::real (x) == std::real (y) &&
648669
std::imag (x) <= std::imag (y) ? x : y));
649670
else
650-
out = isnan (y) ? x : (abs (x) < abs (y) ? x :
651-
(abs (x) == abs (y) && std::arg (x) <= std::arg (y) ? x : y));
671+
out = isnan (y) ? x : (mappers_abs (x) < mappers_abs (y) ? x :
672+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) <= std::arg (y) ? x : y));
652673
return out;
653674
}
654675

@@ -664,8 +685,8 @@ max (const std::complex<float>& x, const std::complex<float>& y,
664685
(std::real (x) == std::real (y) &&
665686
std::imag (x) >= std::imag (y) ? x : y));
666687
else
667-
out = isnan (y) ? x : (abs (x) > abs (y) ? x :
668-
(abs (x) == abs (y) && std::arg (x) >= std::arg (y) ? x : y));
688+
out = isnan (y) ? x : (mappers_abs (x) > mappers_abs (y) ? x :
689+
(mappers_abs (x) == mappers_abs (y) && std::arg (x) >= std::arg (y) ? x : y));
669690
return out;
670691
}
671692

@@ -708,8 +729,8 @@ min (const octave_int<T>& x, const octave_int<T>& y,
708729
if (realabs)
709730
out = x.value () <= y.value () ? x : y;
710731
else
711-
out = abs (x.value ()) < abs (y.value ()) ? x :
712-
(abs (x.value ()) == abs (y.value ()) &&
732+
out = mappers_abs (x.value ()) < mappers_abs (y.value ()) ? x :
733+
(mappers_abs (x.value ()) == mappers_abs (y.value ()) &&
713734
x.value () <= y.value () ? x : y);
714735
return out;
715736
}
@@ -723,8 +744,8 @@ max (const octave_int<T>& x, const octave_int<T>& y,
723744
if (realabs)
724745
out = x.value () >= y.value () ? x : y;
725746
else
726-
out = abs (x.value ()) > abs (y.value ()) ? x :
727-
(abs (x.value ()) == abs (y.value ()) &&
747+
out = mappers_abs (x.value ()) > mappers_abs (y.value ()) ? x :
748+
(mappers_abs (x.value ()) == mappers_abs (y.value ()) &&
728749
x.value () >= y.value () ? x : y);
729750
return out;
730751
}

0 commit comments

Comments
 (0)