Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Common/Bitmask.h
Views: 1798
/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/14/*15simple bitmask class16*/1718#pragma once1920#include <stdint.h>21#include <string.h>2223#include <AP_InternalError/AP_InternalError.h>2425template<uint16_t NUMBITS>26class Bitmask {27static constexpr uint16_t NUMWORDS = ((NUMBITS+31)/32);2829static_assert(NUMBITS > 0, "must store something");30// for first_set()'s return value31static_assert(NUMBITS <= INT16_MAX, "must fit in int16_t");32// so that 1U << bits is in range33static_assert(sizeof(unsigned int) >= sizeof(uint32_t), "int too small");3435public:36Bitmask() {37clearall();38}3940Bitmask &operator=(const Bitmask&other) {41memcpy(bits, other.bits, sizeof(bits[0])*NUMWORDS);42return *this;43}4445bool operator==(const Bitmask&other) {46return memcmp(bits, other.bits, sizeof(bits[0])*NUMWORDS) == 0;47}4849bool operator!=(const Bitmask&other) {50return !(*this == other);51}5253Bitmask(const Bitmask &other) = delete;545556// Construct a bitmask with some bits enabled.57template<size_t N>58Bitmask(const uint16_t (&enabled_bits)[N]) {59clearall();60for (size_t i = 0; i < N; ++i) {61if (enabled_bits[i] < NUMBITS) {62set(enabled_bits[i]);63}64}65}6667// set given bitnumber68void set(uint16_t bit) {69if (!validate(bit)) {70return; // ignore access of invalid bit71}72uint16_t word = bit/32;73uint8_t ofs = bit & 0x1f;74bits[word] |= (1U << ofs);75}7677// set all bits78void setall(void) {79// set all words to 111...80for (uint16_t i=0; i<NUMWORDS; i++) {81bits[i] = 0xffffffff;82}83// ensure out-of-range bits in the last word, if any exist, are 084uint16_t num_valid_bits = NUMBITS % 32;85if (num_valid_bits) { // word has out of range bits86bits[NUMWORDS-1] = (1U << num_valid_bits) - 1;87}88}8990// clear given bitnumber91void clear(uint16_t bit) {92if (!validate(bit)) {93return; // ignore access of invalid bit94}95uint16_t word = bit/32;96uint8_t ofs = bit & 0x1f;97bits[word] &= ~(1U << ofs);98}99100// set given bitnumber to on/off101void setonoff(uint16_t bit, bool onoff) {102if (onoff) {103set(bit);104} else {105clear(bit);106}107}108109// clear all bits110void clearall(void) {111memset(bits, 0, NUMWORDS*sizeof(bits[0]));112}113114// return true if given bitnumber is set115bool get(uint16_t bit) const {116if (!validate(bit)) {117return false; // pretend invalid bit is not set118}119uint16_t word = bit/32;120uint8_t ofs = bit & 0x1f;121return (bits[word] & (1U << ofs)) != 0;122}123124// return true if all bits are clear125bool empty(void) const {126for (uint16_t i=0; i<NUMWORDS; i++) {127if (bits[i] != 0) {128return false;129}130}131return true;132}133134// return number of bits set135uint16_t count() const {136uint16_t sum = 0;137for (uint16_t i=0; i<NUMWORDS; i++) {138sum += __builtin_popcount(bits[i]);139}140return sum;141}142143// return first bit set, or -1 if none set144int16_t first_set() const {145for (uint16_t i=0; i<NUMWORDS; i++) {146if (bits[i] != 0) {147return i*32 + __builtin_ffs(bits[i]) - 1;148}149}150return -1;151}152153// return number of bits available154uint16_t size() const {155return NUMBITS;156}157158private:159bool validate(uint16_t bit) const {160if (bit >= NUMBITS) {161INTERNAL_ERROR(AP_InternalError::error_t::bitmask_range);162return false;163}164return true;165}166167uint32_t bits[NUMWORDS];168};169170171