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 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #ifndef CPL_MASK_H_INCLUDED
32 : #define CPL_MASK_H_INCLUDED
33 :
34 : #include "cpl_port.h"
35 : #include "cpl_vsi.h"
36 :
37 : #ifdef __cplusplus
38 :
39 : #include <cstring>
40 :
41 : /**
42 : * Allocates a buffer to store a given number of bits
43 : *
44 : * @param size number of bits
45 : * @param default_value initial value of bits
46 : */
47 592 : inline GUInt32 *CPLMaskCreate(std::size_t size, bool default_value)
48 : {
49 592 : std::size_t nBytes = (size + 31) / 8;
50 592 : void *buf = VSI_MALLOC_VERBOSE(nBytes);
51 592 : if (buf == nullptr)
52 : {
53 0 : return nullptr;
54 : }
55 592 : std::memset(buf, default_value ? 0xff : 0, nBytes);
56 592 : return static_cast<GUInt32 *>(buf);
57 : }
58 :
59 : /**
60 : * Get the value of a bit
61 : *
62 : * @param mask bit mask
63 : * @param i index of bit
64 : * @return `true` if bit is set
65 : */
66 36995397 : inline bool CPLMaskGet(GUInt32 *mask, std::size_t i)
67 : {
68 36995397 : return mask[i >> 5] & (0x01 << (i & 0x1f));
69 : }
70 :
71 : /**
72 : * Clear the value of a bit (set to false)
73 : *
74 : * @param mask bit mask
75 : * @param i index of bit to clear
76 : */
77 86954602 : inline void CPLMaskClear(GUInt32 *mask, std::size_t i)
78 : {
79 86954602 : mask[i >> 5] &= ~(0x01 << (i & 0x1f));
80 86954602 : }
81 :
82 : /**
83 : * Clear all bits in a mask
84 : *
85 : * @param mask bit mask
86 : * @param size number of bits in mask
87 : */
88 19 : inline void CPLMaskClearAll(GUInt32 *mask, std::size_t size)
89 : {
90 19 : auto nBytes = (size + 31) / 8;
91 19 : std::memset(mask, 0, nBytes);
92 19 : }
93 :
94 : /**
95 : * Set the value of a bit to true
96 : *
97 : * @param mask bit mask
98 : * @param i index of bit to set
99 : */
100 4756994 : inline void CPLMaskSet(GUInt32 *mask, std::size_t i)
101 : {
102 4756994 : mask[i >> 5] |= (0x01 << (i & 0x1f));
103 4756994 : }
104 :
105 : /**
106 : * Set all bits in a mask
107 : *
108 : * @param mask bit mask
109 : * @param size number of bits in mask
110 : */
111 640 : inline void CPLMaskSetAll(GUInt32 *mask, std::size_t size)
112 : {
113 640 : auto nBytes = (size + 31) / 8;
114 640 : std::memset(mask, 0xff, nBytes);
115 640 : }
116 :
117 : /**
118 : * Set a mask to true wherever a second mask is true
119 : *
120 : * @param mask1 destination mask
121 : * @param mask2 source mask
122 : * @param n number of bits in masks (must be same)
123 : */
124 595 : inline void CPLMaskMerge(GUInt32 *mask1, GUInt32 *mask2, std::size_t n)
125 : {
126 595 : std::size_t nBytes = (n + 31) / 8;
127 595 : std::size_t nIter = nBytes / 4;
128 1812724 : for (std::size_t i = 0; i < nIter; i++)
129 : {
130 1812133 : mask1[i] |= mask2[i];
131 : }
132 595 : }
133 :
134 : #endif // __cplusplus
135 :
136 : #endif // CPL_MASK_H
|