mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-26 07:33:47 +00:00
88b0bb4db9
C23's <stdbit.h> in the long run should be better supported than Gnulib's count-one-bits.h and similar headers, so switch to the C23 primitives, with a Gnulib fallback for platforms lacking C23. * admin/merge-gnulib (GNULIB_MODULES): Remove count-leading-zeros, count-one-bits, count-trailing-zeros. Add stdc_bit_width, stdc_count_ones, stdc_trailing_zeros. * lib/count-leading-zeros.c, lib/count-leading-zeros.h: * lib/count-one-bits.c, lib/count-one-bits.h: * lib/count-trailing-zeros.c, lib/count-trailing-zeros.h: Remove. * lib/stdbit.c, lib/stdbit.in.h, lib/stdc_bit_width.c: * lib/stdc_count_ones.c, lib/stdc_leading_zeros.c: * lib/stdc_trailing_zeros.c, m4/stdbit_h.m4: New files, copied from Gnulib. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * src/data.c: Do not include count-one-bits.h, count-trailing-zeros.h. Instead, rely on lisp.h including stdbit.h. (Flogcount, Fbool_vector_count_population) (Fbool_vector_count_consecutive): Use stdbit.h macros instead of count-one-bits.h and count-trailing-zeros.h macros. (shift_right_ull, count_one_bits_word, pre_value) (count_trailing_zero_bits): Remove; no longer needed. * src/lisp.h: Include stdbit.h instead of count-leading-zeros.h. (elogb): Use stdbit.h macro instead of count-leading-zeros.h macro.
1078 lines
29 KiB
C
1078 lines
29 KiB
C
/* 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
|
|
|
|
_GL_INLINE_HEADER_BEGIN
|
|
|
|
#ifndef _GL_STDBIT_INLINE
|
|
# define _GL_STDBIT_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_LEADING_ZEROS_INLINE
|
|
# define _GL_STDC_LEADING_ZEROS_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_LEADING_ONES_INLINE
|
|
# define _GL_STDC_LEADING_ONES_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_TRAILING_ZEROS_INLINE
|
|
# define _GL_STDC_TRAILING_ZEROS_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_TRAILING_ONES_INLINE
|
|
# define _GL_STDC_TRAILING_ONES_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_FIRST_LEADING_ZERO_INLINE
|
|
# define _GL_STDC_FIRST_LEADING_ZERO_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_FIRST_LEADING_ONE_INLINE
|
|
# define _GL_STDC_FIRST_LEADING_ONE_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_FIRST_TRAILING_ZERO_INLINE
|
|
# define _GL_STDC_FIRST_TRAILING_ZERO_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_FIRST_TRAILING_ONE_INLINE
|
|
# define _GL_STDC_FIRST_TRAILING_ONE_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_COUNT_ZEROS_INLINE
|
|
# define _GL_STDC_COUNT_ZEROS_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_COUNT_ONES_INLINE
|
|
# define _GL_STDC_COUNT_ONES_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_HAS_SINGLE_BIT_INLINE
|
|
# define _GL_STDC_HAS_SINGLE_BIT_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_BIT_WIDTH_INLINE
|
|
# define _GL_STDC_BIT_WIDTH_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_BIT_FLOOR_INLINE
|
|
# define _GL_STDC_BIT_FLOOR_INLINE _GL_INLINE
|
|
#endif
|
|
#ifndef _GL_STDC_BIT_CEIL_INLINE
|
|
# define _GL_STDC_BIT_CEIL_INLINE _GL_INLINE
|
|
#endif
|
|
|
|
/* 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
|
|
|
|
|
|
/* ISO C 23 § 7.18.1 General */
|
|
|
|
#define __STDC_VERSION_STDBIT_H__ 202311L
|
|
|
|
|
|
/* ISO C 23 § 7.18.2 Endian */
|
|
|
|
#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
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__
|
|
# define _GL_STDBIT_HAS_BUILTIN_CLZ true
|
|
# define _GL_STDBIT_HAS_BUILTIN_CTZ true
|
|
# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true
|
|
#elif defined __has_builtin
|
|
# if (__has_builtin (__builtin_clz) \
|
|
&& __has_builtin (__builtin_clzl) \
|
|
&& __has_builtin (__builtin_clzll))
|
|
# define _GL_STDBIT_HAS_BUILTIN_CLZ true
|
|
# endif
|
|
# if (__has_builtin (__builtin_ctz) \
|
|
&& __has_builtin (__builtin_ctzl) \
|
|
&& __has_builtin (__builtin_ctzll))
|
|
# define _GL_STDBIT_HAS_BUILTIN_CTZ true
|
|
# endif
|
|
# if (__has_builtin (__builtin_popcount) \
|
|
&& __has_builtin (__builtin_popcountl) \
|
|
&& __has_builtin (__builtin_popcountll))
|
|
# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true
|
|
# endif
|
|
#endif
|
|
|
|
/* Count leading 0 bits of N, even if N is 0. */
|
|
#ifdef _GL_STDBIT_HAS_BUILTIN_CLZ
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clz (unsigned int n)
|
|
{
|
|
return n ? __builtin_clz (n) : 8 * sizeof n;
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzl (unsigned long int n)
|
|
{
|
|
return n ? __builtin_clzl (n) : 8 * sizeof n;
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzll (unsigned long long int n)
|
|
{
|
|
return n ? __builtin_clzll (n) : 8 * sizeof n;
|
|
}
|
|
#elif defined _MSC_VER
|
|
|
|
/* Declare the few MSVC intrinsics that we need. We prefer not to include
|
|
<intrin.h> because it would pollute the namespace. */
|
|
extern unsigned char _BitScanReverse (unsigned long *, unsigned long);
|
|
# pragma intrinsic (_BitScanReverse)
|
|
# ifdef _M_X64
|
|
extern unsigned char _BitScanReverse64 (unsigned long *, unsigned long long);
|
|
# pragma intrinsic (_BitScanReverse64)
|
|
# endif
|
|
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzl (unsigned long int n)
|
|
{
|
|
unsigned long int r;
|
|
return 8 * sizeof n - (_BitScanReverse (&r, n) ? r + 1 : 0);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clz (unsigned int n)
|
|
{
|
|
return __gl_stdbit_clzl (n) - 8 * (sizeof 0ul - sizeof n);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzll (unsigned long long int n)
|
|
{
|
|
# ifdef _M_X64
|
|
unsigned long int r;
|
|
return 8 * sizeof n - (_BitScanReverse64 (&r, n) ? r + 1 : 0);
|
|
# else
|
|
unsigned long int hi = n >> 32;
|
|
return __gl_stdbit_clzl (hi ? hi : n) + (hi ? 0 : 32);
|
|
# endif
|
|
}
|
|
|
|
#else /* !_MSC_VER */
|
|
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzll (unsigned long long int n)
|
|
{
|
|
int r = 0;
|
|
for (int i = 8 * sizeof n >> 1; 1 << 6 <= i; i >>= 1)
|
|
{
|
|
int a = (1ull << i <= n) * i; n >>= a; r += a;
|
|
}
|
|
int a5 = (0x00000000ffffffff < n) << 5; n >>= a5; r += a5;
|
|
int a4 = (0x000000000000ffff < n) << 4; n >>= a4; r += a4;
|
|
int a3 = (0x00000000000000ff < n) << 3; n >>= a3; r += a3;
|
|
int a2 = (0x000000000000000f < n) << 2; n >>= a2; r += a2;
|
|
return (8 * sizeof n - (1 << 2) - r) + ((0x11112234ull >> (n << 2)) & 0xf);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clz (unsigned int n)
|
|
{
|
|
return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0u);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_clzl (unsigned long int n)
|
|
{
|
|
return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0ul);
|
|
}
|
|
#endif
|
|
|
|
/* Count trailing 0 bits of N, even if N is 0. */
|
|
#ifdef _GL_STDBIT_HAS_BUILTIN_CTZ
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctz (unsigned int n)
|
|
{
|
|
return n ? __builtin_ctz (n) : 8 * sizeof n;
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzl (unsigned long int n)
|
|
{
|
|
return n ? __builtin_ctzl (n) : 8 * sizeof n;
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzll (unsigned long long int n)
|
|
{
|
|
return n ? __builtin_ctzll (n) : 8 * sizeof n;
|
|
}
|
|
#elif defined _MSC_VER
|
|
|
|
/* Declare the few MSVC intrinsics that we need. We prefer not to include
|
|
<intrin.h> because it would pollute the namespace. */
|
|
extern unsigned char _BitScanForward (unsigned long *, unsigned long);
|
|
# pragma intrinsic (_BitScanForward)
|
|
# ifdef _M_X64
|
|
extern unsigned char _BitScanForward64 (unsigned long *, unsigned long long);
|
|
# pragma intrinsic (_BitScanForward64)
|
|
# endif
|
|
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzl (unsigned long int n)
|
|
{
|
|
unsigned long int r;
|
|
return _BitScanForward (&r, n) ? r : 8 * sizeof n;
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctz (unsigned int n)
|
|
{
|
|
return __gl_stdbit_ctzl (n | (1ul << (8 * sizeof n - 1) << 1));
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzll (unsigned long long int n)
|
|
{
|
|
# ifdef _M_X64
|
|
unsigned long int r;
|
|
return _BitScanForward64 (&r, n) ? r : 8 * sizeof n;
|
|
# else
|
|
unsigned int lo = n;
|
|
return __gl_stdbit_ctzl (lo ? lo : n >> 32) + (lo ? 0 : 32);
|
|
# endif
|
|
}
|
|
|
|
#else /* !_MSC_VER */
|
|
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctz (unsigned int n)
|
|
{
|
|
return 8 * sizeof n - (n ? __gl_stdbit_clz (n & -n) + 1 : 0);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzl (unsigned long int n)
|
|
{
|
|
return 8 * sizeof n - (n ? __gl_stdbit_clzl (n & -n) + 1 : 0);
|
|
}
|
|
_GL_STDBIT_INLINE int
|
|
__gl_stdbit_ctzll (unsigned long long int n)
|
|
{
|
|
return 8 * sizeof n - (n ? __gl_stdbit_clzll (n & -n) + 1 : 0);
|
|
}
|
|
#endif
|
|
|
|
#if @GL_STDC_COUNT_ONES@
|
|
/* Count 1 bits in N. */
|
|
# ifdef _GL_STDBIT_HAS_BUILTIN_POPCOUNT
|
|
# define __gl_stdbit_popcount __builtin_popcount
|
|
# define __gl_stdbit_popcountl __builtin_popcountl
|
|
# define __gl_stdbit_popcountll __builtin_popcountll
|
|
# else
|
|
_GL_STDC_COUNT_ONES_INLINE int
|
|
__gl_stdbit_popcount_wide (unsigned long long int n)
|
|
{
|
|
if (sizeof n & (sizeof n - 1))
|
|
{
|
|
/* Use a simple O(log N) loop on theoretical platforms where N's
|
|
width is not a power of 2. */
|
|
int count = 0;
|
|
for (int i = 0; i < 8 * sizeof n; i++, n >>= 1)
|
|
count += n & 1;
|
|
return count;
|
|
}
|
|
else
|
|
{
|
|
/* N's width is a power of 2; count in parallel. */
|
|
unsigned long long int
|
|
max = -1ull,
|
|
x555555 = max / (1 << 1 | 1), /* 0x555555... */
|
|
x333333 = max / (1 << 2 | 1), /* 0x333333... */
|
|
x0f0f0f = max / (1 << 4 | 1), /* 0x0f0f0f... */
|
|
x010101 = max / ((1 << 8) - 1), /* 0x010101... */
|
|
x000_7f = max / 0xffffffffffffffff * 0x7f; /* 0x000000000000007f... */
|
|
n -= (n >> 1) & x555555;
|
|
n = (n & x333333) + ((n >> 2) & x333333);
|
|
n = (n + (n >> 4)) & x0f0f0f;
|
|
|
|
/* If the popcount always fits in 8 bits, multiply so that the
|
|
popcount is in the leading 8 bits of the product; these days
|
|
this is typically faster than the alternative below. */
|
|
if (8 * sizeof n < 1 << 8)
|
|
return n * x010101 >> 8 * (sizeof n - 1);
|
|
|
|
/* N is at least 256 bits wide! Fall back on an O(log log N)
|
|
loop that a compiler could unroll. Unroll the first three
|
|
iterations by hand, to skip some division and masking. This
|
|
is the most we can easily do without hassling with constants
|
|
that a typical-platform compiler would reject. */
|
|
n += n >> (1 << 3);
|
|
n += n >> (1 << 4);
|
|
n += n >> (1 << 5);
|
|
n &= x000_7f;
|
|
for (int i = 64; i < 8 * sizeof n; i <<= 1)
|
|
n = (n + (n >> i)) & max / (1ull << i | 1);
|
|
return n;
|
|
}
|
|
}
|
|
|
|
# ifdef _MSC_VER
|
|
# if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64)
|
|
/* Declare the few MSVC intrinsics that we need. We prefer not to include
|
|
<intrin.h> because it would pollute the namespace. */
|
|
extern void __cpuid (int[4], int);
|
|
# pragma intrinsic (__cpuid)
|
|
extern unsigned int __popcnt (unsigned int);
|
|
# pragma intrinsic (__popcnt)
|
|
# ifdef _M_X64
|
|
extern unsigned long long __popcnt64 (unsigned long long);
|
|
# pragma intrinsic (__popcnt64)
|
|
# else
|
|
_GL_STDC_COUNT_ONES_INLINE int
|
|
__popcnt64 (unsigned long long int n)
|
|
{
|
|
return __popcnt (n >> 32) + __popcnt (n);
|
|
}
|
|
# endif
|
|
# endif
|
|
|
|
/* 1 if supported, -1 if not, 0 if unknown. */
|
|
extern signed char __gl_stdbit_popcount_support;
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE bool
|
|
__gl_stdbit_popcount_supported (void)
|
|
{
|
|
if (!__gl_stdbit_popcount_support)
|
|
{
|
|
/* Do as described in
|
|
<https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64>
|
|
Although Microsoft started requiring POPCNT in MS-Windows 11 24H2,
|
|
we'll be more cautious. */
|
|
int cpu_info[4];
|
|
__cpuid (cpu_info, 1);
|
|
__gl_stdbit_popcount_support = cpu_info[2] & 1 << 23 ? 1 : -1;
|
|
}
|
|
return 0 < __gl_stdbit_popcount_support;
|
|
}
|
|
_GL_STDC_COUNT_ONES_INLINE int
|
|
__gl_stdbit_popcount (unsigned int n)
|
|
{
|
|
return (__gl_stdbit_popcount_supported ()
|
|
? __popcnt (n)
|
|
: __gl_stdbit_popcount_wide (n));
|
|
}
|
|
_GL_STDC_COUNT_ONES_INLINE int
|
|
__gl_stdbit_popcountl (unsigned long int n)
|
|
{
|
|
return (__gl_stdbit_popcount_supported ()
|
|
? __popcnt (n)
|
|
: __gl_stdbit_popcount_wide (n));
|
|
}
|
|
_GL_STDC_COUNT_ONES_INLINE int
|
|
__gl_stdbit_popcountll (unsigned long long int n)
|
|
{
|
|
return (__gl_stdbit_popcount_supported ()
|
|
? __popcnt64 (n)
|
|
: __gl_stdbit_popcount_wide (n));
|
|
}
|
|
# else /* !_MSC_VER */
|
|
# define __gl_stdbit_popcount __gl_stdbit_popcount_wide
|
|
# define __gl_stdbit_popcountl __gl_stdbit_popcount_wide
|
|
# define __gl_stdbit_popcountll __gl_stdbit_popcount_wide
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.3 Count Leading Zeros */
|
|
|
|
#if @GL_STDC_LEADING_ZEROS@
|
|
|
|
_GL_STDC_LEADING_ZEROS_INLINE unsigned int
|
|
stdc_leading_zeros_ui (unsigned int n)
|
|
{
|
|
return __gl_stdbit_clz (n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ZEROS_INLINE unsigned int
|
|
stdc_leading_zeros_uc (unsigned char n)
|
|
{
|
|
return stdc_leading_zeros_ui (n) - 8 * (sizeof 0u - sizeof n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ZEROS_INLINE unsigned int
|
|
stdc_leading_zeros_us (unsigned short int n)
|
|
{
|
|
return stdc_leading_zeros_ui (n) - 8 * (sizeof 0u - sizeof n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ZEROS_INLINE unsigned int
|
|
stdc_leading_zeros_ul (unsigned long int n)
|
|
{
|
|
return __gl_stdbit_clzl (n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ZEROS_INLINE unsigned int
|
|
stdc_leading_zeros_ull (unsigned long long int n)
|
|
{
|
|
return __gl_stdbit_clzll (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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.4 Count Leading Ones */
|
|
|
|
#if @GL_STDC_LEADING_ONES@
|
|
|
|
_GL_STDC_LEADING_ONES_INLINE unsigned int
|
|
stdc_leading_ones_uc (unsigned char n)
|
|
{
|
|
return stdc_leading_zeros_uc (~n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ONES_INLINE unsigned int
|
|
stdc_leading_ones_us (unsigned short int n)
|
|
{
|
|
return stdc_leading_zeros_us (~n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ONES_INLINE unsigned int
|
|
stdc_leading_ones_ui (unsigned int n)
|
|
{
|
|
return stdc_leading_zeros_ui (~n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ONES_INLINE unsigned int
|
|
stdc_leading_ones_ul (unsigned long int n)
|
|
{
|
|
return stdc_leading_zeros_ul (~n);
|
|
}
|
|
|
|
_GL_STDC_LEADING_ONES_INLINE unsigned int
|
|
stdc_leading_ones_ull (unsigned long long int n)
|
|
{
|
|
return stdc_leading_zeros_ull (~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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.5 Count Trailing Zeros */
|
|
|
|
#if @GL_STDC_TRAILING_ZEROS@
|
|
|
|
_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
|
|
stdc_trailing_zeros_ui (unsigned int n)
|
|
{
|
|
return __gl_stdbit_ctz (n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
|
|
stdc_trailing_zeros_uc (unsigned char n)
|
|
{
|
|
return stdc_trailing_zeros_ui (n | (1 + (unsigned char) -1));
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
|
|
stdc_trailing_zeros_us (unsigned short int n)
|
|
{
|
|
return stdc_trailing_zeros_ui (n | (1 + (unsigned short int) -1));
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
|
|
stdc_trailing_zeros_ul (unsigned long int n)
|
|
{
|
|
return __gl_stdbit_ctzl (n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ZEROS_INLINE unsigned int
|
|
stdc_trailing_zeros_ull (unsigned long long int n)
|
|
{
|
|
return __gl_stdbit_ctzll (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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.6 Count Trailing Ones */
|
|
|
|
#if @GL_STDC_TRAILING_ONES@
|
|
|
|
_GL_STDC_TRAILING_ONES_INLINE unsigned int
|
|
stdc_trailing_ones_uc (unsigned char n)
|
|
{
|
|
return stdc_trailing_zeros_uc (~n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ONES_INLINE unsigned int
|
|
stdc_trailing_ones_us (unsigned short int n)
|
|
{
|
|
return stdc_trailing_zeros_us (~n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ONES_INLINE unsigned int
|
|
stdc_trailing_ones_ui (unsigned int n)
|
|
{
|
|
return stdc_trailing_zeros_ui (~n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ONES_INLINE unsigned int
|
|
stdc_trailing_ones_ul (unsigned long int n)
|
|
{
|
|
return stdc_trailing_zeros_ul (~n);
|
|
}
|
|
|
|
_GL_STDC_TRAILING_ONES_INLINE unsigned int
|
|
stdc_trailing_ones_ull (unsigned long long int n)
|
|
{
|
|
return stdc_trailing_zeros_ull (~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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.7 First Leading Zero */
|
|
|
|
#if @GL_STDC_FIRST_LEADING_ZERO@
|
|
|
|
_GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int
|
|
stdc_first_leading_zero_uc (unsigned char n)
|
|
{
|
|
unsigned int count = stdc_leading_ones_uc (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int
|
|
stdc_first_leading_zero_us (unsigned short int n)
|
|
{
|
|
unsigned int count = stdc_leading_ones_us (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int
|
|
stdc_first_leading_zero_ui (unsigned int n)
|
|
{
|
|
unsigned int count = stdc_leading_ones_ui (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int
|
|
stdc_first_leading_zero_ul (unsigned long int n)
|
|
{
|
|
unsigned int count = stdc_leading_ones_ul (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int
|
|
stdc_first_leading_zero_ull (unsigned long long int n)
|
|
{
|
|
unsigned int count = stdc_leading_ones_ull (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
# 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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.8 First Leading One */
|
|
|
|
#if @GL_STDC_FIRST_LEADING_ONE@
|
|
|
|
_GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int
|
|
stdc_first_leading_one_uc (unsigned char n)
|
|
{
|
|
unsigned int count = stdc_leading_zeros_uc (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int
|
|
stdc_first_leading_one_us (unsigned short int n)
|
|
{
|
|
unsigned int count = stdc_leading_zeros_us (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int
|
|
stdc_first_leading_one_ui (unsigned int n)
|
|
{
|
|
unsigned int count = stdc_leading_zeros_ui (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int
|
|
stdc_first_leading_one_ul (unsigned long int n)
|
|
{
|
|
unsigned int count = stdc_leading_zeros_ul (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int
|
|
stdc_first_leading_one_ull (unsigned long long int n)
|
|
{
|
|
unsigned int count = stdc_leading_zeros_ull (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
# 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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.9 First Trailing Zero */
|
|
|
|
#if @GL_STDC_FIRST_TRAILING_ZERO@
|
|
|
|
_GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int
|
|
stdc_first_trailing_zero_uc (unsigned char n)
|
|
{
|
|
unsigned int count = stdc_trailing_ones_uc (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int
|
|
stdc_first_trailing_zero_us (unsigned short int n)
|
|
{
|
|
unsigned int count = stdc_trailing_ones_us (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int
|
|
stdc_first_trailing_zero_ui (unsigned int n)
|
|
{
|
|
unsigned int count = stdc_trailing_ones_ui (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int
|
|
stdc_first_trailing_zero_ul (unsigned long int n)
|
|
{
|
|
unsigned int count = stdc_trailing_ones_ul (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int
|
|
stdc_first_trailing_zero_ull (unsigned long long int n)
|
|
{
|
|
unsigned int count = stdc_trailing_ones_ull (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
# 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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.10 First Trailing One */
|
|
|
|
#if @GL_STDC_FIRST_TRAILING_ONE@
|
|
|
|
_GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int
|
|
stdc_first_trailing_one_uc (unsigned char n)
|
|
{
|
|
unsigned int count = stdc_trailing_zeros_uc (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int
|
|
stdc_first_trailing_one_us (unsigned short int n)
|
|
{
|
|
unsigned int count = stdc_trailing_zeros_us (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int
|
|
stdc_first_trailing_one_ui (unsigned int n)
|
|
{
|
|
unsigned int count = stdc_trailing_zeros_ui (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int
|
|
stdc_first_trailing_one_ul (unsigned long int n)
|
|
{
|
|
unsigned int count = stdc_trailing_zeros_ul (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
_GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int
|
|
stdc_first_trailing_one_ull (unsigned long long int n)
|
|
{
|
|
unsigned int count = stdc_trailing_zeros_ull (n);
|
|
unsigned int bits = 8 * sizeof n;
|
|
return count % bits + (count < bits);
|
|
}
|
|
|
|
#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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.12 Count Ones */
|
|
|
|
#if @GL_STDC_COUNT_ONES@
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE unsigned int
|
|
stdc_count_ones_ui (unsigned int n)
|
|
{
|
|
return __gl_stdbit_popcount (n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE unsigned int
|
|
stdc_count_ones_uc (unsigned char n)
|
|
{
|
|
return stdc_count_ones_ui (n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE unsigned int
|
|
stdc_count_ones_us (unsigned short int n)
|
|
{
|
|
return stdc_count_ones_ui (n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE unsigned int
|
|
stdc_count_ones_ul (unsigned long int n)
|
|
{
|
|
return __gl_stdbit_popcountl (n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ONES_INLINE unsigned int
|
|
stdc_count_ones_ull (unsigned long long int n)
|
|
{
|
|
return __gl_stdbit_popcountll (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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.11 Count Zeros */
|
|
|
|
#if @GL_STDC_COUNT_ZEROS@
|
|
|
|
_GL_STDC_COUNT_ZEROS_INLINE unsigned int
|
|
stdc_count_zeros_uc (unsigned char n)
|
|
{
|
|
return stdc_count_ones_uc (~n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ZEROS_INLINE unsigned int
|
|
stdc_count_zeros_us (unsigned short int n)
|
|
{
|
|
return stdc_count_ones_us (~n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ZEROS_INLINE unsigned int
|
|
stdc_count_zeros_ui (unsigned int n)
|
|
{
|
|
return stdc_count_ones_ui (~n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ZEROS_INLINE unsigned int
|
|
stdc_count_zeros_ul (unsigned long int n)
|
|
{
|
|
return stdc_count_ones_ul (~n);
|
|
}
|
|
|
|
_GL_STDC_COUNT_ZEROS_INLINE unsigned int
|
|
stdc_count_zeros_ull (unsigned long long int n)
|
|
{
|
|
return stdc_count_ones_ull (~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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.13 Single-bit Check */
|
|
|
|
#if @GL_STDC_HAS_SINGLE_BIT@
|
|
|
|
_GL_STDC_HAS_SINGLE_BIT_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_STDC_HAS_SINGLE_BIT_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_STDC_HAS_SINGLE_BIT_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_STDC_HAS_SINGLE_BIT_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_STDC_HAS_SINGLE_BIT_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)))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.14 Bit Width */
|
|
|
|
#if @GL_STDC_BIT_WIDTH@
|
|
|
|
_GL_STDC_BIT_WIDTH_INLINE unsigned int
|
|
stdc_bit_width_uc (unsigned char n)
|
|
{
|
|
return 8 * sizeof n - stdc_leading_zeros_uc (n);
|
|
}
|
|
|
|
_GL_STDC_BIT_WIDTH_INLINE unsigned int
|
|
stdc_bit_width_us (unsigned short int n)
|
|
{
|
|
return 8 * sizeof n - stdc_leading_zeros_us (n);
|
|
}
|
|
|
|
_GL_STDC_BIT_WIDTH_INLINE unsigned int
|
|
stdc_bit_width_ui (unsigned int n)
|
|
{
|
|
return 8 * sizeof n - stdc_leading_zeros_ui (n);
|
|
}
|
|
|
|
_GL_STDC_BIT_WIDTH_INLINE unsigned int
|
|
stdc_bit_width_ul (unsigned long int n)
|
|
{
|
|
return 8 * sizeof n - stdc_leading_zeros_ul (n);
|
|
}
|
|
|
|
_GL_STDC_BIT_WIDTH_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))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.15 Bit Floor */
|
|
|
|
#if @GL_STDC_BIT_FLOOR@
|
|
|
|
_GL_STDC_BIT_FLOOR_INLINE unsigned char
|
|
stdc_bit_floor_uc (unsigned char n)
|
|
{
|
|
return n ? 1u << (stdc_bit_width_uc (n) - 1) : 0;
|
|
}
|
|
|
|
_GL_STDC_BIT_FLOOR_INLINE unsigned short int
|
|
stdc_bit_floor_us (unsigned short int n)
|
|
{
|
|
return n ? 1u << (stdc_bit_width_us (n) - 1) : 0;
|
|
}
|
|
|
|
_GL_STDC_BIT_FLOOR_INLINE unsigned int
|
|
stdc_bit_floor_ui (unsigned int n)
|
|
{
|
|
return n ? 1u << (stdc_bit_width_ui (n) - 1) : 0;
|
|
}
|
|
|
|
_GL_STDC_BIT_FLOOR_INLINE unsigned long int
|
|
stdc_bit_floor_ul (unsigned long int n)
|
|
{
|
|
return n ? 1ul << (stdc_bit_width_ul (n) - 1) : 0;
|
|
}
|
|
|
|
_GL_STDC_BIT_FLOOR_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))))
|
|
|
|
#endif
|
|
|
|
|
|
/* ISO C 23 § 7.18.16 Bit Ceiling */
|
|
|
|
#if @GL_STDC_BIT_CEIL@
|
|
|
|
_GL_STDC_BIT_CEIL_INLINE unsigned char
|
|
stdc_bit_ceil_uc (unsigned char n)
|
|
{
|
|
return n <= 1 ? 1 : 2u << (stdc_bit_width_uc (n - 1) - 1);
|
|
}
|
|
|
|
_GL_STDC_BIT_CEIL_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_STDC_BIT_CEIL_INLINE unsigned int
|
|
stdc_bit_ceil_ui (unsigned int n)
|
|
{
|
|
return n <= 1 ? 1 : 2u << (stdc_bit_width_ui (n - 1) - 1);
|
|
}
|
|
|
|
_GL_STDC_BIT_CEIL_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_STDC_BIT_CEIL_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))))
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
_GL_INLINE_HEADER_END
|
|
|
|
#endif /* STDBIT_H */
|