blob: e96942b36740cc2a6f3bc06c915fb81736f1930b [file] [log] [blame] [edit]
/*
* 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 */