[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/4] stdbit: new module
From: |
Paul Eggert |
Subject: |
[PATCH 1/4] stdbit: new module |
Date: |
Sat, 11 May 2024 12:08:39 -0700 |
* doc/gnulib-tool.texi, doc/gnulib.texi: Mention it.
* doc/posix-headers/stdbit.texi, lib/stdbit.c, lib/stdbit.in.h:
* m4/stdbit_h.m4, modules/stdbit:
New files.
---
ChangeLog | 8 +
doc/gnulib-tool.texi | 1 +
doc/gnulib.texi | 2 +
doc/posix-headers/stdbit.texi | 25 ++
lib/stdbit.c | 3 +
lib/stdbit.in.h | 640 ++++++++++++++++++++++++++++++++++
m4/stdbit_h.m4 | 19 +
modules/stdbit | 44 +++
8 files changed, 742 insertions(+)
create mode 100644 doc/posix-headers/stdbit.texi
create mode 100644 lib/stdbit.c
create mode 100644 lib/stdbit.in.h
create mode 100644 m4/stdbit_h.m4
create mode 100644 modules/stdbit
diff --git a/ChangeLog b/ChangeLog
index da40ff41de..1019917f36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-05-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ stdbit: new module
+ * doc/gnulib-tool.texi, doc/gnulib.texi: Mention it.
+ * doc/posix-headers/stdbit.texi, lib/stdbit.c, lib/stdbit.in.h:
+ * m4/stdbit_h.m4, modules/stdbit:
+ New files.
+
2024-05-11 Bruno Haible <bruno@clisp.org>
doc: Mention module execinfo.
diff --git a/doc/gnulib-tool.texi b/doc/gnulib-tool.texi
index 9ed30c2055..5a2fd19cac 100644
--- a/doc/gnulib-tool.texi
+++ b/doc/gnulib-tool.texi
@@ -585,6 +585,7 @@ This is true for the following POSIX or ISO C standardized
header files:
@item @code{spawn.h}
@item @code{stdalign.h}
@item @code{stdarg.h}
+@item @code{stdbit.h}
@item @code{stddef.h}
@item @code{stdint.h}
@item @code{stdio.h}
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index 55cf6ebcc9..6cbd10619e 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -1082,6 +1082,7 @@ which (known) portability problems are not worked around
by Gnulib.
* stdalign.h::
* stdarg.h::
* stdatomic.h::
+* stdbit.h::
* stdbool.h::
* stdckdint.h::
* stddef.h::
@@ -1174,6 +1175,7 @@ which (known) portability problems are not worked around
by Gnulib.
@include posix-headers/stdalign.texi
@include posix-headers/stdarg.texi
@include posix-headers/stdatomic.texi
+@include posix-headers/stdbit.texi
@include posix-headers/stdbool.texi
@include posix-headers/stdckdint.texi
@include posix-headers/stddef.texi
diff --git a/doc/posix-headers/stdbit.texi b/doc/posix-headers/stdbit.texi
new file mode 100644
index 0000000000..8870668a59
--- /dev/null
+++ b/doc/posix-headers/stdbit.texi
@@ -0,0 +1,25 @@
+@node stdbit.h
+@section @file{stdbit.h}
+
+Gnulib module: stdbit
+
+Portability problems fixed by Gnulib:
+@itemize
+@item
+This header file is missing on many non-C23 platforms:
+glibc 2.38, FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5,
+AIX 7.3, HP-UX 11.31, Solaris 11.4, mingw, MSVC 17, Android 15.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@item
+On older non-C23 platforms lacking @code{typeof} or equivalent, a call
+to @code{stdc_bit_floor} and @code{stdc_bit_ceil} may yield a type
+that is wider than its argument. Although C23 seems to allow this,
+it differs from GNU behavior.
+
+@item
+On non-C23 platforms, type-generic functions apply portably only to
+the standard unsigned integer types specified by C17 or earlier.
+@end itemize
diff --git a/lib/stdbit.c b/lib/stdbit.c
new file mode 100644
index 0000000000..0346ec095c
--- /dev/null
+++ b/lib/stdbit.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#define _GL_STDBIT_INLINE _GL_EXTERN_INLINE
+#include <stdbit.h>
diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h
new file mode 100644
index 0000000000..a2fff04772
--- /dev/null
+++ b/lib/stdbit.in.h
@@ -0,0 +1,640 @@
+/* stdbit.h - C23 bit and byte utilities for non-C23 platforms
+
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#ifndef STDBIT_H
+#define STDBIT_H 1
+
+/* This file uses _GL_INLINE, WORDS_BIGENDIAN. */
+#if !_GL_CONFIG_H_INCLUDED
+ #error "Please include config.h first."
+#endif
+
+#include <count-leading-zeros.h>
+#include <count-trailing-zeros.h>
+#include <count-one-bits.h>
+
+/* An expression, preferably with the type of A, that has the value of B. */
+#if ((defined __GNUC__ && 2 <= __GNUC__) \
+ || (defined __clang_major__ && 4 <= __clang_major__) \
+ || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
+ || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__))
+# define _GL_STDBIT_TYPEOF_CAST(a, b) ((__typeof__ (a)) (b))
+#elif 202311 <= __STDC_VERSION__
+# define _GL_STDBIT_TYPEOF_CAST(a, b) ((typeof (a)) (b))
+#else
+/* This platform is so old that it lacks typeof, so _Generic is likely
+ missing or unreliable. The C23 standard seems to allow yielding B
+ (which is always unsigned long long int), so do that. */
+# define _GL_STDBIT_TYPEOF_CAST(a, b) (b)
+#endif
+
+#define __STDC_VERSION_STDBIT_H__ 202311L
+
+#define __STDC_ENDIAN_BIG__ 4321
+#define __STDC_ENDIAN_LITTLE__ 1234
+#ifdef WORDS_BIGENDIAN
+# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__
+#else
+# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
+#endif
+
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_STDBIT_INLINE
+# define _GL_STDBIT_INLINE _GL_INLINE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_zeros_uc (unsigned char n)
+{
+ return count_leading_zeros (n) - 8 * (sizeof 0u - sizeof n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_zeros_us (unsigned short int n)
+{
+ return count_leading_zeros (n) - 8 * (sizeof 0u - sizeof n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_zeros_ui (unsigned int n)
+{
+ return count_leading_zeros (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_zeros_ul (unsigned long int n)
+{
+ return count_leading_zeros_l (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_zeros_ull (unsigned long long int n)
+{
+ return count_leading_zeros_ll (n);
+}
+
+#define stdc_leading_zeros(n) \
+ (sizeof (n) == 1 ? stdc_leading_zeros_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_zeros_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_leading_zeros_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_leading_zeros_ul (n) \
+ : stdc_leading_zeros_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_ones_uc (unsigned char n)
+{
+ unsigned int ui = n;
+ return count_leading_zeros (~(ui << 8 * (sizeof ui - sizeof n)));
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_ones_us (unsigned short int n)
+{
+ unsigned int ui = n;
+ return count_leading_zeros (~(ui << 8 * (sizeof ui - sizeof n)));
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_ones_ui (unsigned int n)
+{
+ return count_leading_zeros (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_ones_ul (unsigned long int n)
+{
+ return count_leading_zeros_l (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_leading_ones_ull (unsigned long long int n)
+{
+ return count_leading_zeros_ll (~n);
+}
+
+#define stdc_leading_ones(n) \
+ (sizeof (n) == 1 ? stdc_leading_ones_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_ones_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_leading_ones_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_leading_ones_ul (n) \
+ : stdc_leading_ones_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_zeros_uc (unsigned char n)
+{
+ return count_trailing_zeros (n | (1 + (unsigned char) -1));
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_zeros_us (unsigned short int n)
+{
+ return count_trailing_zeros (n | (1 + (unsigned short int) -1));
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_zeros_ui (unsigned int n)
+{
+ return count_trailing_zeros (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_zeros_ul (unsigned long int n)
+{
+ return count_trailing_zeros_l (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_zeros_ull (unsigned long long int n)
+{
+ return count_trailing_zeros_ll (n);
+}
+
+#define stdc_trailing_zeros(n) \
+ (sizeof (n) == 1 ? stdc_trailing_zeros_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_zeros_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_trailing_zeros_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_trailing_zeros_ul (n) \
+ : stdc_trailing_zeros_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_ones_uc (unsigned char n)
+{
+ unsigned int ui = n;
+ return count_trailing_zeros (~ui);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_ones_us (unsigned short int n)
+{
+ unsigned int ui = n;
+ return count_trailing_zeros (~ui);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_ones_ui (unsigned int n)
+{
+ return count_trailing_zeros (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_ones_ul (unsigned long int n)
+{
+ return count_trailing_zeros_l (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_trailing_ones_ull (unsigned long long int n)
+{
+ return count_trailing_zeros_ll (~n);
+}
+
+#define stdc_trailing_ones(n) \
+ (sizeof (n) == 1 ? stdc_trailing_ones_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_ones_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_trailing_ones_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_trailing_ones_ul (n) \
+ : stdc_trailing_ones_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_zero_uc (unsigned char n)
+{
+ unsigned int count = stdc_leading_ones_uc (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_zero_us (unsigned short int n)
+{
+ unsigned int count = stdc_leading_ones_us (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_zero_ui (unsigned int n)
+{
+ unsigned int count = stdc_leading_ones_ui (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_zero_ul (unsigned long int n)
+{
+ unsigned int count = stdc_leading_ones_ul (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_zero_ull (unsigned long long int n)
+{
+ unsigned int count = stdc_leading_ones_ull (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+#define stdc_first_leading_zero(n) \
+ (sizeof (n) == 1 ? stdc_first_leading_zero_uc (n) \
+ : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_zero_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_first_leading_zero_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_first_leading_zero_ul (n) \
+ : stdc_first_leading_zero_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_one_uc (unsigned char n)
+{
+ unsigned int count = stdc_leading_zeros_uc (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_one_us (unsigned short int n)
+{
+ unsigned int count = stdc_leading_zeros_us (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_one_ui (unsigned int n)
+{
+ unsigned int count = stdc_leading_zeros_ui (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_one_ul (unsigned long int n)
+{
+ unsigned int count = stdc_leading_zeros_ul (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_leading_one_ull (unsigned long long int n)
+{
+ unsigned int count = stdc_leading_zeros_ull (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+#define stdc_first_leading_one(n) \
+ (sizeof (n) == 1 ? stdc_first_leading_one_uc (n) \
+ : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_one_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_first_leading_one_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_first_leading_one_ul (n) \
+ : stdc_first_leading_one_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_zero_uc (unsigned char n)
+{
+ unsigned int count = stdc_trailing_ones_uc (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_zero_us (unsigned short int n)
+{
+ unsigned int count = stdc_trailing_ones_us (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_zero_ui (unsigned int n)
+{
+ unsigned int count = stdc_trailing_ones_ui (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_zero_ul (unsigned long int n)
+{
+ unsigned int count = stdc_trailing_ones_ul (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_zero_ull (unsigned long long int n)
+{
+ unsigned int count = stdc_trailing_ones_ull (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+#define stdc_first_trailing_zero(n) \
+ (sizeof (n) == 1 ? stdc_first_trailing_zero_uc (n) \
+ : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_zero_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_first_trailing_zero_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_first_trailing_zero_ul (n) \
+ : stdc_first_trailing_zero_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_one_uc (unsigned char n)
+{
+ unsigned int count = stdc_trailing_zeros_uc (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_one_us (unsigned short int n)
+{
+ unsigned int count = stdc_trailing_zeros_us (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_one_ui (unsigned int n)
+{
+ unsigned int count = stdc_trailing_zeros_ui (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_one_ul (unsigned long int n)
+{
+ unsigned int count = stdc_trailing_zeros_ul (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_first_trailing_one_ull (unsigned long long int n)
+{
+ unsigned int count = stdc_trailing_zeros_ull (n);
+ return count == 8 * sizeof n ? 0 : count + 1;
+}
+
+#define stdc_first_trailing_one(n) \
+ (sizeof (n) == 1 ? stdc_first_trailing_one_uc (n) \
+ : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_one_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_first_trailing_one_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_first_trailing_one_ul (n) \
+ : stdc_first_trailing_one_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_zeros_uc (unsigned char n)
+{
+ unsigned int ui = n;
+ return count_one_bits (~ui) - 8 * (sizeof ui - sizeof n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_zeros_us (unsigned short int n)
+{
+ unsigned int ui = n;
+ return count_one_bits (~ui) - 8 * (sizeof ui - sizeof n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_zeros_ui (unsigned int n)
+{
+ return count_one_bits (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_zeros_ul (unsigned long int n)
+{
+ return count_one_bits_l (~n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_zeros_ull (unsigned long long int n)
+{
+ return count_one_bits_ll (~n);
+}
+
+#define stdc_count_zeros(n) \
+ (sizeof (n) == 1 ? stdc_count_zeros_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_count_zeros_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_count_zeros_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_count_zeros_ul (n) \
+ : stdc_count_zeros_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_ones_uc (unsigned char n)
+{
+ return count_one_bits (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_ones_us (unsigned short int n)
+{
+ return count_one_bits (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_ones_ui (unsigned int n)
+{
+ return count_one_bits (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_ones_ul (unsigned long int n)
+{
+ return count_one_bits_l (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_count_ones_ull (unsigned long long int n)
+{
+ return count_one_bits_ll (n);
+}
+
+#define stdc_count_ones(n) \
+ (sizeof (n) == 1 ? stdc_count_ones_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_count_ones_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_count_ones_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_count_ones_ul (n) \
+ : stdc_count_ones_ull (n))
+
+
+_GL_STDBIT_INLINE bool
+stdc_has_single_bit_uc (unsigned char n)
+{
+ unsigned char n_1 = n - 1, nx = n_1 ^ n;
+ return n_1 < nx;
+}
+
+_GL_STDBIT_INLINE bool
+stdc_has_single_bit_us (unsigned short int n)
+{
+ unsigned short int n_1 = n - 1, nx = n_1 ^ n;
+ return n_1 < nx;
+}
+
+_GL_STDBIT_INLINE bool
+stdc_has_single_bit_ui (unsigned int n)
+{
+ unsigned int n_1 = n - 1, nx = n_1 ^ n;
+ return n_1 < nx;
+}
+
+_GL_STDBIT_INLINE bool
+stdc_has_single_bit_ul (unsigned long int n)
+{
+ unsigned long int n_1 = n - 1, nx = n_1 ^ n;
+ return n_1 < nx;
+}
+
+_GL_STDBIT_INLINE bool
+stdc_has_single_bit_ull (unsigned long long int n)
+{
+ unsigned long long int n_1 = n - 1, nx = n_1 ^ n;
+ return n_1 < nx;
+}
+
+#define stdc_has_single_bit(n) \
+ ((bool) \
+ (sizeof (n) == 1 ? stdc_has_single_bit_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_has_single_bit_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_has_single_bit_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_has_single_bit_ul (n) \
+ : stdc_has_single_bit_ull (n)))
+
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_width_uc (unsigned char n)
+{
+ return 8 * sizeof n - stdc_leading_zeros_uc (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_width_us (unsigned short int n)
+{
+ return 8 * sizeof n - stdc_leading_zeros_us (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_width_ui (unsigned int n)
+{
+ return 8 * sizeof n - stdc_leading_zeros_ui (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_width_ul (unsigned long int n)
+{
+ return 8 * sizeof n - stdc_leading_zeros_ul (n);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_width_ull (unsigned long long int n)
+{
+ return 8 * sizeof n - stdc_leading_zeros_ull (n);
+}
+
+#define stdc_bit_width(n) \
+ (sizeof (n) == 1 ? stdc_bit_width_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_width_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_bit_width_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_bit_width_ul (n) \
+ : stdc_bit_width_ull (n))
+
+
+_GL_STDBIT_INLINE unsigned char
+stdc_bit_floor_uc (unsigned char n)
+{
+ return n ? 1u << (stdc_bit_width_uc (n) - 1) : 0;
+}
+
+_GL_STDBIT_INLINE unsigned short int
+stdc_bit_floor_us (unsigned short int n)
+{
+ return n ? 1u << (stdc_bit_width_us (n) - 1) : 0;
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_floor_ui (unsigned int n)
+{
+ return n ? 1u << (stdc_bit_width_ui (n) - 1) : 0;
+}
+
+_GL_STDBIT_INLINE unsigned long int
+stdc_bit_floor_ul (unsigned long int n)
+{
+ return n ? 1ul << (stdc_bit_width_ul (n) - 1) : 0;
+}
+
+_GL_STDBIT_INLINE unsigned long long int
+stdc_bit_floor_ull (unsigned long long int n)
+{
+ return n ? 1ull << (stdc_bit_width_ull (n) - 1) : 0;
+}
+
+#define stdc_bit_floor(n) \
+ (_GL_STDBIT_TYPEOF_CAST \
+ (n, \
+ (sizeof (n) == 1 ? stdc_bit_floor_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_floor_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_bit_floor_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_bit_floor_ul (n) \
+ : stdc_bit_floor_ull (n))))
+
+
+_GL_STDBIT_INLINE unsigned char
+stdc_bit_ceil_uc (unsigned char n)
+{
+ return n <= 1 ? 1 : 2u << (stdc_bit_width_uc (n - 1) - 1);
+}
+
+_GL_STDBIT_INLINE unsigned short int
+stdc_bit_ceil_us (unsigned short int n)
+{
+ return n <= 1 ? 1 : 2u << (stdc_bit_width_us (n - 1) - 1);
+}
+
+_GL_STDBIT_INLINE unsigned int
+stdc_bit_ceil_ui (unsigned int n)
+{
+ return n <= 1 ? 1 : 2u << (stdc_bit_width_ui (n - 1) - 1);
+}
+
+_GL_STDBIT_INLINE unsigned long int
+stdc_bit_ceil_ul (unsigned long int n)
+{
+ return n <= 1 ? 1 : 2ul << (stdc_bit_width_ul (n - 1) - 1);
+}
+
+_GL_STDBIT_INLINE unsigned long long int
+stdc_bit_ceil_ull (unsigned long long int n)
+{
+ return n <= 1 ? 1 : 2ull << (stdc_bit_width_ull (n - 1) - 1);
+}
+
+#define stdc_bit_ceil(n) \
+ (_GL_STDBIT_TYPEOF_CAST \
+ (n, \
+ (sizeof (n) == 1 ? stdc_bit_ceil_uc (n) \
+ : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_ceil_us (n) \
+ : sizeof (n) == sizeof 0u ? stdc_bit_ceil_ui (n) \
+ : sizeof (n) == sizeof 0ul ? stdc_bit_ceil_ul (n) \
+ : stdc_bit_ceil_ull (n))))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* STDBIT_H */
diff --git a/m4/stdbit_h.m4 b/m4/stdbit_h.m4
new file mode 100644
index 0000000000..9ce3cb3146
--- /dev/null
+++ b/m4/stdbit_h.m4
@@ -0,0 +1,19 @@
+# stddef_h.m4
+# serial 1
+dnl Copyright 2024 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl A placeholder for <stdbit.h>, for platforms that have issues.
+
+AC_DEFUN_ONCE([gl_STDBIT_H],
+[
+ AC_REQUIRE([gl_BIGENDIAN])
+ AC_CHECK_HEADERS_ONCE([stdbit.h])
+ if test $ac_cv_header_stdbit_h = yes; then
+ GL_GENERATE_STDBIT_H=false
+ else
+ GL_GENERATE_STDBIT_H=true
+ fi
+])
diff --git a/modules/stdbit b/modules/stdbit
new file mode 100644
index 0000000000..6096869774
--- /dev/null
+++ b/modules/stdbit
@@ -0,0 +1,44 @@
+Description:
+A stdbit.h that is like C23.
+
+Files:
+lib/stdbit.c
+lib/stdbit.in.h
+m4/stdbit_h.m4
+
+Depends-on:
+count-leading-zeros [$GL_GENERATE_STDBIT_H]
+count-trailing-zeros [$GL_GENERATE_STDBIT_H]
+count-one-bits [$GL_GENERATE_STDBIT_H]
+stdbool [$GL_GENERATE_STDBIT_H]
+
+configure.ac:
+gl_STDBIT_H
+gl_CONDITIONAL_HEADER([stdbit.h])
+AC_PROG_MKDIR_P
+
+Makefile.am:
+BUILT_SOURCES += $(STDBIT_H)
+
+# We need the following in order to create <stdbit.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDBIT_H
+stdbit.h: stdbit.in.h $(top_builddir)/config.status
+@NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%'
+ $(gl_V_at)cp $(srcdir)/stdbit.in.h $@-t
+ $(AM_V_at)mv $@-t $@
+lib_SOURCES += stdbit.c
+else
+stdbit.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stdbit.h stdbit.h-t
+
+Include:
+<stdbit.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--
2.44.0
- [PATCH 0/4] New stdbit module, for C23 style stdbit.h, Paul Eggert, 2024/05/11
- [PATCH 1/4] stdbit: new module,
Paul Eggert <=
- Re: [PATCH 1/4] stdbit: new module, Collin Funk, 2024/05/12
- Re: [PATCH 1/4] stdbit: new module, Paul Eggert, 2024/05/12
- Re: [PATCH 1/4] stdbit: new module, Collin Funk, 2024/05/12
- Re: [PATCH 1/4] stdbit: new module, Paul Eggert, 2024/05/12
- Re: Python class comments, Bruno Haible, 2024/05/13
- Re: Python class comments, Collin Funk, 2024/05/13
- Re: *.m4 conventions, Bruno Haible, 2024/05/13
- Re: *.m4 conventions, Paul Eggert, 2024/05/13
- Re: *.m4 conventions, Bruno Haible, 2024/05/13
- Re: *.m4 conventions, Paul Eggert, 2024/05/13