BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_bitstringimputil.h
Go to the documentation of this file.
1/// @file bdlb_bitstringimputil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_bitstringimputil.h -*-C++-*-
8#ifndef INCLUDED_BDLB_BITSTRINGIMPUTIL
9#define INCLUDED_BDLB_BITSTRINGIMPUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_bitstringimputil bdlb_bitstringimputil
15/// @brief Provide functional bit-manipulation of `uint64_t` values.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_bitstringimputil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_bitstringimputil-purpose"> Purpose</a>
25/// * <a href="#bdlb_bitstringimputil-classes"> Classes </a>
26/// * <a href="#bdlb_bitstringimputil-description"> Description </a>
27/// * <a href="#bdlb_bitstringimputil-usage"> Usage </a>
28/// * <a href="#bdlb_bitstringimputil-example-1-manipulators"> Example 1: Manipulators </a>
29/// * <a href="#bdlb_bitstringimputil-accessors"> Accessors </a>
30///
31/// # Purpose {#bdlb_bitstringimputil-purpose}
32/// Provide functional bit-manipulation of `uint64_t` values.
33///
34/// # Classes {#bdlb_bitstringimputil-classes}
35///
36/// - bdlb::BitStringImpUtil: namespace for `uint64_t` utilities
37///
38/// @see bdlb_bitstringutil
39///
40/// # Description {#bdlb_bitstringimputil-description}
41/// This component provides a utility `struct`,
42/// `bdlb::BitStringImpUtil`, that serves as a namespace for a collection of
43/// functions that provide bit-level operations on `uint64_t` values. Some of
44/// these functions consist of a single bitwise logical operation. The point of
45/// implementing them as functions is to facilitate providing these functions as
46/// arguments to templates in @ref bdlb_bitstringutil .
47///
48/// Note that no functions supporting `uint32_t` are provided here. This
49/// component exists solely to support `bdlb::BitStringUtil`, which deals
50/// entirely in `uint64_t` values.
51///
52/// Note that the `find*` functions defined here only find set bits -- there is
53/// never a context in @ref bdlb_bitstringutil where a `find*` that found clear
54/// bits is needed.
55///
56/// ## Usage {#bdlb_bitstringimputil-usage}
57///
58///
59/// This section illustrates the intended use of this component.
60///
61/// Note that, in all of these examples, the low-order bit is considered bit 0
62/// and resides on the right edge of the bit string.
63///
64/// ### Example 1: Manipulators {#bdlb_bitstringimputil-example-1-manipulators}
65///
66///
67/// This example demonstrates the "manipulator" static functions defined in this
68/// component, which can change the state of a `uint64_t`.
69///
70/// The `*EqBits` functions (`andEqBits`, `minusEqBits`, `orEqBits`, and
71/// `xorEqBits`), have the following signature:
72/// @code
73/// void function(uint64_t *dstValue,
74/// int dstIndex,
75/// uint64_t srcValue,
76/// int numBits);
77/// @endcode
78/// First, we demonstrate the `andEqBits` function:
79/// @code
80/// +--------------------------------------------------------------------------+
81/// | 'bdlb::BitStringImpUtil::andEqBits(&dstValue, 8, 0, 8)' in binary: |
82/// | |
83/// | 'dstValue' before in binary: 0..00000000000000000011001100110011 |
84/// | 'srcValue == 0' in binary: 0..00000000000000000000000000000000 |
85/// | 'srcValue', 0x00, at index 8: 00000000 |
86/// | 'dstValue' after in binary: 0..00000000000000000000000000110011 |
87/// +--------------------------------------------------------------------------+
88///
89/// uint64_t dstValue;
90///
91/// dstValue = 0x3333;
92/// bdlb::BitStringImpUtil::andEqBits(&dstValue, 8, 0, 8);
93/// assert(static_cast<uint64_t>(0x33) == dstValue);
94/// @endcode
95/// Then, we apply `andEqBits` with all bits set in the relevant part of
96/// 'srcValue, which has no effect:
97/// @code
98/// +--------------------------------------------------------------------------+
99/// | 'bdlb::BitStringImpUtil::andEqBits(&dstValue, 8, 0, 8)' in binary: |
100/// | |
101/// | 'dstValue' before in binary: 0..00000000000000000011001100110011 |
102/// | 'srcValue == 0xffff' in binary: 0..00000000000000001111111111111111 |
103/// | 'srcValue', 0xff, at index 8: 11111111 |
104/// | 'dstValue' after in binary: 0..00000000000000000011001100110011 |
105/// +--------------------------------------------------------------------------+
106///
107/// dstValue = 0x3333;
108/// bdlb::BitStringImpUtil::andEqBits(&dstValue, 8, 0xffff, 8);
109/// assert(static_cast<uint64_t>(0x3333) == dstValue);
110/// @endcode
111/// Next, we demonstrate `orEqBits`, which takes low-order bits of a `srcValue`
112/// and bitwise ORs them with `dstValue`:
113/// @code
114/// +--------------------------------------------------------------------------+
115/// | 'bdlb::BitStringImpUtil::orEqBits(&dstValue, 16, 0xffff, 8)' in binary: |
116/// | |
117/// | 'dstValue' before in binary: 0..00110011001100110011001100110011 |
118/// | 'srcValue == 0xffff' in binary: 0..00000000000000001111111111111111 |
119/// | 'srcValue', 0xff, at index 16: 11111111 |
120/// | 'dstValue' after in binary: 0..00110011111111110011001100110011 |
121/// +--------------------------------------------------------------------------+
122///
123/// dstValue = 0x33333333;
124/// bdlb::BitStringImpUtil::orEqBits(&dstValue, 16, 0xffff, 8);
125/// assert(static_cast<uint64_t>(0x33ff3333) == dstValue);
126/// @endcode
127/// Then, we demonstrate applying the same operation where `*dstValue` is
128/// initially 0:
129/// @code
130/// +--------------------------------------------------------------------------+
131/// | 'bdlb::BitStringImpUtil::orEqBits(&dstValue, 16, 0xffff, 8)' in binary: |
132/// | |
133/// | 'dstValue' before in binary: 0..00000000000000000000000000000000 |
134/// | 'srcValue == 0xffff' in binary: 0..00000000000000001111111111111111 |
135/// | 'srcValue', 0xff, at index 16: 11111111 |
136/// | 'dstValue' after in binary: 0..00000000111111110000000000000000 |
137/// +--------------------------------------------------------------------------+
138///
139/// dstValue = 0;
140/// bdlb::BitStringImpUtil::orEqBits(&dstValue, 16, 0xffff, 8);
141/// assert(static_cast<uint64_t>(0x00ff0000) == dstValue);
142/// @endcode
143/// Now, we apply another function, `xorEqBits`, that takes the low-order bits
144/// of `srcValue` and bitwise XORs them with `dstValue`:
145/// @code
146/// +--------------------------------------------------------------------------+
147/// | 'bdlb::BitStringImpUtil::xorEqBits(&dstValue, 16, 0xffff, 8)' in binary: |
148/// | |
149/// | 'dstValue' before in binary: 0..01110111011101110111011101110111 |
150/// | 'srcValue', 0xff, at index 16: 11111111 |
151/// | 'dstValue' after in binary: 0..01110111100010000111011101110111 |
152/// ----------------------------------------------------------------------------
153///
154/// dstValue = 0x77777777;
155/// bdlb::BitStringImpUtil::xorEqBits(&dstValue, 16, 0xffff, 8);
156/// assert(static_cast<uint64_t>(0x77887777) == dstValue);
157/// @endcode
158/// Finally, we apply the same function with a different value of `srcValue`
159/// and observe the result:
160/// @code
161/// +--------------------------------------------------------------------------+
162/// | 'bdlb::BitStringImpUtil::xorEqBits(&dstValue, 16, 0x5555, 8)' in binary: |
163/// | |
164/// | 'dstValue' before in binary: 0..01110111011101110111011101110111 |
165/// | 'srcValue', 0x55, at index 16: 01010101 |
166/// | 'dstValue' after in binary: 0..01110111001000100111011101110111 |
167/// +--------------------------------------------------------------------------+
168///
169/// dstValue = 0x77777777;
170/// bdlb::BitStringImpUtil::xorEqBits(&dstValue, 16, 0x5555, 8);
171/// assert(static_cast<uint64_t>(0x77227777) == dstValue);
172/// @endcode
173///
174/// ### Accessors {#bdlb_bitstringimputil-accessors}
175///
176///
177/// This example demonstrates the "accessor" static functions, which read, but
178/// do not modify, the state of a `uint64_t`.
179///
180/// The `find1At(Max,Min)IndexRaw` routines are used for finding the
181/// highest-order (or lowest-order) set bit in a `uint64_t`. These functions
182/// are "raw" because the behavior is undefined if they are passed 0.
183///
184/// First, we apply `find1AtMaxIndexRaw`:
185/// @code
186/// +--------------------------------------------------------------------------+
187/// | 'bdlb::BitStringImpUtil::find1AtMaxIndexRaw(0x10a)' in binary: |
188/// | |
189/// | input: 0..000000000000000000000000100001010 |
190/// | bit 8, highest bit set: 1 |
191/// +--------------------------------------------------------------------------+
192///
193/// assert(8 == bdlb::BitStringImpUtil::find1AtMaxIndexRaw(0x10a));
194/// @endcode
195/// Finally, we apply `find1AtMinIndexRaw`:
196/// @code
197/// +--------------------------------------------------------------------------+
198/// | 'bdlb::BitStringImpUtil::find1AtMinIndexRaw(0xffff0180)' in binary: |
199/// | |
200/// | input: 0..011111111111111110000000110000000 |
201/// | bit 7, lowest bit set: 1 |
202/// +--------------------------------------------------------------------------+
203///
204/// assert(7 == bdlb::BitStringImpUtil::find1AtMinIndexRaw(0xffff0180));
205/// @endcode
206/// @}
207/** @} */
208/** @} */
209
210/** @addtogroup bdl
211 * @{
212 */
213/** @addtogroup bdlb
214 * @{
215 */
216/** @addtogroup bdlb_bitstringimputil
217 * @{
218 */
219
220#include <bdlscm_version.h>
221
222#include <bdlb_bitmaskutil.h>
223#include <bdlb_bitutil.h>
224
225#include <bsls_assert.h>
226#include <bsls_performancehint.h>
227#include <bsls_review.h>
228
229#include <bsl_cstdint.h>
230
231
232namespace bdlb {
233
234 // =======================
235 // struct BitStringImpUtil
236 // =======================
237
238/// This `struct` provides a namespace for static functions to be used
239/// solely in the implementation of `BitStringUtil`. The "Manipulators"
240/// are intended to be provided as arguments to templates in
241/// @ref bdlb_bitstringutil , whereas the "Accessors" are to be called directly
242/// within that component.
244
245 // PUBLIC TYPES
246 enum { k_BITS_PER_UINT64 = 64 }; // number of bits in 'uint64_t'
247
248 // CLASS METHODS
249
250 // Manipulators
251
252 /// Bitwise AND the specified least-significant `numBits` in the
253 /// specified `srcValue` to those in the specified `dstValue` starting
254 /// at the specified `dstIndex`. The behavior is undefined unless
255 /// `0 <= dstIndex`, `0 <= numBits`, and
256 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
257 static void andEqBits(bsl::uint64_t *dstValue,
258 int dstIndex,
259 bsl::uint64_t srcValue,
260 int numBits);
261
262 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
263 /// AND-ed with the specified `srcValue`.
264 static void andEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
265
266 /// Bitwise MINUS the specified least-significant `numBits` in the
267 /// specified `srcValue` from those in the specified `dstValue` starting
268 /// at the specified `dstIndex`. The behavior is undefined unless
269 /// `0 <= dstIndex`, `0 <= numBits`, and
270 /// `dstIndex + numBits <= k_BITS_PER_UINT64`. Note that the bitwise
271 /// difference, `a - b`, is defined in C++ code as `a & ~b`.
272 static void minusEqBits(bsl::uint64_t *dstValue,
273 int dstIndex,
274 bsl::uint64_t srcValue,
275 int numBits);
276
277 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
278 /// AND-ed with the complement of the specified `srcValue`.
279 static void minusEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
280
281 /// Bitwise OR the specified least-significant `numBits` in the
282 /// specified `srcValue` to those in the specified `dstValue` starting
283 /// at the specified `dstIndex`. The behavior is undefined unless
284 /// `0 <= dstIndex`, `0 <= numBits`, and
285 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
286 static void orEqBits(bsl::uint64_t *dstValue,
287 int dstIndex,
288 bsl::uint64_t srcValue,
289 int numBits);
290
291 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
292 /// OR-ed with the specified `srcValue`.
293 static void orEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
294
295 /// Replace the specified `numBits` in the specified `dstValue` starting
296 /// at the specified `dstIndex` with the least-significant `numBits` of
297 /// the specified `srcValue`. The behavior is undefined unless
298 /// `0 <= dstIndex`, `0 <= numBits`, and
299 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
300 static void setEqBits(bsl::uint64_t *dstValue,
301 int dstIndex,
302 bsl::uint64_t srcValue,
303 int numBits);
304
305 /// Assign to the specified `*dstValue` the value of the specified
306 /// `srcValue`.
307 static void setEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
308
309 /// Bitwise XOR the specified least-significant `numBits` in the
310 /// specified `srcValue` to those in the specified `dstValue` starting
311 /// at the specified `dstIndex`. The behavior is undefined unless
312 /// `0 <= dstIndex`, `0 <= numBits`, and
313 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
314 static void xorEqBits(bsl::uint64_t *dstValue,
315 int dstIndex,
316 bsl::uint64_t srcValue,
317 int numBits);
318
319 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
320 /// XOR-ed with the specified `srcValue`.
321 static void xorEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
322
323 // Accessors
324
325 /// Return the index of the highest-order set bit in the specified
326 /// non-zero `value`. The behavior is undefined unless `0 != value`.
327 /// Note that this method is "raw" due to the requirement that at least
328 /// one bit in `value` must be set.
329 static int find1AtMaxIndexRaw(bsl::uint64_t value);
330
331 /// Return the index of the lowest-order set bit in the specified
332 /// non-zero `value`. The behavior is undefined unless `0 != value`.
333 /// Note that this method is "raw" due to the requirement that at least
334 /// one bit in `value` must be set.
335 static int find1AtMinIndexRaw(bsl::uint64_t value);
336};
337
338// ============================================================================
339// INLINE DEFINITIONS
340// ============================================================================
341
342 // -----------------------
343 // struct BitStringImpUtil
344 // -----------------------
345
346 // Manipulators
347
348inline
349void BitStringImpUtil::andEqBits(bsl::uint64_t *dstValue,
350 int dstIndex,
351 bsl::uint64_t srcValue,
352 int numBits)
353{
354 BSLS_ASSERT(dstValue);
355 BSLS_ASSERT( 0 <= dstIndex);
356 BSLS_ASSERT( 0 <= numBits);
357 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
358
360 *dstValue &= BitMaskUtil::zero64(dstIndex, numBits) |
361 (srcValue << dstIndex);
362 }
363}
364
365inline
366void BitStringImpUtil::andEqWord(bsl::uint64_t *dstValue,
367 bsl::uint64_t srcValue)
368{
369 BSLS_ASSERT(dstValue);
370
371 *dstValue &= srcValue;
372}
373
374inline
375void BitStringImpUtil::minusEqBits(bsl::uint64_t *dstValue,
376 int dstIndex,
377 bsl::uint64_t srcValue,
378 int numBits)
379{
380 BSLS_ASSERT(dstValue);
381 BSLS_ASSERT( 0 <= dstIndex);
382 BSLS_ASSERT( 0 <= numBits);
383 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
384
386 *dstValue &= BitMaskUtil::zero64(dstIndex, numBits) |
387 (~srcValue << dstIndex);
388 }
389}
390
391inline
392void BitStringImpUtil::minusEqWord(bsl::uint64_t *dstValue,
393 bsl::uint64_t srcValue)
394{
395 BSLS_ASSERT(dstValue);
396
397 *dstValue &= ~srcValue;
398}
399
400inline
401void BitStringImpUtil::orEqBits(bsl::uint64_t *dstValue,
402 int dstIndex,
403 bsl::uint64_t srcValue,
404 int numBits)
405{
406 BSLS_ASSERT(dstValue);
407 BSLS_ASSERT( 0 <= dstIndex);
408 BSLS_ASSERT( 0 <= numBits);
409 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
410
412 *dstValue |= (srcValue & BitMaskUtil::lt64(numBits)) << dstIndex;
413 }
414}
415
416inline
417void BitStringImpUtil::orEqWord(bsl::uint64_t *dstValue,
418 bsl::uint64_t srcValue)
419{
420 BSLS_ASSERT(dstValue);
421
422 *dstValue |= srcValue;
423}
424
425inline
426void BitStringImpUtil::setEqBits(bsl::uint64_t *dstValue,
427 int dstIndex,
428 bsl::uint64_t srcValue,
429 int numBits)
430{
431 BSLS_ASSERT(dstValue);
432 BSLS_ASSERT(0 <= dstIndex);
433 BSLS_ASSERT(0 <= numBits);
434 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
435
437 const bsl::uint64_t mask = BitMaskUtil::lt64(numBits);
438
439 *dstValue &= ~(mask << dstIndex);
440 *dstValue |= (srcValue & mask) << dstIndex;
441 }
442}
443
444inline
445void BitStringImpUtil::setEqWord(bsl::uint64_t *dstValue,
446 bsl::uint64_t srcValue)
447{
448 BSLS_ASSERT(dstValue);
449
450 *dstValue = srcValue;
451}
452
453inline
454void BitStringImpUtil::xorEqBits(bsl::uint64_t *dstValue,
455 int dstIndex,
456 bsl::uint64_t srcValue,
457 int numBits)
458{
459 BSLS_ASSERT(dstValue);
460 BSLS_ASSERT( 0 <= dstIndex);
461 BSLS_ASSERT( 0 <= numBits);
462 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
463
465 *dstValue ^= (srcValue & BitMaskUtil::lt64(numBits)) << dstIndex;
466 }
467}
468
469inline
470void BitStringImpUtil::xorEqWord(bsl::uint64_t *dstValue,
471 bsl::uint64_t srcValue)
472{
473 BSLS_ASSERT(dstValue);
474
475 *dstValue ^= srcValue;
476}
477
478 // Accessors
479
480inline
482{
483 BSLS_ASSERT(0 != value);
484
486}
487
488inline
490{
491 BSLS_ASSERT(0 != value);
492
493 return BitUtil::numTrailingUnsetBits(value);
494}
495
496} // close package namespace
497
498
499#endif
500
501// ----------------------------------------------------------------------------
502// Copyright 2015 Bloomberg Finance L.P.
503//
504// Licensed under the Apache License, Version 2.0 (the "License");
505// you may not use this file except in compliance with the License.
506// You may obtain a copy of the License at
507//
508// http://www.apache.org/licenses/LICENSE-2.0
509//
510// Unless required by applicable law or agreed to in writing, software
511// distributed under the License is distributed on an "AS IS" BASIS,
512// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
513// See the License for the specific language governing permissions and
514// limitations under the License.
515// ----------------------------- END-OF-FILE ----------------------------------
516
517/** @} */
518/** @} */
519/** @} */
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
Definition bdlb_algorithmworkaroundutil.h:74
static bsl::uint64_t zero64(int index, int numBits)
Definition bdlb_bitmaskutil.h:438
static bsl::uint64_t lt64(int index)
Definition bdlb_bitmaskutil.h:372
Definition bdlb_bitstringimputil.h:243
static void setEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:426
static void minusEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:375
static void orEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:417
static int find1AtMaxIndexRaw(bsl::uint64_t value)
Definition bdlb_bitstringimputil.h:481
static void orEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:401
static void setEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:445
static void andEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:366
static void xorEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:454
static void minusEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:392
static int find1AtMinIndexRaw(bsl::uint64_t value)
Definition bdlb_bitstringimputil.h:489
@ k_BITS_PER_UINT64
Definition bdlb_bitstringimputil.h:246
static void xorEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:470
static void andEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:349
static int numTrailingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:462
static int numLeadingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:409