[libcxx-commits] [libcxx] [libc++] Implement C++29 Bit Permutations P3104R6 (PR #217820)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Aug 20 22:53:42 PDT 2026


https://github.com/siradam7th updated https://github.com/llvm/llvm-project/pull/217820

>From 2a2a3e0dad1d3325892748ef5add83469dbc67cb Mon Sep 17 00:00:00 2001
From: siradam7th <oss at afterback.gq>
Date: Fri, 21 Aug 2026 06:15:40 +0100
Subject: [PATCH 1/5] [libc++] implement std::bit_reverse

---
 libcxx/include/CMakeLists.txt      |  1 +
 libcxx/include/__bit/bit_reverse.h | 32 ++++++++++++++++++++++++++++++
 libcxx/include/bit                 |  4 ++++
 libcxx/include/module.modulemap.in |  1 +
 libcxx/modules/std/bit.inc         |  6 ++++++
 5 files changed, 44 insertions(+)
 create mode 100644 libcxx/include/__bit/bit_reverse.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a1d6a09aa6b20..dbb7b60763ad0 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -235,6 +235,7 @@ set(files
   __bit/bit_floor.h
   __bit/bit_log2.h
   __bit/bit_width.h
+  __bit/bit_reverse.h
   __bit/blsr.h
   __bit/byteswap.h
   __bit/countl.h
diff --git a/libcxx/include/__bit/bit_reverse.h b/libcxx/include/__bit/bit_reverse.h
new file mode 100644
index 0000000000000..c62a4b188c5e7
--- /dev/null
+++ b/libcxx/include/__bit/bit_reverse.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_REVERSE_H
+#define _LIBCPP___BIT_BIT_REVERSE_H
+
+#include <__config>
+#include <__type_traits/integer_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 29
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_reverse(_Tp __t) noexcept {
+  return __builtin_elementwise_bitreverse(__t);
+}
+
+#endif // _LIBCPP_STD_VER >= 29
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_REVERSE_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index 40fcda27856bb..e9ac5124a254c 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -84,6 +84,10 @@ namespace std {
 #    include <__bit/byteswap.h>
 #  endif
 
+#  if _LIBCPP_STD_VER >= 29
+#    include <__bit/bit_reverse.h>
+#  endif
+
 #  include <version>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 4512cc71153ca..ef878b12c2b86 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -919,6 +919,7 @@ module std {
     module bit_floor        { header "__bit/bit_floor.h" }
     module bit_log2         { header "__bit/bit_log2.h" }
     module bit_width        { header "__bit/bit_width.h" }
+    module bit_reverse      { header "__bit/bit_reverse.h" }
     module blsr             { header "__bit/blsr.h" }
     module byteswap         { header "__bit/byteswap.h" }
     module countl           { header "__bit/countl.h" }
diff --git a/libcxx/modules/std/bit.inc b/libcxx/modules/std/bit.inc
index 027a6c17ad6a6..6974e98f1484b 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -35,4 +35,10 @@ export namespace std {
 
   // [bit.endian], endian
   using std::endian;
+
+#if _LIBCPP_STD_VER >= 29
+  // [bit.permute], permutation
+  using std::bit_reverse;
+#endif
+
 } // namespace std

>From 4bd380bc420668f63c29cdc1060236d83fee94cb Mon Sep 17 00:00:00 2001
From: siradam7th <oss at afterback.gq>
Date: Fri, 21 Aug 2026 06:17:11 +0100
Subject: [PATCH 2/5] [libc++] implement std::bit_repeat

---
 libcxx/include/CMakeLists.txt      |  1 +
 libcxx/include/__bit/bit_repeat.h  | 37 ++++++++++++++++++++++++++++++
 libcxx/include/bit                 |  1 +
 libcxx/include/module.modulemap.in |  1 +
 libcxx/modules/std/bit.inc         |  1 +
 5 files changed, 41 insertions(+)
 create mode 100644 libcxx/include/__bit/bit_repeat.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index dbb7b60763ad0..4b3cffaa075bd 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -236,6 +236,7 @@ set(files
   __bit/bit_log2.h
   __bit/bit_width.h
   __bit/bit_reverse.h
+  __bit/bit_repeat.h
   __bit/blsr.h
   __bit/byteswap.h
   __bit/countl.h
diff --git a/libcxx/include/__bit/bit_repeat.h b/libcxx/include/__bit/bit_repeat.h
new file mode 100644
index 0000000000000..47c0cad70ba66
--- /dev/null
+++ b/libcxx/include/__bit/bit_repeat.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_REPEAT_H
+#define _LIBCPP___BIT_BIT_REPEAT_H
+
+#include <__config>
+#include <__type_traits/integer_traits.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 29
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_repeat(_Tp __t, int __l) {
+  _Tp __res = 0;
+  for (int i = 0; i < numeric_limits<_Tp>::digits; ++i) {
+    __res |= ((__t >> (i % __l)) & 1) << i;
+  }
+  return __res;
+}
+
+#endif // _LIBCPP_STD_VER >= 29
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_REPEAT_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index e9ac5124a254c..a5d345e1bd030 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -85,6 +85,7 @@ namespace std {
 #  endif
 
 #  if _LIBCPP_STD_VER >= 29
+#    include <__bit/bit_repeat.h>
 #    include <__bit/bit_reverse.h>
 #  endif
 
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index ef878b12c2b86..cc64d073d60d2 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -920,6 +920,7 @@ module std {
     module bit_log2         { header "__bit/bit_log2.h" }
     module bit_width        { header "__bit/bit_width.h" }
     module bit_reverse      { header "__bit/bit_reverse.h" }
+    module bit_repeat       { header "__bit/bit_repeat.h" }
     module blsr             { header "__bit/blsr.h" }
     module byteswap         { header "__bit/byteswap.h" }
     module countl           { header "__bit/countl.h" }
diff --git a/libcxx/modules/std/bit.inc b/libcxx/modules/std/bit.inc
index 6974e98f1484b..bdc3a2084f07a 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -38,6 +38,7 @@ export namespace std {
 
 #if _LIBCPP_STD_VER >= 29
   // [bit.permute], permutation
+  using std::bit_repeat;
   using std::bit_reverse;
 #endif
 

>From 8add4cc0171bb629871077310fd044737bb687b6 Mon Sep 17 00:00:00 2001
From: siradam7th <oss at afterback.gq>
Date: Fri, 21 Aug 2026 06:19:37 +0100
Subject: [PATCH 3/5] [libc++] implement std::bit_compress

---
 libcxx/include/CMakeLists.txt       |  1 +
 libcxx/include/__bit/bit_compress.h | 32 +++++++++++++++++++++++++++++
 libcxx/include/bit                  |  1 +
 libcxx/include/module.modulemap.in  |  1 +
 libcxx/modules/std/bit.inc          |  1 +
 5 files changed, 36 insertions(+)
 create mode 100644 libcxx/include/__bit/bit_compress.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4b3cffaa075bd..97f9d6aa9065d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -237,6 +237,7 @@ set(files
   __bit/bit_width.h
   __bit/bit_reverse.h
   __bit/bit_repeat.h
+  __bit/bit_compress.h
   __bit/blsr.h
   __bit/byteswap.h
   __bit/countl.h
diff --git a/libcxx/include/__bit/bit_compress.h b/libcxx/include/__bit/bit_compress.h
new file mode 100644
index 0000000000000..6266a6841dd93
--- /dev/null
+++ b/libcxx/include/__bit/bit_compress.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_COMPRESS_H
+#define _LIBCPP___BIT_BIT_COMPRESS_H
+
+#include <__config>
+#include <__type_traits/integer_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 29
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_compress(_Tp __t, _Tp __m) noexcept {
+  return __builtin_elementwise_pext(__t, __m);
+}
+
+#endif // _LIBCPP_STD_VER >= 29
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_COMPRESS_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index a5d345e1bd030..0b5ed8885e769 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -85,6 +85,7 @@ namespace std {
 #  endif
 
 #  if _LIBCPP_STD_VER >= 29
+#    include <__bit/bit_compress.h>
 #    include <__bit/bit_repeat.h>
 #    include <__bit/bit_reverse.h>
 #  endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index cc64d073d60d2..d83e828dcc63a 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -921,6 +921,7 @@ module std {
     module bit_width        { header "__bit/bit_width.h" }
     module bit_reverse      { header "__bit/bit_reverse.h" }
     module bit_repeat       { header "__bit/bit_repeat.h" }
+    module bit_compress     { header "__bit/bit_compress.h" }
     module blsr             { header "__bit/blsr.h" }
     module byteswap         { header "__bit/byteswap.h" }
     module countl           { header "__bit/countl.h" }
diff --git a/libcxx/modules/std/bit.inc b/libcxx/modules/std/bit.inc
index bdc3a2084f07a..823cd39d3cfc1 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -38,6 +38,7 @@ export namespace std {
 
 #if _LIBCPP_STD_VER >= 29
   // [bit.permute], permutation
+  using std::bit_compress;
   using std::bit_repeat;
   using std::bit_reverse;
 #endif

>From 606851cc30c078e5e3a9c723de951488dbd50f0a Mon Sep 17 00:00:00 2001
From: siradam7th <oss at afterback.gq>
Date: Fri, 21 Aug 2026 06:20:55 +0100
Subject: [PATCH 4/5] [libc++] implement std::bit_expand

---
 libcxx/include/CMakeLists.txt      |  1 +
 libcxx/include/__bit/bit_expand.h  | 32 ++++++++++++++++++++++++++++++
 libcxx/include/bit                 |  1 +
 libcxx/include/module.modulemap.in |  1 +
 libcxx/modules/std/bit.inc         |  1 +
 5 files changed, 36 insertions(+)
 create mode 100644 libcxx/include/__bit/bit_expand.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 97f9d6aa9065d..d4950bb82b202 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -238,6 +238,7 @@ set(files
   __bit/bit_reverse.h
   __bit/bit_repeat.h
   __bit/bit_compress.h
+  __bit/bit_expand.h
   __bit/blsr.h
   __bit/byteswap.h
   __bit/countl.h
diff --git a/libcxx/include/__bit/bit_expand.h b/libcxx/include/__bit/bit_expand.h
new file mode 100644
index 0000000000000..8e94bc52a3632
--- /dev/null
+++ b/libcxx/include/__bit/bit_expand.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_EXPAND_H
+#define _LIBCPP___BIT_BIT_EXPAND_H
+
+#include <__config>
+#include <__type_traits/integer_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 29
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_expand(_Tp __t, _Tp __m) noexcept {
+  return __builtin_elementwise_pdep(__t, __m);
+}
+
+#endif // _LIBCPP_STD_VER >= 29
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_EXPAND_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index 0b5ed8885e769..e71ee4d736080 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -86,6 +86,7 @@ namespace std {
 
 #  if _LIBCPP_STD_VER >= 29
 #    include <__bit/bit_compress.h>
+#    include <__bit/bit_expand.h>
 #    include <__bit/bit_repeat.h>
 #    include <__bit/bit_reverse.h>
 #  endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index d83e828dcc63a..9bde5799fc07d 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -922,6 +922,7 @@ module std {
     module bit_reverse      { header "__bit/bit_reverse.h" }
     module bit_repeat       { header "__bit/bit_repeat.h" }
     module bit_compress     { header "__bit/bit_compress.h" }
+    module bit_expand       { header "__bit/bit_expand.h" }
     module blsr             { header "__bit/blsr.h" }
     module byteswap         { header "__bit/byteswap.h" }
     module countl           { header "__bit/countl.h" }
diff --git a/libcxx/modules/std/bit.inc b/libcxx/modules/std/bit.inc
index 823cd39d3cfc1..7d8403c833a08 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -39,6 +39,7 @@ export namespace std {
 #if _LIBCPP_STD_VER >= 29
   // [bit.permute], permutation
   using std::bit_compress;
+  using std::bit_expand;
   using std::bit_repeat;
   using std::bit_reverse;
 #endif

>From 45089eeab0001ac553c73d06b596a052a3e904f2 Mon Sep 17 00:00:00 2001
From: siradam7th <oss at afterback.gq>
Date: Fri, 21 Aug 2026 06:52:14 +0100
Subject: [PATCH 5/5] [libc++] lint CMakeLists.txt

---
 libcxx/include/CMakeLists.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d4950bb82b202..bebe90bdb9133 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -232,13 +232,13 @@ set(files
   __atomic/to_gcc_order.h
   __bit/bit_cast.h
   __bit/bit_ceil.h
+  __bit/bit_compress.h
+  __bit/bit_expand.h
   __bit/bit_floor.h
   __bit/bit_log2.h
-  __bit/bit_width.h
-  __bit/bit_reverse.h
   __bit/bit_repeat.h
-  __bit/bit_compress.h
-  __bit/bit_expand.h
+  __bit/bit_reverse.h
+  __bit/bit_width.h
   __bit/blsr.h
   __bit/byteswap.h
   __bit/countl.h



More information about the libcxx-commits mailing list