From: Paul Eggert Date: Fri, 10 May 2024 00:36:10 +0000 (-0700) Subject: stdbit: new module X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=4de6323d5d20996e51097a90f617cd4404a23eba;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index da40ff41de..1019917f36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2024-05-11 Paul Eggert + + 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 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 +#define _GL_STDBIT_INLINE _GL_EXTERN_INLINE +#include 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 . */ + +/* 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 +#include +#include + +/* 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 , 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 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: + + +License: +LGPLv2+ + +Maintainer: +all