libstdc++-v3/ChangeLog:

        * include/bits/simd_alg.h: New file.

Signed-off-by: Matthias Kretz <[email protected]>
---
 libstdc++-v3/include/bits/simd_alg.h | 76 ++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 libstdc++-v3/include/bits/simd_alg.h


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Center for Heavy Ion Research               https://gsi.de
 std::simd
──────────────────────────────────────────────────────────────────────────
diff --git a/libstdc++-v3/include/bits/simd_alg.h b/libstdc++-v3/include/bits/simd_alg.h
new file mode 100644
index 00000000000..3e9652bae94
--- /dev/null
+++ b/libstdc++-v3/include/bits/simd_alg.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later WITH GCC-exception-3.1 */
+/* Copyright © 2025      GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+ *                       Matthias Kretz <[email protected]>
+ */
+
+#ifndef _GLIBCXX_SIMD_ALG_H
+#define _GLIBCXX_SIMD_ALG_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#if __cplusplus >= 202400L
+
+#include "simd_vec.h"
+
+// psabi warnings are bogus because the ABI of the internal types never leaks into user code
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpsabi"
+
+// [simd.alg] -----------------------------------------------------------------
+namespace std::simd
+{
+  template<typename _Tp, typename _Ap>
+    [[__gnu__::__always_inline__]]
+    constexpr basic_vec<_Tp, _Ap>
+    min(const basic_vec<_Tp, _Ap>& __a, const basic_vec<_Tp, _Ap>& __b) noexcept
+    { return __select_impl(__a < __b, __a, __b); }
+
+  template<typename _Tp, typename _Ap>
+    [[__gnu__::__always_inline__]]
+    constexpr basic_vec<_Tp, _Ap>
+    max(const basic_vec<_Tp, _Ap>& __a, const basic_vec<_Tp, _Ap>& __b) noexcept
+    { return __select_impl(__a < __b, __b, __a); }
+
+  template<typename _Tp, typename _Ap>
+    [[__gnu__::__always_inline__]]
+    constexpr pair<basic_vec<_Tp, _Ap>, basic_vec<_Tp, _Ap>>
+    minmax(const basic_vec<_Tp, _Ap>& __a, const basic_vec<_Tp, _Ap>& __b) noexcept
+    { return {min(__a, __b), max(__a, __b)}; }
+
+  template<typename _Tp, typename _Ap>
+    [[__gnu__::__always_inline__]]
+    constexpr basic_vec<_Tp, _Ap>
+    clamp(const basic_vec<_Tp, _Ap>& __v, const basic_vec<_Tp, _Ap>& __lo,
+          const basic_vec<_Tp, _Ap>& __hi)
+    {
+      __glibcxx_simd_precondition(none_of(__lo > __hi), "lower bound is larger than upper bound");
+      return max(__lo, min(__hi, __v));
+    }
+
+  template<typename _Tp, typename _Up>
+    constexpr auto
+    select(bool __c, const _Tp& __a, const _Up& __b)
+    -> remove_cvref_t<decltype(__c ? __a : __b)>
+    { return __c ? __a : __b; }
+
+  template<size_t _Bytes, typename _Ap, typename _Tp, typename _Up>
+    [[__gnu__::__always_inline__]]
+    constexpr auto
+    select(const basic_mask<_Bytes, _Ap>& __c, const _Tp& __a, const _Up& __b)
+    noexcept -> decltype(__select_impl(__c, __a, __b))
+    { return __select_impl(__c, __a, __b); }
+}
+
+namespace std
+{
+  using simd::min;
+  using simd::max;
+  using simd::minmax;
+  using simd::clamp;
+}
+
+#pragma GCC diagnostic pop
+#endif // C++26
+#endif // _GLIBCXX_SIMD_ALG_H

Reply via email to