[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