]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdlib/stdbit.h
stdlib: Fix stdbit.h with -Wconversion for older gcc
[thirdparty/glibc.git] / stdlib / stdbit.h
CommitLineData
b34b46b8
JM
1/* ISO C23 Standard: 7.18 - Bit and byte utilities <stdbit.h>.
2 Copyright (C) 2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#ifndef _STDBIT_H
20#define _STDBIT_H 1
21
22#include <features.h>
23#include <bits/endian.h>
24#include <bits/stdint-intn.h>
25#include <bits/stdint-uintn.h>
26#include <bits/stdint-least.h>
27/* In C23, <stdbool.h> defines only an implementation-namespace macro,
28 so is OK to include here. Before C23, including <stdbool.h> allows
29 the header to use bool rather than _Bool unconditionally, and so to
30 compile as C++ (although the type-generic macros are not a good
31 form of type-generic interface for C++). */
32#include <stdbool.h>
33#define __need_size_t
34#include <stddef.h>
35
36#define __STDC_VERSION_STDBIT_H__ 202311L
37
38#define __STDC_ENDIAN_LITTLE__ __LITTLE_ENDIAN
39#define __STDC_ENDIAN_BIG__ __BIG_ENDIAN
40#define __STDC_ENDIAN_NATIVE__ __BYTE_ORDER
41
42__BEGIN_DECLS
43
c8e31fbf
AZ
44/* Use __pacify_uint16 (N) instead of (uint16_t) (N) when the cast is helpful
45 only to pacify older GCC (e.g., GCC 10 -Wconversion) or non-GCC. */
46#if __GNUC_PREREQ (11, 0)
47# define __pacify_uint8(n) (n)
48# define __pacify_uint16(n) (n)
49#else
50# define __pacify_uint8(n) ((uint8_t) (n))
51# define __pacify_uint16(n) ((uint16_t) (n))
52#endif
53
b34b46b8
JM
54/* Count leading zeros. */
55extern unsigned int stdc_leading_zeros_uc (unsigned char __x)
56 __THROW __attribute_const__;
57extern unsigned int stdc_leading_zeros_us (unsigned short __x)
58 __THROW __attribute_const__;
59extern unsigned int stdc_leading_zeros_ui (unsigned int __x)
60 __THROW __attribute_const__;
61extern unsigned int stdc_leading_zeros_ul (unsigned long int __x)
62 __THROW __attribute_const__;
63__extension__
64extern unsigned int stdc_leading_zeros_ull (unsigned long long int __x)
65 __THROW __attribute_const__;
66#define stdc_leading_zeros(x) \
67 (stdc_leading_zeros_ull (x) \
68 - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x))))
69
70#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
71static __always_inline unsigned int
72__clz64_inline (uint64_t __x)
73{
74 return __x == 0 ? 64U : (unsigned int) __builtin_clzll (__x);
75}
76
77static __always_inline unsigned int
78__clz32_inline (uint32_t __x)
79{
80 return __x == 0 ? 32U : (unsigned int) __builtin_clz (__x);
81}
82
83static __always_inline unsigned int
84__clz16_inline (uint16_t __x)
85{
86 return __clz32_inline (__x) - 16;
87}
88
89static __always_inline unsigned int
90__clz8_inline (uint8_t __x)
91{
92 return __clz32_inline (__x) - 24;
93}
94
95# define stdc_leading_zeros_uc(x) (__clz8_inline (x))
96# define stdc_leading_zeros_us(x) (__clz16_inline (x))
97# define stdc_leading_zeros_ui(x) (__clz32_inline (x))
98# if __WORDSIZE == 64
99# define stdc_leading_zeros_ul(x) (__clz64_inline (x))
100# else
101# define stdc_leading_zeros_ul(x) (__clz32_inline (x))
102# endif
103# define stdc_leading_zeros_ull(x) (__clz64_inline (x))
104#endif
105
106/* Count leading ones. */
107extern unsigned int stdc_leading_ones_uc (unsigned char __x)
108 __THROW __attribute_const__;
109extern unsigned int stdc_leading_ones_us (unsigned short __x)
110 __THROW __attribute_const__;
111extern unsigned int stdc_leading_ones_ui (unsigned int __x)
112 __THROW __attribute_const__;
113extern unsigned int stdc_leading_ones_ul (unsigned long int __x)
114 __THROW __attribute_const__;
115__extension__
116extern unsigned int stdc_leading_ones_ull (unsigned long long int __x)
117 __THROW __attribute_const__;
118#define stdc_leading_ones(x) \
119 (stdc_leading_ones_ull ((unsigned long long int) (x) \
120 << 8 * (sizeof (0ULL) - sizeof (x))))
121
122#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
123static __always_inline unsigned int
124__clo64_inline (uint64_t __x)
125{
126 return __clz64_inline (~__x);
127}
128
129static __always_inline unsigned int
130__clo32_inline (uint32_t __x)
131{
132 return __clz32_inline (~__x);
133}
134
135static __always_inline unsigned int
136__clo16_inline (uint16_t __x)
137{
c8e31fbf 138 return __clz16_inline (__pacify_uint16 (~__x));
b34b46b8
JM
139}
140
141static __always_inline unsigned int
142__clo8_inline (uint8_t __x)
143{
c8e31fbf 144 return __clz8_inline (__pacify_uint8 (~__x));
b34b46b8
JM
145}
146
147# define stdc_leading_ones_uc(x) (__clo8_inline (x))
148# define stdc_leading_ones_us(x) (__clo16_inline (x))
149# define stdc_leading_ones_ui(x) (__clo32_inline (x))
150# if __WORDSIZE == 64
151# define stdc_leading_ones_ul(x) (__clo64_inline (x))
152# else
153# define stdc_leading_ones_ul(x) (__clo32_inline (x))
154# endif
155# define stdc_leading_ones_ull(x) (__clo64_inline (x))
156#endif
157
158/* Count trailing zeros. */
159extern unsigned int stdc_trailing_zeros_uc (unsigned char __x)
160 __THROW __attribute_const__;
161extern unsigned int stdc_trailing_zeros_us (unsigned short __x)
162 __THROW __attribute_const__;
163extern unsigned int stdc_trailing_zeros_ui (unsigned int __x)
164 __THROW __attribute_const__;
165extern unsigned int stdc_trailing_zeros_ul (unsigned long int __x)
166 __THROW __attribute_const__;
167__extension__
168extern unsigned int stdc_trailing_zeros_ull (unsigned long long int __x)
169 __THROW __attribute_const__;
170#define stdc_trailing_zeros(x) \
171 (sizeof (x) == 8 ? stdc_trailing_zeros_ull (x) \
172 : sizeof (x) == 4 ? stdc_trailing_zeros_ui (x) \
173 : sizeof (x) == 2 ? stdc_trailing_zeros_us (x) \
174 : stdc_trailing_zeros_uc (x))
175
176#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
177static __always_inline unsigned int
178__ctz64_inline (uint64_t __x)
179{
180 return __x == 0 ? 64U : (unsigned int) __builtin_ctzll (__x);
181}
182
183static __always_inline unsigned int
184__ctz32_inline (uint32_t __x)
185{
186 return __x == 0 ? 32U : (unsigned int) __builtin_ctz (__x);
187}
188
189static __always_inline unsigned int
190__ctz16_inline (uint16_t __x)
191{
192 return __x == 0 ? 16U : (unsigned int) __builtin_ctz (__x);
193}
194
195static __always_inline unsigned int
196__ctz8_inline (uint8_t __x)
197{
198 return __x == 0 ? 8U : (unsigned int) __builtin_ctz (__x);
199}
200
201# define stdc_trailing_zeros_uc(x) (__ctz8_inline (x))
202# define stdc_trailing_zeros_us(x) (__ctz16_inline (x))
203# define stdc_trailing_zeros_ui(x) (__ctz32_inline (x))
204# if __WORDSIZE == 64
205# define stdc_trailing_zeros_ul(x) (__ctz64_inline (x))
206# else
207# define stdc_trailing_zeros_ul(x) (__ctz32_inline (x))
208# endif
209# define stdc_trailing_zeros_ull(x) (__ctz64_inline (x))
210#endif
211
212/* Count trailing ones. */
213extern unsigned int stdc_trailing_ones_uc (unsigned char __x)
214 __THROW __attribute_const__;
215extern unsigned int stdc_trailing_ones_us (unsigned short __x)
216 __THROW __attribute_const__;
217extern unsigned int stdc_trailing_ones_ui (unsigned int __x)
218 __THROW __attribute_const__;
219extern unsigned int stdc_trailing_ones_ul (unsigned long int __x)
220 __THROW __attribute_const__;
221__extension__
222extern unsigned int stdc_trailing_ones_ull (unsigned long long int __x)
223 __THROW __attribute_const__;
224#define stdc_trailing_ones(x) (stdc_trailing_ones_ull (x))
225
226#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
227static __always_inline unsigned int
228__cto64_inline (uint64_t __x)
229{
230 return __ctz64_inline (~__x);
231}
232
233static __always_inline unsigned int
234__cto32_inline (uint32_t __x)
235{
236 return __ctz32_inline (~__x);
237}
238
239static __always_inline unsigned int
240__cto16_inline (uint16_t __x)
241{
c8e31fbf 242 return __ctz16_inline (__pacify_uint16 (~__x));
b34b46b8
JM
243}
244
245static __always_inline unsigned int
246__cto8_inline (uint8_t __x)
247{
c8e31fbf 248 return __ctz8_inline (__pacify_uint8 (~__x));
b34b46b8
JM
249}
250
251# define stdc_trailing_ones_uc(x) (__cto8_inline (x))
252# define stdc_trailing_ones_us(x) (__cto16_inline (x))
253# define stdc_trailing_ones_ui(x) (__cto32_inline (x))
254# if __WORDSIZE == 64
255# define stdc_trailing_ones_ul(x) (__cto64_inline (x))
256# else
257# define stdc_trailing_ones_ul(x) (__cto32_inline (x))
258# endif
259# define stdc_trailing_ones_ull(x) (__cto64_inline (x))
260#endif
261
262/* First leading zero. */
263extern unsigned int stdc_first_leading_zero_uc (unsigned char __x)
264 __THROW __attribute_const__;
265extern unsigned int stdc_first_leading_zero_us (unsigned short __x)
266 __THROW __attribute_const__;
267extern unsigned int stdc_first_leading_zero_ui (unsigned int __x)
268 __THROW __attribute_const__;
269extern unsigned int stdc_first_leading_zero_ul (unsigned long int __x)
270 __THROW __attribute_const__;
271__extension__
272extern unsigned int stdc_first_leading_zero_ull (unsigned long long int __x)
273 __THROW __attribute_const__;
274#define stdc_first_leading_zero(x) \
275 (sizeof (x) == 8 ? stdc_first_leading_zero_ull (x) \
276 : sizeof (x) == 4 ? stdc_first_leading_zero_ui (x) \
277 : sizeof (x) == 2 ? stdc_first_leading_zero_us (x) \
278 : stdc_first_leading_zero_uc (x))
279
280#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
281static __always_inline unsigned int
282__flz64_inline (uint64_t __x)
283{
284 return __x == (uint64_t) -1 ? 0 : 1 + __clo64_inline (__x);
285}
286
287static __always_inline unsigned int
288__flz32_inline (uint32_t __x)
289{
290 return __x == (uint32_t) -1 ? 0 : 1 + __clo32_inline (__x);
291}
292
293static __always_inline unsigned int
294__flz16_inline (uint16_t __x)
295{
296 return __x == (uint16_t) -1 ? 0 : 1 + __clo16_inline (__x);
297}
298
299static __always_inline unsigned int
300__flz8_inline (uint8_t __x)
301{
302 return __x == (uint8_t) -1 ? 0 : 1 + __clo8_inline (__x);
303}
304
305# define stdc_first_leading_zero_uc(x) (__flz8_inline (x))
306# define stdc_first_leading_zero_us(x) (__flz16_inline (x))
307# define stdc_first_leading_zero_ui(x) (__flz32_inline (x))
308# if __WORDSIZE == 64
309# define stdc_first_leading_zero_ul(x) (__flz64_inline (x))
310# else
311# define stdc_first_leading_zero_ul(x) (__flz32_inline (x))
312# endif
313# define stdc_first_leading_zero_ull(x) (__flz64_inline (x))
314#endif
315
316/* First leading one. */
317extern unsigned int stdc_first_leading_one_uc (unsigned char __x)
318 __THROW __attribute_const__;
319extern unsigned int stdc_first_leading_one_us (unsigned short __x)
320 __THROW __attribute_const__;
321extern unsigned int stdc_first_leading_one_ui (unsigned int __x)
322 __THROW __attribute_const__;
323extern unsigned int stdc_first_leading_one_ul (unsigned long int __x)
324 __THROW __attribute_const__;
325__extension__
326extern unsigned int stdc_first_leading_one_ull (unsigned long long int __x)
327 __THROW __attribute_const__;
328#define stdc_first_leading_one(x) \
329 (sizeof (x) == 8 ? stdc_first_leading_one_ull (x) \
330 : sizeof (x) == 4 ? stdc_first_leading_one_ui (x) \
331 : sizeof (x) == 2 ? stdc_first_leading_one_us (x) \
332 : stdc_first_leading_one_uc (x))
333
334#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
335static __always_inline unsigned int
336__flo64_inline (uint64_t __x)
337{
338 return __x == 0 ? 0 : 1 + __clz64_inline (__x);
339}
340
341static __always_inline unsigned int
342__flo32_inline (uint32_t __x)
343{
344 return __x == 0 ? 0 : 1 + __clz32_inline (__x);
345}
346
347static __always_inline unsigned int
348__flo16_inline (uint16_t __x)
349{
350 return __x == 0 ? 0 : 1 + __clz16_inline (__x);
351}
352
353static __always_inline unsigned int
354__flo8_inline (uint8_t __x)
355{
356 return __x == 0 ? 0 : 1 + __clz8_inline (__x);
357}
358
359# define stdc_first_leading_one_uc(x) (__flo8_inline (x))
360# define stdc_first_leading_one_us(x) (__flo16_inline (x))
361# define stdc_first_leading_one_ui(x) (__flo32_inline (x))
362# if __WORDSIZE == 64
363# define stdc_first_leading_one_ul(x) (__flo64_inline (x))
364# else
365# define stdc_first_leading_one_ul(x) (__flo32_inline (x))
366# endif
367# define stdc_first_leading_one_ull(x) (__flo64_inline (x))
368#endif
369
370/* First trailing zero. */
371extern unsigned int stdc_first_trailing_zero_uc (unsigned char __x)
372 __THROW __attribute_const__;
373extern unsigned int stdc_first_trailing_zero_us (unsigned short __x)
374 __THROW __attribute_const__;
375extern unsigned int stdc_first_trailing_zero_ui (unsigned int __x)
376 __THROW __attribute_const__;
377extern unsigned int stdc_first_trailing_zero_ul (unsigned long int __x)
378 __THROW __attribute_const__;
379__extension__
380extern unsigned int stdc_first_trailing_zero_ull (unsigned long long int __x)
381 __THROW __attribute_const__;
382#define stdc_first_trailing_zero(x) \
383 (sizeof (x) == 8 ? stdc_first_trailing_zero_ull (x) \
384 : sizeof (x) == 4 ? stdc_first_trailing_zero_ui (x) \
385 : sizeof (x) == 2 ? stdc_first_trailing_zero_us (x) \
386 : stdc_first_trailing_zero_uc (x))
387
388#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
389static __always_inline unsigned int
390__ftz64_inline (uint64_t __x)
391{
392 return __x == (uint64_t) -1 ? 0 : 1 + __cto64_inline (__x);
393}
394
395static __always_inline unsigned int
396__ftz32_inline (uint32_t __x)
397{
398 return __x == (uint32_t) -1 ? 0 : 1 + __cto32_inline (__x);
399}
400
401static __always_inline unsigned int
402__ftz16_inline (uint16_t __x)
403{
404 return __x == (uint16_t) -1 ? 0 : 1 + __cto16_inline (__x);
405}
406
407static __always_inline unsigned int
408__ftz8_inline (uint8_t __x)
409{
410 return __x == (uint8_t) -1 ? 0 : 1 + __cto8_inline (__x);
411}
412
413# define stdc_first_trailing_zero_uc(x) (__ftz8_inline (x))
414# define stdc_first_trailing_zero_us(x) (__ftz16_inline (x))
415# define stdc_first_trailing_zero_ui(x) (__ftz32_inline (x))
416# if __WORDSIZE == 64
417# define stdc_first_trailing_zero_ul(x) (__ftz64_inline (x))
418# else
419# define stdc_first_trailing_zero_ul(x) (__ftz32_inline (x))
420# endif
421# define stdc_first_trailing_zero_ull(x) (__ftz64_inline (x))
422#endif
423
424/* First trailing one. */
425extern unsigned int stdc_first_trailing_one_uc (unsigned char __x)
426 __THROW __attribute_const__;
427extern unsigned int stdc_first_trailing_one_us (unsigned short __x)
428 __THROW __attribute_const__;
429extern unsigned int stdc_first_trailing_one_ui (unsigned int __x)
430 __THROW __attribute_const__;
431extern unsigned int stdc_first_trailing_one_ul (unsigned long int __x)
432 __THROW __attribute_const__;
433__extension__
434extern unsigned int stdc_first_trailing_one_ull (unsigned long long int __x)
435 __THROW __attribute_const__;
436#define stdc_first_trailing_one(x) \
437 (sizeof (x) == 8 ? stdc_first_trailing_one_ull (x) \
438 : sizeof (x) == 4 ? stdc_first_trailing_one_ui (x) \
439 : sizeof (x) == 2 ? stdc_first_trailing_one_us (x) \
440 : stdc_first_trailing_one_uc (x))
441
442#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
443static __always_inline unsigned int
444__fto64_inline (uint64_t __x)
445{
446 return __x == 0 ? 0 : 1 + __ctz64_inline (__x);
447}
448
449static __always_inline unsigned int
450__fto32_inline (uint32_t __x)
451{
452 return __x == 0 ? 0 : 1 + __ctz32_inline (__x);
453}
454
455static __always_inline unsigned int
456__fto16_inline (uint16_t __x)
457{
458 return __x == 0 ? 0 : 1 + __ctz16_inline (__x);
459}
460
461static __always_inline unsigned int
462__fto8_inline (uint8_t __x)
463{
464 return __x == 0 ? 0 : 1 + __ctz8_inline (__x);
465}
466
467# define stdc_first_trailing_one_uc(x) (__fto8_inline (x))
468# define stdc_first_trailing_one_us(x) (__fto16_inline (x))
469# define stdc_first_trailing_one_ui(x) (__fto32_inline (x))
470# if __WORDSIZE == 64
471# define stdc_first_trailing_one_ul(x) (__fto64_inline (x))
472# else
473# define stdc_first_trailing_one_ul(x) (__fto32_inline (x))
474# endif
475# define stdc_first_trailing_one_ull(x) (__fto64_inline (x))
476#endif
477
478/* Count zeros. */
479extern unsigned int stdc_count_zeros_uc (unsigned char __x)
480 __THROW __attribute_const__;
481extern unsigned int stdc_count_zeros_us (unsigned short __x)
482 __THROW __attribute_const__;
483extern unsigned int stdc_count_zeros_ui (unsigned int __x)
484 __THROW __attribute_const__;
485extern unsigned int stdc_count_zeros_ul (unsigned long int __x)
486 __THROW __attribute_const__;
487__extension__
488extern unsigned int stdc_count_zeros_ull (unsigned long long int __x)
489 __THROW __attribute_const__;
490#define stdc_count_zeros(x) \
491 (stdc_count_zeros_ull (x) \
492 - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x))))
493
494#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll)
495static __always_inline unsigned int
496__cz64_inline (uint64_t __x)
497{
498 return 64U - (unsigned int) __builtin_popcountll (__x);
499}
500
501static __always_inline unsigned int
502__cz32_inline (uint32_t __x)
503{
504 return 32U - (unsigned int) __builtin_popcount (__x);
505}
506
507static __always_inline unsigned int
508__cz16_inline (uint16_t __x)
509{
510 return 16U - (unsigned int) __builtin_popcount (__x);
511}
512
513static __always_inline unsigned int
514__cz8_inline (uint8_t __x)
515{
516 return 8U - (unsigned int) __builtin_popcount (__x);
517}
518
519# define stdc_count_zeros_uc(x) (__cz8_inline (x))
520# define stdc_count_zeros_us(x) (__cz16_inline (x))
521# define stdc_count_zeros_ui(x) (__cz32_inline (x))
522# if __WORDSIZE == 64
523# define stdc_count_zeros_ul(x) (__cz64_inline (x))
524# else
525# define stdc_count_zeros_ul(x) (__cz32_inline (x))
526# endif
527# define stdc_count_zeros_ull(x) (__cz64_inline (x))
528#endif
529
530/* Count ones. */
531extern unsigned int stdc_count_ones_uc (unsigned char __x)
532 __THROW __attribute_const__;
533extern unsigned int stdc_count_ones_us (unsigned short __x)
534 __THROW __attribute_const__;
535extern unsigned int stdc_count_ones_ui (unsigned int __x)
536 __THROW __attribute_const__;
537extern unsigned int stdc_count_ones_ul (unsigned long int __x)
538 __THROW __attribute_const__;
539__extension__
540extern unsigned int stdc_count_ones_ull (unsigned long long int __x)
541 __THROW __attribute_const__;
542#define stdc_count_ones(x) (stdc_count_ones_ull (x))
543
544#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll)
545static __always_inline unsigned int
546__co64_inline (uint64_t __x)
547{
548 return (unsigned int) __builtin_popcountll (__x);
549}
550
551static __always_inline unsigned int
552__co32_inline (uint32_t __x)
553{
554 return (unsigned int) __builtin_popcount (__x);
555}
556
557static __always_inline unsigned int
558__co16_inline (uint16_t __x)
559{
560 return (unsigned int) __builtin_popcount (__x);
561}
562
563static __always_inline unsigned int
564__co8_inline (uint8_t __x)
565{
566 return (unsigned int) __builtin_popcount (__x);
567}
568
569# define stdc_count_ones_uc(x) (__co8_inline (x))
570# define stdc_count_ones_us(x) (__co16_inline (x))
571# define stdc_count_ones_ui(x) (__co32_inline (x))
572# if __WORDSIZE == 64
573# define stdc_count_ones_ul(x) (__co64_inline (x))
574# else
575# define stdc_count_ones_ul(x) (__co32_inline (x))
576# endif
577# define stdc_count_ones_ull(x) (__co64_inline (x))
578#endif
579
580/* Single-bit check. */
581extern bool stdc_has_single_bit_uc (unsigned char __x)
582 __THROW __attribute_const__;
583extern bool stdc_has_single_bit_us (unsigned short __x)
584 __THROW __attribute_const__;
585extern bool stdc_has_single_bit_ui (unsigned int __x)
586 __THROW __attribute_const__;
587extern bool stdc_has_single_bit_ul (unsigned long int __x)
588 __THROW __attribute_const__;
589__extension__
590extern bool stdc_has_single_bit_ull (unsigned long long int __x)
591 __THROW __attribute_const__;
592#define stdc_has_single_bit(x) \
593 ((bool) (sizeof (x) <= sizeof (unsigned int) \
594 ? stdc_has_single_bit_ui (x) \
595 : stdc_has_single_bit_ull (x)))
596
597static __always_inline bool
598__hsb64_inline (uint64_t __x)
599{
600 return (__x ^ (__x - 1)) > __x - 1;
601}
602
603static __always_inline bool
604__hsb32_inline (uint32_t __x)
605{
606 return (__x ^ (__x - 1)) > __x - 1;
607}
608
609static __always_inline bool
610__hsb16_inline (uint16_t __x)
611{
612 return (__x ^ (__x - 1)) > __x - 1;
613}
614
615static __always_inline bool
616__hsb8_inline (uint8_t __x)
617{
618 return (__x ^ (__x - 1)) > __x - 1;
619}
620
621#define stdc_has_single_bit_uc(x) (__hsb8_inline (x))
622#define stdc_has_single_bit_us(x) (__hsb16_inline (x))
623#define stdc_has_single_bit_ui(x) (__hsb32_inline (x))
624#if __WORDSIZE == 64
625# define stdc_has_single_bit_ul(x) (__hsb64_inline (x))
626#else
627# define stdc_has_single_bit_ul(x) (__hsb32_inline (x))
628#endif
629#define stdc_has_single_bit_ull(x) (__hsb64_inline (x))
630
631/* Bit width. */
632extern unsigned int stdc_bit_width_uc (unsigned char __x)
633 __THROW __attribute_const__;
634extern unsigned int stdc_bit_width_us (unsigned short __x)
635 __THROW __attribute_const__;
636extern unsigned int stdc_bit_width_ui (unsigned int __x)
637 __THROW __attribute_const__;
638extern unsigned int stdc_bit_width_ul (unsigned long int __x)
639 __THROW __attribute_const__;
640__extension__
641extern unsigned int stdc_bit_width_ull (unsigned long long int __x)
642 __THROW __attribute_const__;
643#define stdc_bit_width(x) (stdc_bit_width_ull (x))
644
645#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
646static __always_inline unsigned int
647__bw64_inline (uint64_t __x)
648{
649 return 64 - __clz64_inline (__x);
650}
651
652static __always_inline unsigned int
653__bw32_inline (uint32_t __x)
654{
655 return 32 - __clz32_inline (__x);
656}
657
658static __always_inline unsigned int
659__bw16_inline (uint16_t __x)
660{
661 return 16 - __clz16_inline (__x);
662}
663
664static __always_inline unsigned int
665__bw8_inline (uint8_t __x)
666{
667 return 8 - __clz8_inline (__x);
668}
669
670# define stdc_bit_width_uc(x) (__bw8_inline (x))
671# define stdc_bit_width_us(x) (__bw16_inline (x))
672# define stdc_bit_width_ui(x) (__bw32_inline (x))
673# if __WORDSIZE == 64
674# define stdc_bit_width_ul(x) (__bw64_inline (x))
675# else
676# define stdc_bit_width_ul(x) (__bw32_inline (x))
677# endif
678# define stdc_bit_width_ull(x) (__bw64_inline (x))
679#endif
680
681/* Bit floor. */
682extern unsigned char stdc_bit_floor_uc (unsigned char __x)
683 __THROW __attribute_const__;
684extern unsigned short stdc_bit_floor_us (unsigned short __x)
685 __THROW __attribute_const__;
686extern unsigned int stdc_bit_floor_ui (unsigned int __x)
687 __THROW __attribute_const__;
688extern unsigned long int stdc_bit_floor_ul (unsigned long int __x)
689 __THROW __attribute_const__;
690__extension__
691extern unsigned long long int stdc_bit_floor_ull (unsigned long long int __x)
692 __THROW __attribute_const__;
693#define stdc_bit_floor(x) ((__typeof (x)) stdc_bit_floor_ull (x))
694
695#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
696static __always_inline uint64_t
697__bf64_inline (uint64_t __x)
698{
699 return __x == 0 ? 0 : ((uint64_t) 1) << (__bw64_inline (__x) - 1);
700}
701
702static __always_inline uint32_t
703__bf32_inline (uint32_t __x)
704{
705 return __x == 0 ? 0 : ((uint32_t) 1) << (__bw32_inline (__x) - 1);
706}
707
708static __always_inline uint16_t
709__bf16_inline (uint16_t __x)
710{
c8e31fbf
AZ
711 return __pacify_uint16 (__x == 0
712 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1));
b34b46b8
JM
713}
714
715static __always_inline uint8_t
716__bf8_inline (uint8_t __x)
717{
c8e31fbf
AZ
718 return __pacify_uint8 (__x == 0
719 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1));
b34b46b8
JM
720}
721
722# define stdc_bit_floor_uc(x) ((unsigned char) __bf8_inline (x))
723# define stdc_bit_floor_us(x) ((unsigned short) __bf16_inline (x))
724# define stdc_bit_floor_ui(x) ((unsigned int) __bf32_inline (x))
725# if __WORDSIZE == 64
726# define stdc_bit_floor_ul(x) ((unsigned long int) __bf64_inline (x))
727# else
728# define stdc_bit_floor_ul(x) ((unsigned long int) __bf32_inline (x))
729# endif
730# define stdc_bit_floor_ull(x) ((unsigned long long int) __bf64_inline (x))
731#endif
732
733/* Bit ceiling. */
734extern unsigned char stdc_bit_ceil_uc (unsigned char __x)
735 __THROW __attribute_const__;
736extern unsigned short stdc_bit_ceil_us (unsigned short __x)
737 __THROW __attribute_const__;
738extern unsigned int stdc_bit_ceil_ui (unsigned int __x)
739 __THROW __attribute_const__;
740extern unsigned long int stdc_bit_ceil_ul (unsigned long int __x)
741 __THROW __attribute_const__;
742__extension__
743extern unsigned long long int stdc_bit_ceil_ull (unsigned long long int __x)
744 __THROW __attribute_const__;
745#define stdc_bit_ceil(x) ((__typeof (x)) stdc_bit_ceil_ull (x))
746
747#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
748static __always_inline uint64_t
749__bc64_inline (uint64_t __x)
750{
751 return __x <= 1 ? 1 : ((uint64_t) 2) << (__bw64_inline (__x - 1) - 1);
752}
753
754static __always_inline uint32_t
755__bc32_inline (uint32_t __x)
756{
757 return __x <= 1 ? 1 : ((uint32_t) 2) << (__bw32_inline (__x - 1) - 1);
758}
759
760static __always_inline uint16_t
761__bc16_inline (uint16_t __x)
762{
c8e31fbf
AZ
763 return __pacify_uint16 (__x <= 1
764 ? 1
765 : ((uint16_t) 2)
766 << (__bw16_inline ((uint16_t) (__x - 1)) - 1));
b34b46b8
JM
767}
768
769static __always_inline uint8_t
770__bc8_inline (uint8_t __x)
771{
c8e31fbf
AZ
772 return __pacify_uint8 (__x <= 1
773 ? 1
774 : ((uint8_t) 2)
775 << (__bw8_inline ((uint8_t) (__x - 1)) - 1));
b34b46b8
JM
776}
777
778# define stdc_bit_ceil_uc(x) ((unsigned char) __bc8_inline (x))
779# define stdc_bit_ceil_us(x) ((unsigned short) __bc16_inline (x))
780# define stdc_bit_ceil_ui(x) ((unsigned int) __bc32_inline (x))
781# if __WORDSIZE == 64
782# define stdc_bit_ceil_ul(x) ((unsigned long int) __bc64_inline (x))
783# else
784# define stdc_bit_ceil_ul(x) ((unsigned long int) __bc32_inline (x))
785# endif
786# define stdc_bit_ceil_ull(x) ((unsigned long long int) __bc64_inline (x))
787#endif
788
789__END_DECLS
790
791#endif /* _STDBIT_H */