BitOps.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2018-2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Namespace
27 Foam::BitOps
28
29Description
30 Various bit-wise operations and adaptor methods for containers
31 that are somewhat similar to bitSet (eg, boolList, labelHashSet).
32
33 The population count uses the Hamming weight
34 (http://en.wikipedia.org/wiki/Hamming_weight).
35
36Namespace
37 Foam::BitSetOps
38
39Description
40 Factory and other methods for bitSet.
41 Adaptor methods for other containers that are somewhat similar to
42 bitSet (eg, boolList, labelHashSet).
43
44\*---------------------------------------------------------------------------*/
45
46#ifndef Foam_BitOps_H
47#define Foam_BitOps_H
48
49#include "label.H"
50#include "UList.H"
51#include "HashSet.H"
52#include "Ostream.H"
53#include <algorithm>
54#include <limits>
55#include <utility>
56
57// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
58
59namespace Foam
60{
61
62// Forward Declarations
63class bitSet;
64template<class T> class List;
65
66/*---------------------------------------------------------------------------*\
67 Namespace BitOps Declaration
68\*---------------------------------------------------------------------------*/
69
70namespace BitOps
71{
72
73// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
74
75//- Count number of 'true' entries.
76// \param val can be set to false to count the number of false values instead
77// For compatibility with bitSet::count()
78inline unsigned int count(const UList<bool>& bools, const bool val=true)
79{
80 return std::count(bools.begin(), bools.end(), val);
81}
82
83//- True if all entries are 'true' or if the set is empty.
84// For compatibility with bitSet::all()
85inline bool all(const UList<bool>& bools)
86{
87 return std::all_of(bools.begin(), bools.end(), identityOp());
88}
89
90//- True if any entries are 'true'.
91// For compatibility with bitSet::any()
92inline bool any(const UList<bool>& bools)
93{
94 return std::any_of(bools.begin(), bools.end(), identityOp());
95}
96
97//- True if no entries are 'true'.
98// For compatibility with bitSet::none()
99inline bool none(const UList<bool>& bools)
100{
101 return std::none_of(bools.begin(), bools.end(), identityOp());
102}
103
104
105//- Set the listed locations (assign 'true').
106// Does auto-vivify for non-existent entries.
107//
108// For compatibility with bitSet::set(labelUList)
109void set(List<bool>& bools, const labelUList& locations);
110
111//- Set the specified range 'on' in a boolList.
112// For compatibility with bitSet::set(labelRange)
113void set(List<bool>& bools, const labelRange& range);
114
115//- Set the specified range in a labelHashSet.
116// For compatibility with bitSet::set(labelRange)
117void set(labelHashSet& hashset, const labelRange& range);
118
119//- Forward to bitSet::set(labelRange)
120void set(bitSet& bitset, const labelRange& range);
121
122
123//- Unset the listed locations (assign 'false').
124// No auto-vivify non-existent entries.
125//
126// For compatibility with bitSet::set(labelUList)
127void unset(List<bool>& bools, const labelUList& locations);
128
129//- Unset the specified range 'on' in a boolList.
130// For compatibility with bitSet::unset(labelRange)
131void unset(List<bool>& bools, const labelRange& range);
132
133//- Unset the specified range in a labelHashSet.
134// For compatibility with bitSet::unset(labelRange)
135void unset(labelHashSet& hashset, const labelRange& range);
136
137//- Forward to bitSet::unset(labelRange)
138void unset(bitSet& bitset, const labelRange& range);
139
140
141//- Construct a selection list of bools (all false) with the given pre-size,
142//- subsequently add specified locations as true,
143//- auto-vivify entries if needed.
144// Similar to bitSet construction from locations
145//
146// \return a List of bools
147List<bool> select(const label n, const labelUList& locations);
148
149//- Construct an auto-sized selection list of bools (all false),
150//- and populate the specified locations as true.
151// Similar to bitSet construction from locations
152//
153// \return a List of bools
154List<bool> select(const labelUList& locations);
155
156//- Return the (sorted) values corresponding to 'true' entries.
157// Similar to bitSet::toc()
158//
159// \return a List of labels
160List<label> toc(const UList<bool>& bools);
161
162//- Return the (sorted) values corresponding to 'true' entries.
163// Similar to bitSet::sortedToc() and labelHashSet::sortedToc()
164//
165// \return a List of labels
166List<label> sortedToc(const UList<bool>& bools);
167
168
169//- Count arbitrary number of bits (of an integral type)
170template<class UIntType>
171inline unsigned int bit_count(UIntType x)
172{
173 unsigned int n = 0u;
174
175 for (; x; ++n) { x &= (x-1); }
176
177 return n;
178}
179
180
181//- Count bits in a 32-bit value (Hamming weight method)
182template<>
183inline unsigned int bit_count(uint32_t x)
184{
185 x -= (x >> 1) & 0x55555555;
186 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
187
188 return ((((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
189}
190
191
192//- Count bits in a 64-bit value (Hamming weight method)
193template<>
194inline unsigned int bit_count(uint64_t x)
195{
196 x -= (x >> 1) & 0x5555555555555555;
197 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
198
199 return unsigned
200 ((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56);
201}
202
203
204//- Repeat a value of the given BitWidth into the destination output type.
205//
206// \note when BitWidth is 1, it is better to do directly.
207// \code
208// (val ? ~0u : 0u)
209// \endcode
210template<class UIntType, unsigned BitWidth>
211inline UIntType repeat_value(unsigned val)
212{
213 static_assert
214 (
215 BitWidth && std::numeric_limits<UIntType>::digits >= BitWidth,
216 "BitWidth too large for target output"
217 );
218
219 // How many fit into the target
220 const unsigned nrepeat = (std::numeric_limits<UIntType>::digits / BitWidth);
221
222 // Max value for a single element
223 const unsigned mask = ((1u << BitWidth) - 1);
224
225 // The first occurrence
226 UIntType fillval = ((val >= mask) ? mask : val);
227
228 // Repeated
229 for (unsigned i = 1; i < nrepeat; ++i)
230 {
231 fillval |= (fillval << BitWidth);
232 }
233
234 return fillval;
235}
236
237
238//- Print 0/1 bits in the (unsigned) integral type
239template<class UIntType>
240inline Ostream& print(Ostream& os, UIntType value, char off='0', char on='1')
241{
242 if (os.format() == IOstream::BINARY)
243 {
244 // Perhaps not the most sensible, but the only thing we currently have.
245 os << label(value);
246 }
247 else
248 {
249 // Starting from most significant bit - makes for easy reading.
250 for
251 (
252 unsigned test = (1u << (std::numeric_limits<UIntType>::digits-1));
253 test;
254 test >>= 1u
255 )
256 {
257 os << ((value & test) ? on : off);
258 }
259 }
260
261 return os;
262}
263
264
265//- An (unsigned) integral type adapter, for output of bit values
266template<class UIntType>
268{
269 typedef UIntType value_type;
271
272 //- Null constructible as zero
273 constexpr bitInfo() noexcept : value(0) {}
274
275 //- Value construct
276 explicit bitInfo(UIntType val) : value(val) {}
277
278 //- Conversion to base type
279 operator UIntType () const { return value; }
280
281 //- Conversion to base type
282 operator UIntType& () { return value; }
283};
284
285} // End namespace BitOps
286
287
288/*---------------------------------------------------------------------------*\
289 Namespace BitSetOps Declaration
290\*---------------------------------------------------------------------------*/
291
292namespace BitSetOps
293{
294
295// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
296
297//- Create a bitSet with length n with the specified \a on locations.
298// The resulting bitSet is guaranteed to have \b exactly the specified length,
299// any values or positions larger than n-1 are silently ignored.
300//
301// \param n the size of the output bitSet
302// \param locations the list of positions corresponding to an \a on bit.
303// \param on the value for on. Set as false to invert the logic.
304//
305// \return a bitset
306bitSet create
307(
308 const label n,
309 const labelHashSet& locations,
310 const bool on = true
311);
312
313
314//- Create a bitSet with length n with the specified \a on locations.
315// The resulting bitSet is guaranteed to have \b exactly the specified length,
316// any values or positions larger than n-1 are silently ignored.
317//
318// \param n the size of the output bitSet
319// \param locations the list of positions corresponding to an \a on bit.
320// \param on the value for on. Set as false to invert the logic.
321//
322// \return a bitset
323bitSet create
324(
325 const label n,
326 const labelUList& locations,
327 const bool on = true
328);
329
330
331//- Create a bitSet with length n with the specified \a on locations
332//- when the list values are equal to the select value.
333//
334// The resulting bitSet is guaranteed to have \b exactly the specified length,
335// any values or positions larger than n-1 are silently ignored.
336//
337// \param n the size of the output bitSet
338// \param select the value to select as 'on'
339// \param values the values to scan for 'select'
340// \param on the value for on. Set as false to invert the logic.
341//
342// \return a bitset
343bitSet create
344(
345 const label n,
346 const label select,
347 const labelUList& values,
348 const bool on = true
349);
350
351} // End namespace BitSetOps
352
353
354// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
355
356
357//- Print 0/1 bits of an (unsigned) integral type via an adapter
358template<class UIntType>
360{
361 BitOps::print(os, info.value);
362 return os;
363}
364
365
366// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
367
368} // End namespace Foam
369
370// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
371
372#endif
373
374// ************************************************************************* //
scalar range
label n
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:350
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:58
OBJstream os(runTime.globalPath()/outputName)
void set(List< bool > &bools, const labelUList &locations)
Set the listed locations (assign 'true').
Definition: BitOps.C:38
List< bool > select(const label n, const labelUList &locations)
Definition: BitOps.C:142
void unset(List< bool > &bools, const labelUList &locations)
Unset the listed locations (assign 'false').
Definition: BitOps.C:107
List< label > toc(const UList< bool > &bools)
Return the (sorted) values corresponding to 'true' entries.
Definition: BitOps.C:166
bool any(const UList< bool > &bools)
True if any entries are 'true'.
Definition: BitOps.H:92
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:78
bool all(const UList< bool > &bools)
True if all entries are 'true' or if the set is empty.
Definition: BitOps.H:85
unsigned int bit_count(UIntType x)
Count arbitrary number of bits (of an integral type)
Definition: BitOps.H:171
List< label > sortedToc(const UList< bool > &bools)
Return the (sorted) values corresponding to 'true' entries.
Definition: BitOps.C:203
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:240
bool none(const UList< bool > &bools)
True if no entries are 'true'.
Definition: BitOps.H:99
UIntType repeat_value(unsigned val)
Repeat a value of the given BitWidth into the destination output type.
Definition: BitOps.H:211
bitSet create(const label n, const labelHashSet &locations, const bool on=true)
Create a bitSet with length n with the specified on locations.
Definition: BitOps.C:212
List< bool > bools(const labelHashSet &locations)
Definition: HashOps.C:81
Namespace for OpenFOAM.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
const direction noexcept
Definition: Scalar.H:223
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
An (unsigned) integral type adapter, for output of bit values.
Definition: BitOps.H:268
UIntType value_type
Definition: BitOps.H:269
bitInfo(UIntType val)
Value construct.
Definition: BitOps.H:276
constexpr bitInfo() noexcept
Null constructible as zero.
Definition: BitOps.H:273
value_type value
Definition: BitOps.H:270