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