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 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 
26 Namespace
27  Foam::BitOps
28 
29 Description
30  Various bit-wise operations, etc.
31 
32  The population count uses the Hamming weight
33  (http://en.wikipedia.org/wiki/Hamming_weight).
34 
35 Namespace
36  Foam::BitSetOps
37 
38 Description
39  Factory and other methods for bitSet.
40 
41 \*---------------------------------------------------------------------------*/
42 
43 #ifndef BitOps_H
44 #define BitOps_H
45 
46 #include "label.H"
47 #include "UList.H"
48 #include "HashSet.H"
49 #include "Ostream.H"
50 #include <algorithm>
51 #include <limits>
52 #include <utility>
53 
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55 
56 namespace Foam
57 {
58 
59 // Forward declarations
60 class bitSet;
61 
62 /*---------------------------------------------------------------------------*\
63  Namespace BitOps Declaration
64 \*---------------------------------------------------------------------------*/
65 
66 namespace BitOps
67 {
68 
69 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
70 
71 //- Count number of 'true' entries.
72 // \param val can be set to false to count the number of false values instead
73 // For compatibility with bitSet::count()
74 inline unsigned int count(const UList<bool>& bools, const bool val=true)
75 {
76  return std::count(bools.begin(), bools.end(), val);
77 }
78 
79 //- True if all entries are 'true' or if the set is empty.
80 // For compatibility with bitSet::all()
81 inline bool all(const UList<bool>& bools)
82 {
83  return std::all_of(bools.begin(), bools.end(), [](bool b){return b;});
84 }
85 
86 //- True if any entries are 'true'.
87 // For compatibility with bitSet::any()
88 inline bool any(const UList<bool>& bools)
89 {
90  return std::any_of(bools.begin(), bools.end(), [](bool b){return b;});
91 }
92 
93 //- True if no entries are 'true'.
94 // For compatibility with bitSet::none()
95 inline bool none(const UList<bool>& bools)
96 {
97  return std::none_of(bools.begin(), bools.end(), [](bool b){return b;});
98 }
99 
100 
101 //- Count arbitrary number of bits (of an integral type)
102 template<class UIntType>
103 inline unsigned int bit_count(UIntType x)
104 {
105  unsigned int n = 0u;
106 
107  for (; x; ++n) { x &= (x-1); }
108 
109  return n;
110 }
111 
112 
113 //- Count bits in a 32-bit value (Hamming weight method)
114 template<>
115 inline unsigned int bit_count(uint32_t x)
116 {
117  x -= (x >> 1) & 0x55555555;
118  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
119 
120  return ((((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
121 }
122 
123 
124 //- Count bits in a 64-bit value (Hamming weight method)
125 template<>
126 inline unsigned int bit_count(uint64_t x)
127 {
128  x -= (x >> 1) & 0x5555555555555555;
129  x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
130 
131  return unsigned
132  ((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56);
133 }
134 
135 
136 //- Repeat a value of the given BitWidth into the destination output type.
137 //
138 // \note when BitWidth is 1, it is better to do directly.
139 // \code
140 // (val ? ~0u : 0u)
141 // \endcode
142 template<class UIntType, unsigned BitWidth>
143 inline UIntType repeat_value(unsigned val)
144 {
145  static_assert
146  (
147  BitWidth && std::numeric_limits<UIntType>::digits >= BitWidth,
148  "BitWidth too large for target output"
149  );
150 
151  // How many fit into the target
152  const unsigned nrepeat = (std::numeric_limits<UIntType>::digits / BitWidth);
153 
154  // Max value for a single element
155  const unsigned mask = ((1u << BitWidth) - 1);
156 
157  // The first occurance
158  UIntType fillval = ((val >= mask) ? mask : val);
159 
160  // Repeated
161  for (unsigned i = 1; i < nrepeat; ++i)
162  {
163  fillval |= (fillval << BitWidth);
164  }
165 
166  return fillval;
167 }
168 
169 
170 //- Print 0/1 bits in the (unsigned) integral type
171 template<class UIntType>
172 inline Ostream& print(Ostream& os, UIntType value, char off='0', char on='1')
173 {
174  if (os.format() == IOstream::BINARY)
175  {
176  // Perhaps not the most sensible, but the only thing we currently have.
177  os << label(value);
178  }
179  else
180  {
181  // Starting from most significant bit - makes for easy reading.
182  for
183  (
184  unsigned test = (1u << (std::numeric_limits<UIntType>::digits-1));
185  test;
186  test >>= 1u
187  )
188  {
189  os << ((value & test) ? on : off);
190  }
191  }
192 
193  return os;
194 }
195 
196 
197 //- An (unsigned) integral type adapter, for output of bit values
198 template<class UIntType>
199 struct bitInfo
200 {
201  typedef UIntType value_type;
203 
204  //- Null constructible as zero
205  constexpr bitInfo() noexcept : value(0) {}
206 
207  //- Value construct
208  explicit bitInfo(UIntType val) : value(val) {}
209 
210  //- Conversion to base type
211  operator UIntType () const { return value; }
212 
213  //- Conversion to base type
214  operator UIntType& () { return value; }
215 };
216 
217 } // End namespace BitOps
218 
219 
220 /*---------------------------------------------------------------------------*\
221  Namespace BitSetOps Declaration
222 \*---------------------------------------------------------------------------*/
223 
224 namespace BitSetOps
225 {
226 
227 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
228 
229 //- Create a bitSet with length n with the specifed \a on locations.
230 // The resulting bitSet is guaranteed to have exactly the specified length,
231 // any values or positions larger than n-1 are silently ignored.
232 //
233 // \param n the size of the output bitSet
234 // \param locations the list of positions corresponding to an \a on bit.
235 // \param on the value for on. Set as false to invert the logic.
236 //
237 // \return a bitset
238 bitSet create
239 (
240  const label n,
241  const labelHashSet& locations,
242  const bool on = true
243 );
244 
245 
246 //- Create a bitSet with length n with the specifed \a on locations.
247 // The resulting bitSet is guaranteed to have exactly the specified length,
248 // any values or positions larger than n-1 are silently ignored.
249 //
250 // \param n the size of the output bitSet
251 // \param locations the list of positions corresponding to an \a on bit.
252 // \param on the value for on. Set as false to invert the logic.
253 //
254 // \return a bitset
255 bitSet create
256 (
257  const label n,
258  const labelUList& locations,
259  const bool on = true
260 );
261 
262 
263 //- Create a bitSet with length n with the specifed \a on locations
264 //- when the list values are equal to the select value.
265 //
266 // The resulting bitSet is guaranteed to have exactly the specified length,
267 // any values or positions larger than n-1 are silently ignored.
268 //
269 // \param n the size of the output bitSet
270 // \param select the value to select as 'on'
271 // \param values the values to scan for 'select'
272 // \param on the value for on. Set as false to invert the logic.
273 //
274 // \return a bitset
275 bitSet create
276 (
277  const label n,
278  const label select,
279  const labelUList& values,
280  const bool on = true
281 );
282 
283 } // End namespace BitSetOps
284 
285 
286 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
287 
288 
289 //- Print 0/1 bits of an (unsigned) integral type via an adapter
290 template<class UIntType>
292 {
293  BitOps::print(os, info.value);
294  return os;
295 }
296 
297 
298 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
299 
300 } // End namespace Foam
301 
302 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
303 
304 #endif
305 
306 // ************************************************************************* //
Foam::BitSetOps::create
bitSet create(const label n, const labelHashSet &locations, const bool on=true)
Create a bitSet with length n with the specifed on locations.
Definition: BitOps.C:35
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
Foam::HashSetOps::bools
List< bool > bools(const labelHashSet &locations)
Definition: HashOps.C:81
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Foam::BitOps::bit_count
unsigned int bit_count(UIntType x)
Count arbitrary number of bits (of an integral type)
Definition: BitOps.H:103
Foam::BitOps::bitInfo::bitInfo
bitInfo(UIntType val)
Value construct.
Definition: BitOps.H:208
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:273
Foam::BitOps::bitInfo::bitInfo
constexpr bitInfo() noexcept
Null constructible as zero.
Definition: BitOps.H:205
Foam::BitOps::all
bool all(const UList< bool > &bools)
True if all entries are 'true' or if the set is empty.
Definition: BitOps.H:81
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::BitOps::repeat_value
UIntType repeat_value(unsigned val)
Repeat a value of the given BitWidth into the destination output type.
Definition: BitOps.H:143
Foam::BitOps::any
bool any(const UList< bool > &bools)
True if any entries are 'true'.
Definition: BitOps.H:88
Foam::BitOps::bitInfo::value
value_type value
Definition: BitOps.H:202
HashSet.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::BitOps::none
bool none(const UList< bool > &bools)
True if no entries are 'true'.
Definition: BitOps.H:95
Ostream.H
Foam::BitOps::bitInfo
An (unsigned) integral type adapter, for output of bit values.
Definition: BitOps.H:199
Foam::IOstreamOption::BINARY
"binary"
Definition: IOstreamOption.H:67
UList.H
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:74
label.H
Foam::BitOps::bitInfo::value_type
UIntType value_type
Definition: BitOps.H:201
Foam::BitOps::print
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:172
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:79
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:415
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102