]> git.ipfire.org Git - thirdparty/glibc.git/blob - stdlib/stdbit.h
61165dd72592b87721bd6e1601f3b51d4289df8f
[thirdparty/glibc.git] / stdlib / stdbit.h
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
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
54 /* Count leading zeros. */
55 extern unsigned int stdc_leading_zeros_uc (unsigned char __x)
56 __THROW __attribute_const__;
57 extern unsigned int stdc_leading_zeros_us (unsigned short __x)
58 __THROW __attribute_const__;
59 extern unsigned int stdc_leading_zeros_ui (unsigned int __x)
60 __THROW __attribute_const__;
61 extern unsigned int stdc_leading_zeros_ul (unsigned long int __x)
62 __THROW __attribute_const__;
63 __extension__
64 extern 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)
71 static __always_inline unsigned int
72 __clz64_inline (uint64_t __x)
73 {
74 return __x == 0 ? 64U : (unsigned int) __builtin_clzll (__x);
75 }
76
77 static __always_inline unsigned int
78 __clz32_inline (uint32_t __x)
79 {
80 return __x == 0 ? 32U : (unsigned int) __builtin_clz (__x);
81 }
82
83 static __always_inline unsigned int
84 __clz16_inline (uint16_t __x)
85 {
86 return __clz32_inline (__x) - 16;
87 }
88
89 static __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. */
107 extern unsigned int stdc_leading_ones_uc (unsigned char __x)
108 __THROW __attribute_const__;
109 extern unsigned int stdc_leading_ones_us (unsigned short __x)
110 __THROW __attribute_const__;
111 extern unsigned int stdc_leading_ones_ui (unsigned int __x)
112 __THROW __attribute_const__;
113 extern unsigned int stdc_leading_ones_ul (unsigned long int __x)
114 __THROW __attribute_const__;
115 __extension__
116 extern 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)
123 static __always_inline unsigned int
124 __clo64_inline (uint64_t __x)
125 {
126 return __clz64_inline (~__x);
127 }
128
129 static __always_inline unsigned int
130 __clo32_inline (uint32_t __x)
131 {
132 return __clz32_inline (~__x);
133 }
134
135 static __always_inline unsigned int
136 __clo16_inline (uint16_t __x)
137 {
138 return __clz16_inline (__pacify_uint16 (~__x));
139 }
140
141 static __always_inline unsigned int
142 __clo8_inline (uint8_t __x)
143 {
144 return __clz8_inline (__pacify_uint8 (~__x));
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. */
159 extern unsigned int stdc_trailing_zeros_uc (unsigned char __x)
160 __THROW __attribute_const__;
161 extern unsigned int stdc_trailing_zeros_us (unsigned short __x)
162 __THROW __attribute_const__;
163 extern unsigned int stdc_trailing_zeros_ui (unsigned int __x)
164 __THROW __attribute_const__;
165 extern unsigned int stdc_trailing_zeros_ul (unsigned long int __x)
166 __THROW __attribute_const__;
167 __extension__
168 extern 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)
177 static __always_inline unsigned int
178 __ctz64_inline (uint64_t __x)
179 {
180 return __x == 0 ? 64U : (unsigned int) __builtin_ctzll (__x);
181 }
182
183 static __always_inline unsigned int
184 __ctz32_inline (uint32_t __x)
185 {
186 return __x == 0 ? 32U : (unsigned int) __builtin_ctz (__x);
187 }
188
189 static __always_inline unsigned int
190 __ctz16_inline (uint16_t __x)
191 {
192 return __x == 0 ? 16U : (unsigned int) __builtin_ctz (__x);
193 }
194
195 static __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. */
213 extern unsigned int stdc_trailing_ones_uc (unsigned char __x)
214 __THROW __attribute_const__;
215 extern unsigned int stdc_trailing_ones_us (unsigned short __x)
216 __THROW __attribute_const__;
217 extern unsigned int stdc_trailing_ones_ui (unsigned int __x)
218 __THROW __attribute_const__;
219 extern unsigned int stdc_trailing_ones_ul (unsigned long int __x)
220 __THROW __attribute_const__;
221 __extension__
222 extern 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)
227 static __always_inline unsigned int
228 __cto64_inline (uint64_t __x)
229 {
230 return __ctz64_inline (~__x);
231 }
232
233 static __always_inline unsigned int
234 __cto32_inline (uint32_t __x)
235 {
236 return __ctz32_inline (~__x);
237 }
238
239 static __always_inline unsigned int
240 __cto16_inline (uint16_t __x)
241 {
242 return __ctz16_inline (__pacify_uint16 (~__x));
243 }
244
245 static __always_inline unsigned int
246 __cto8_inline (uint8_t __x)
247 {
248 return __ctz8_inline (__pacify_uint8 (~__x));
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. */
263 extern unsigned int stdc_first_leading_zero_uc (unsigned char __x)
264 __THROW __attribute_const__;
265 extern unsigned int stdc_first_leading_zero_us (unsigned short __x)
266 __THROW __attribute_const__;
267 extern unsigned int stdc_first_leading_zero_ui (unsigned int __x)
268 __THROW __attribute_const__;
269 extern unsigned int stdc_first_leading_zero_ul (unsigned long int __x)
270 __THROW __attribute_const__;
271 __extension__
272 extern 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)
281 static __always_inline unsigned int
282 __flz64_inline (uint64_t __x)
283 {
284 return __x == (uint64_t) -1 ? 0 : 1 + __clo64_inline (__x);
285 }
286
287 static __always_inline unsigned int
288 __flz32_inline (uint32_t __x)
289 {
290 return __x == (uint32_t) -1 ? 0 : 1 + __clo32_inline (__x);
291 }
292
293 static __always_inline unsigned int
294 __flz16_inline (uint16_t __x)
295 {
296 return __x == (uint16_t) -1 ? 0 : 1 + __clo16_inline (__x);
297 }
298
299 static __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. */
317 extern unsigned int stdc_first_leading_one_uc (unsigned char __x)
318 __THROW __attribute_const__;
319 extern unsigned int stdc_first_leading_one_us (unsigned short __x)
320 __THROW __attribute_const__;
321 extern unsigned int stdc_first_leading_one_ui (unsigned int __x)
322 __THROW __attribute_const__;
323 extern unsigned int stdc_first_leading_one_ul (unsigned long int __x)
324 __THROW __attribute_const__;
325 __extension__
326 extern 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)
335 static __always_inline unsigned int
336 __flo64_inline (uint64_t __x)
337 {
338 return __x == 0 ? 0 : 1 + __clz64_inline (__x);
339 }
340
341 static __always_inline unsigned int
342 __flo32_inline (uint32_t __x)
343 {
344 return __x == 0 ? 0 : 1 + __clz32_inline (__x);
345 }
346
347 static __always_inline unsigned int
348 __flo16_inline (uint16_t __x)
349 {
350 return __x == 0 ? 0 : 1 + __clz16_inline (__x);
351 }
352
353 static __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. */
371 extern unsigned int stdc_first_trailing_zero_uc (unsigned char __x)
372 __THROW __attribute_const__;
373 extern unsigned int stdc_first_trailing_zero_us (unsigned short __x)
374 __THROW __attribute_const__;
375 extern unsigned int stdc_first_trailing_zero_ui (unsigned int __x)
376 __THROW __attribute_const__;
377 extern unsigned int stdc_first_trailing_zero_ul (unsigned long int __x)
378 __THROW __attribute_const__;
379 __extension__
380 extern 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)
389 static __always_inline unsigned int
390 __ftz64_inline (uint64_t __x)
391 {
392 return __x == (uint64_t) -1 ? 0 : 1 + __cto64_inline (__x);
393 }
394
395 static __always_inline unsigned int
396 __ftz32_inline (uint32_t __x)
397 {
398 return __x == (uint32_t) -1 ? 0 : 1 + __cto32_inline (__x);
399 }
400
401 static __always_inline unsigned int
402 __ftz16_inline (uint16_t __x)
403 {
404 return __x == (uint16_t) -1 ? 0 : 1 + __cto16_inline (__x);
405 }
406
407 static __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. */
425 extern unsigned int stdc_first_trailing_one_uc (unsigned char __x)
426 __THROW __attribute_const__;
427 extern unsigned int stdc_first_trailing_one_us (unsigned short __x)
428 __THROW __attribute_const__;
429 extern unsigned int stdc_first_trailing_one_ui (unsigned int __x)
430 __THROW __attribute_const__;
431 extern unsigned int stdc_first_trailing_one_ul (unsigned long int __x)
432 __THROW __attribute_const__;
433 __extension__
434 extern 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)
443 static __always_inline unsigned int
444 __fto64_inline (uint64_t __x)
445 {
446 return __x == 0 ? 0 : 1 + __ctz64_inline (__x);
447 }
448
449 static __always_inline unsigned int
450 __fto32_inline (uint32_t __x)
451 {
452 return __x == 0 ? 0 : 1 + __ctz32_inline (__x);
453 }
454
455 static __always_inline unsigned int
456 __fto16_inline (uint16_t __x)
457 {
458 return __x == 0 ? 0 : 1 + __ctz16_inline (__x);
459 }
460
461 static __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. */
479 extern unsigned int stdc_count_zeros_uc (unsigned char __x)
480 __THROW __attribute_const__;
481 extern unsigned int stdc_count_zeros_us (unsigned short __x)
482 __THROW __attribute_const__;
483 extern unsigned int stdc_count_zeros_ui (unsigned int __x)
484 __THROW __attribute_const__;
485 extern unsigned int stdc_count_zeros_ul (unsigned long int __x)
486 __THROW __attribute_const__;
487 __extension__
488 extern 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)
495 static __always_inline unsigned int
496 __cz64_inline (uint64_t __x)
497 {
498 return 64U - (unsigned int) __builtin_popcountll (__x);
499 }
500
501 static __always_inline unsigned int
502 __cz32_inline (uint32_t __x)
503 {
504 return 32U - (unsigned int) __builtin_popcount (__x);
505 }
506
507 static __always_inline unsigned int
508 __cz16_inline (uint16_t __x)
509 {
510 return 16U - (unsigned int) __builtin_popcount (__x);
511 }
512
513 static __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. */
531 extern unsigned int stdc_count_ones_uc (unsigned char __x)
532 __THROW __attribute_const__;
533 extern unsigned int stdc_count_ones_us (unsigned short __x)
534 __THROW __attribute_const__;
535 extern unsigned int stdc_count_ones_ui (unsigned int __x)
536 __THROW __attribute_const__;
537 extern unsigned int stdc_count_ones_ul (unsigned long int __x)
538 __THROW __attribute_const__;
539 __extension__
540 extern 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)
545 static __always_inline unsigned int
546 __co64_inline (uint64_t __x)
547 {
548 return (unsigned int) __builtin_popcountll (__x);
549 }
550
551 static __always_inline unsigned int
552 __co32_inline (uint32_t __x)
553 {
554 return (unsigned int) __builtin_popcount (__x);
555 }
556
557 static __always_inline unsigned int
558 __co16_inline (uint16_t __x)
559 {
560 return (unsigned int) __builtin_popcount (__x);
561 }
562
563 static __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. */
581 extern bool stdc_has_single_bit_uc (unsigned char __x)
582 __THROW __attribute_const__;
583 extern bool stdc_has_single_bit_us (unsigned short __x)
584 __THROW __attribute_const__;
585 extern bool stdc_has_single_bit_ui (unsigned int __x)
586 __THROW __attribute_const__;
587 extern bool stdc_has_single_bit_ul (unsigned long int __x)
588 __THROW __attribute_const__;
589 __extension__
590 extern 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
597 static __always_inline bool
598 __hsb64_inline (uint64_t __x)
599 {
600 return (__x ^ (__x - 1)) > __x - 1;
601 }
602
603 static __always_inline bool
604 __hsb32_inline (uint32_t __x)
605 {
606 return (__x ^ (__x - 1)) > __x - 1;
607 }
608
609 static __always_inline bool
610 __hsb16_inline (uint16_t __x)
611 {
612 return (__x ^ (__x - 1)) > __x - 1;
613 }
614
615 static __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. */
632 extern unsigned int stdc_bit_width_uc (unsigned char __x)
633 __THROW __attribute_const__;
634 extern unsigned int stdc_bit_width_us (unsigned short __x)
635 __THROW __attribute_const__;
636 extern unsigned int stdc_bit_width_ui (unsigned int __x)
637 __THROW __attribute_const__;
638 extern unsigned int stdc_bit_width_ul (unsigned long int __x)
639 __THROW __attribute_const__;
640 __extension__
641 extern 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)
646 static __always_inline unsigned int
647 __bw64_inline (uint64_t __x)
648 {
649 return 64 - __clz64_inline (__x);
650 }
651
652 static __always_inline unsigned int
653 __bw32_inline (uint32_t __x)
654 {
655 return 32 - __clz32_inline (__x);
656 }
657
658 static __always_inline unsigned int
659 __bw16_inline (uint16_t __x)
660 {
661 return 16 - __clz16_inline (__x);
662 }
663
664 static __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. */
682 extern unsigned char stdc_bit_floor_uc (unsigned char __x)
683 __THROW __attribute_const__;
684 extern unsigned short stdc_bit_floor_us (unsigned short __x)
685 __THROW __attribute_const__;
686 extern unsigned int stdc_bit_floor_ui (unsigned int __x)
687 __THROW __attribute_const__;
688 extern unsigned long int stdc_bit_floor_ul (unsigned long int __x)
689 __THROW __attribute_const__;
690 __extension__
691 extern 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)
696 static __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
702 static __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
708 static __always_inline uint16_t
709 __bf16_inline (uint16_t __x)
710 {
711 return __pacify_uint16 (__x == 0
712 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1));
713 }
714
715 static __always_inline uint8_t
716 __bf8_inline (uint8_t __x)
717 {
718 return __pacify_uint8 (__x == 0
719 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1));
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. */
734 extern unsigned char stdc_bit_ceil_uc (unsigned char __x)
735 __THROW __attribute_const__;
736 extern unsigned short stdc_bit_ceil_us (unsigned short __x)
737 __THROW __attribute_const__;
738 extern unsigned int stdc_bit_ceil_ui (unsigned int __x)
739 __THROW __attribute_const__;
740 extern unsigned long int stdc_bit_ceil_ul (unsigned long int __x)
741 __THROW __attribute_const__;
742 __extension__
743 extern 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)
748 static __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
754 static __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
760 static __always_inline uint16_t
761 __bc16_inline (uint16_t __x)
762 {
763 return __pacify_uint16 (__x <= 1
764 ? 1
765 : ((uint16_t) 2)
766 << (__bw16_inline ((uint16_t) (__x - 1)) - 1));
767 }
768
769 static __always_inline uint8_t
770 __bc8_inline (uint8_t __x)
771 {
772 return __pacify_uint8 (__x <= 1
773 ? 1
774 : ((uint8_t) 2)
775 << (__bw8_inline ((uint8_t) (__x - 1)) - 1));
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 */