[libcxx-commits] [libcxx] [libc++] Implement C++29 Bit Permutations P3104R6 (PR #217820)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Sep 25 06:41:54 PDT 2026
https://github.com/siradam7th updated https://github.com/llvm/llvm-project/pull/217820
>From c281774ac93e4b2e208c8abbc9d740edb5c101b5 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 | 1 +
libcxx/include/module.modulemap.in | 1 +
libcxx/modules/std/bit.inc | 6 ++++++
5 files changed, 41 insertions(+)
create mode 100644 libcxx/include/__bit/bit_reverse.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 99c3bd8b72aa81..83b527eee2fb83 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 00000000000000..eae2903771fa6d
--- /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
+
+#if _LIBCPP_STD_VER >= 29
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_reverse(_Tp __t) noexcept {
+ return __builtin_elementwise_bitreverse(__t);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 29
+
+#endif // _LIBCPP___BIT_BIT_REVERSE_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index be3dfdc451b3d4..d89a8122a1454d 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -91,6 +91,7 @@ namespace std {
# endif
# if _LIBCPP_STD_VER >= 29
+# include <__bit/bit_reverse.h>
# include <__bit/shift.h>
# endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 3e2b446780a437..fba4d3777915e3 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -922,6 +922,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 dd05b3963db333..055a3b77c08b5b 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -41,4 +41,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 9383327d28a92c131c41c80c8553876641412319 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 83b527eee2fb83..b6a3b486086a28 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 00000000000000..3b617329e8f61c
--- /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
+
+#if _LIBCPP_STD_VER >= 29
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+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;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 29
+
+#endif // _LIBCPP___BIT_BIT_REPEAT_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index d89a8122a1454d..966de711a3bfc7 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -91,6 +91,7 @@ namespace std {
# endif
# if _LIBCPP_STD_VER >= 29
+# include <__bit/bit_repeat.h>
# include <__bit/bit_reverse.h>
# include <__bit/shift.h>
# endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index fba4d3777915e3..81abbed3c8cf89 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -923,6 +923,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 055a3b77c08b5b..f296afcf608c2d 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -44,6 +44,7 @@ export namespace std {
#if _LIBCPP_STD_VER >= 29
// [bit.permute], permutation
+ using std::bit_repeat;
using std::bit_reverse;
#endif
>From 584a5012e2e8254fc60bdf76f4ed96e56c3bb60f 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 b6a3b486086a28..0fa815e9cbb190 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 00000000000000..4fe2b009563b90
--- /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
+
+#if _LIBCPP_STD_VER >= 29
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_compress(_Tp __t, _Tp __m) noexcept {
+ return __builtin_elementwise_pext(__t, __m);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 29
+
+#endif // _LIBCPP___BIT_BIT_COMPRESS_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index 966de711a3bfc7..67d7ae6c2194a2 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -91,6 +91,7 @@ namespace std {
# endif
# if _LIBCPP_STD_VER >= 29
+# include <__bit/bit_compress.h>
# include <__bit/bit_repeat.h>
# include <__bit/bit_reverse.h>
# include <__bit/shift.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 81abbed3c8cf89..9b5419c58292b2 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -924,6 +924,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 f296afcf608c2d..33799bbd9d4da5 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -44,6 +44,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 43b3834de4c671f50a9b793d652b9f62dadda489 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 0fa815e9cbb190..a99bf01e717586 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 00000000000000..fc86578439f7b8
--- /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
+
+#if _LIBCPP_STD_VER >= 29
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_expand(_Tp __t, _Tp __m) noexcept {
+ return __builtin_elementwise_pdep(__t, __m);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 29
+
+#endif // _LIBCPP___BIT_BIT_EXPAND_H
diff --git a/libcxx/include/bit b/libcxx/include/bit
index 67d7ae6c2194a2..62fb145a665b23 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -92,6 +92,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>
# include <__bit/shift.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 9b5419c58292b2..1d7a8bf537040f 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -925,6 +925,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 33799bbd9d4da5..7ac49f3b8acb8d 100644
--- a/libcxx/modules/std/bit.inc
+++ b/libcxx/modules/std/bit.inc
@@ -45,6 +45,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 5a4852a9448b2bca4e9c35d1f4da413d78ad63e6 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 a99bf01e717586..2db119c32510bf 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