Line data Source code
1 : /********************************************************************** 2 : * 3 : * Name: cpl_mask.h 4 : * Project: CPL - Common Portability Library 5 : * Purpose: Bitmask manipulation functions 6 : * Author: Daniel Baston, dbaston@gmail.com 7 : * 8 : ********************************************************************** 9 : * Copyright (c) 2022, ISciences LLC 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #ifndef CPL_MASK_H_INCLUDED 15 : #define CPL_MASK_H_INCLUDED 16 : 17 : #include "cpl_port.h" 18 : #include "cpl_vsi.h" 19 : 20 : #ifdef __cplusplus 21 : 22 : #include <cstring> 23 : 24 : /** 25 : * Allocates a buffer to store a given number of bits 26 : * 27 : * @param size number of bits 28 : * @param default_value initial value of bits 29 : */ 30 613 : inline GUInt32 *CPLMaskCreate(std::size_t size, bool default_value) 31 : { 32 613 : std::size_t nBytes = (size + 31) / 8; 33 613 : void *buf = VSI_MALLOC_VERBOSE(nBytes); 34 613 : if (buf == nullptr) 35 : { 36 0 : return nullptr; 37 : } 38 613 : std::memset(buf, default_value ? 0xff : 0, nBytes); 39 613 : return static_cast<GUInt32 *>(buf); 40 : } 41 : 42 : /** 43 : * Get the value of a bit 44 : * 45 : * @param mask bit mask 46 : * @param i index of bit 47 : * @return `true` if bit is set 48 : */ 49 36996197 : inline bool CPLMaskGet(GUInt32 *mask, std::size_t i) 50 : { 51 36996197 : return mask[i >> 5] & (0x01 << (i & 0x1f)); 52 : } 53 : 54 : /** 55 : * Clear the value of a bit (set to false) 56 : * 57 : * @param mask bit mask 58 : * @param i index of bit to clear 59 : */ 60 87277102 : inline void CPLMaskClear(GUInt32 *mask, std::size_t i) 61 : { 62 87277102 : mask[i >> 5] &= ~(0x01 << (i & 0x1f)); 63 87277102 : } 64 : 65 : /** 66 : * Clear all bits in a mask 67 : * 68 : * @param mask bit mask 69 : * @param size number of bits in mask 70 : */ 71 19 : inline void CPLMaskClearAll(GUInt32 *mask, std::size_t size) 72 : { 73 19 : auto nBytes = (size + 31) / 8; 74 19 : std::memset(mask, 0, nBytes); 75 19 : } 76 : 77 : /** 78 : * Set the value of a bit to true 79 : * 80 : * @param mask bit mask 81 : * @param i index of bit to set 82 : */ 83 4975494 : inline void CPLMaskSet(GUInt32 *mask, std::size_t i) 84 : { 85 4975494 : mask[i >> 5] |= (0x01 << (i & 0x1f)); 86 4975494 : } 87 : 88 : /** 89 : * Set all bits in a mask 90 : * 91 : * @param mask bit mask 92 : * @param size number of bits in mask 93 : */ 94 661 : inline void CPLMaskSetAll(GUInt32 *mask, std::size_t size) 95 : { 96 661 : auto nBytes = (size + 31) / 8; 97 661 : std::memset(mask, 0xff, nBytes); 98 661 : } 99 : 100 : /** 101 : * Set a mask to true wherever a second mask is true 102 : * 103 : * @param mask1 destination mask 104 : * @param mask2 source mask 105 : * @param n number of bits in masks (must be same) 106 : */ 107 616 : inline void CPLMaskMerge(GUInt32 *mask1, GUInt32 *mask2, std::size_t n) 108 : { 109 616 : std::size_t nBytes = (n + 31) / 8; 110 616 : std::size_t nIter = nBytes / 4; 111 1822844 : for (std::size_t i = 0; i < nIter; i++) 112 : { 113 1822223 : mask1[i] |= mask2[i]; 114 : } 115 616 : } 116 : 117 : #endif // __cplusplus 118 : 119 : #endif // CPL_MASK_H