| /* |
| * BRLTTY - A background process providing access to the console screen (when in |
| * text mode) for a blind person using a refreshable braille display. |
| * |
| * Copyright (C) 1995-2023 by The BRLTTY Developers. |
| * |
| * BRLTTY comes with ABSOLUTELY NO WARRANTY. |
| * |
| * This is free software, placed 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. Please see the file LICENSE-LGPL for details. |
| * |
| * Web Page: http://brltty.app/ |
| * |
| * This software is maintained by Dave Mielke <dave@mielke.cc>. |
| */ |
| |
| #ifndef BRLTTY_INCLUDED_BITMASK |
| #define BRLTTY_INCLUDED_BITMASK |
| |
| #include "prologue.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif /* __cplusplus */ |
| |
| /* These macros are meant for internal use only. */ |
| #define BITMASK_ELEMENT_SIZE(element) (sizeof(element) * 8) |
| #define BITMASK_INDEX(bit,size) ((bit) / (size)) |
| #define BITMASK_SHIFT(bit,size) ((bit) % (size)) |
| #define BITMASK_ELEMENT_COUNT(bits,size) (BITMASK_INDEX((bits)-1, (size)) + 1) |
| #define BITMASK_ELEMENT(name,bit) ((name)[BITMASK_INDEX((bit), BITMASK_ELEMENT_SIZE((name)[0]))]) |
| #define BITMASK_BIT(name,bit) (UINTMAX_C(1) << BITMASK_SHIFT((bit), BITMASK_ELEMENT_SIZE((name)[0]))) |
| |
| /* These macros are for public use. */ |
| #define BITMASK(name,bits,type) unsigned type name[BITMASK_ELEMENT_COUNT((bits), BITMASK_ELEMENT_SIZE(type))] |
| #define BITMASK_SIZE(name) BITMASK_ELEMENT_SIZE((name)) |
| #define BITMASK_ZERO(name) memset((name), 0, sizeof(name)) |
| #define BITMASK_CLEAR(name,bit) (BITMASK_ELEMENT((name), (bit)) &= ~BITMASK_BIT((name), (bit))) |
| #define BITMASK_SET(name,bit) (BITMASK_ELEMENT((name), (bit)) |= BITMASK_BIT((name), (bit))) |
| #define BITMASK_TEST(name,bit) (BITMASK_ELEMENT((name), (bit)) & BITMASK_BIT((name), (bit))) |
| |
| static inline unsigned char |
| popcount (unsigned int bits) { |
| #ifdef HAVE_BUILTIN_POPCOUNT |
| return __builtin_popcount(bits); |
| #else /* __builtin_popcount */ |
| unsigned char count = 0; |
| |
| while (bits) { |
| if (bits & 0X1) count += 1; |
| bits >>= 1; |
| } |
| |
| return count; |
| #endif /* __builtin_popcount */ |
| } |
| |
| #define BITMASK_COUNT(name,variable) \ |
| unsigned int variable = 0; \ |
| for (int i=0; i<ARRAY_COUNT(name); i+=1) variable += popcount(name[i]); |
| |
| #ifdef __cplusplus |
| } |
| #endif /* __cplusplus */ |
| |
| #endif /* BRLTTY_INCLUDED_BITMASK */ |