BDE 4.39.x 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.
243///
244/// See @ref bdlb_bitstringimputil
246
247 // PUBLIC TYPES
248 enum { k_BITS_PER_UINT64 = 64 }; // number of bits in 'uint64_t'
249
250 // CLASS METHODS
251
252 // Manipulators
253
254 /// Bitwise AND the specified least-significant `numBits` in the
255 /// specified `srcValue` to those in the specified `dstValue` starting at the specified `dstIndex`.
256 ///
257 /// \pre The behavior is undefined unless
258 /// `0 <= dstIndex`, `0 <= numBits`, and
259 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
260 static void andEqBits(bsl::uint64_t *dstValue,
261 int dstIndex,
262 bsl::uint64_t srcValue,
263 int numBits);
264
265 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
266 /// AND-ed with the specified `srcValue`.
267 static void andEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
268
269 /// Bitwise MINUS the specified least-significant `numBits` in the
270 /// specified `srcValue` from those in the specified `dstValue` starting at the specified `dstIndex`.
271 ///
272 /// \pre The behavior is undefined unless
273 /// `0 <= dstIndex`, `0 <= numBits`, and `dstIndex + numBits <= k_BITS_PER_UINT64`.
274 ///
275 /// \note Note that the bitwise
276 /// difference, `a - b`, is defined in C++ code as `a & ~b`.
277 static void minusEqBits(bsl::uint64_t *dstValue,
278 int dstIndex,
279 bsl::uint64_t srcValue,
280 int numBits);
281
282 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
283 /// AND-ed with the complement of the specified `srcValue`.
284 static void minusEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
285
286 /// Bitwise OR the specified least-significant `numBits` in the
287 /// specified `srcValue` to those in the specified `dstValue` starting at the specified `dstIndex`.
288 ///
289 /// \pre The behavior is undefined unless
290 /// `0 <= dstIndex`, `0 <= numBits`, and
291 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
292 static void orEqBits(bsl::uint64_t *dstValue,
293 int dstIndex,
294 bsl::uint64_t srcValue,
295 int numBits);
296
297 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
298 /// OR-ed with the specified `srcValue`.
299 static void orEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
300
301 /// Replace the specified `numBits` in the specified `dstValue` starting
302 /// at the specified `dstIndex` with the least-significant `numBits` of the specified `srcValue`.
303 ///
304 /// \pre The behavior is undefined unless
305 /// `0 <= dstIndex`, `0 <= numBits`, and
306 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
307 static void setEqBits(bsl::uint64_t *dstValue,
308 int dstIndex,
309 bsl::uint64_t srcValue,
310 int numBits);
311
312 /// Assign to the specified `*dstValue` the value of the specified
313 /// `srcValue`.
314 static void setEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
315
316 /// Bitwise XOR the specified least-significant `numBits` in the
317 /// specified `srcValue` to those in the specified `dstValue` starting at the specified `dstIndex`.
318 ///
319 /// \pre The behavior is undefined unless
320 /// `0 <= dstIndex`, `0 <= numBits`, and
321 /// `dstIndex + numBits <= k_BITS_PER_UINT64`.
322 static void xorEqBits(bsl::uint64_t *dstValue,
323 int dstIndex,
324 bsl::uint64_t srcValue,
325 int numBits);
326
327 /// Assign to the specified `*dstValue` the value of `*dstValue` bitwise
328 /// XOR-ed with the specified `srcValue`.
329 static void xorEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue);
330
331 // Accessors
332
333 /// Return the index of the highest-order set bit in the specified non-zero `value`.
334 ///
335 /// \pre The behavior is undefined unless `0 != value`.
336 ///
337 /// \note Note that this method is "raw" due to the requirement that at least
338 /// one bit in `value` must be set.
339 static int find1AtMaxIndexRaw(bsl::uint64_t value);
340
341 /// Return the index of the lowest-order set bit in the specified non-zero `value`.
342 ///
343 /// \pre The behavior is undefined unless `0 != value`.
344 ///
345 /// \note Note that this method is "raw" due to the requirement that at least
346 /// one bit in `value` must be set.
347 static int find1AtMinIndexRaw(bsl::uint64_t value);
348};
349
350// ============================================================================
351// INLINE DEFINITIONS
352// ============================================================================
353
354 // -----------------------
355 // struct BitStringImpUtil
356 // -----------------------
357
358 // Manipulators
359
360inline
361void BitStringImpUtil::andEqBits(bsl::uint64_t *dstValue,
362 int dstIndex,
363 bsl::uint64_t srcValue,
364 int numBits)
365{
366 BSLS_ASSERT(dstValue);
367 BSLS_ASSERT( 0 <= dstIndex);
368 BSLS_ASSERT( 0 <= numBits);
369 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
370
372 *dstValue &= BitMaskUtil::zero64(dstIndex, numBits) |
373 (srcValue << dstIndex);
374 }
375}
376
377inline
378void BitStringImpUtil::andEqWord(bsl::uint64_t *dstValue,
379 bsl::uint64_t srcValue)
380{
381 BSLS_ASSERT(dstValue);
382
383 *dstValue &= srcValue;
384}
385
386inline
387void BitStringImpUtil::minusEqBits(bsl::uint64_t *dstValue,
388 int dstIndex,
389 bsl::uint64_t srcValue,
390 int numBits)
391{
392 BSLS_ASSERT(dstValue);
393 BSLS_ASSERT( 0 <= dstIndex);
394 BSLS_ASSERT( 0 <= numBits);
395 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
396
398 *dstValue &= BitMaskUtil::zero64(dstIndex, numBits) |
399 (~srcValue << dstIndex);
400 }
401}
402
403inline
404void BitStringImpUtil::minusEqWord(bsl::uint64_t *dstValue,
405 bsl::uint64_t srcValue)
406{
407 BSLS_ASSERT(dstValue);
408
409 *dstValue &= ~srcValue;
410}
411
412inline
413void BitStringImpUtil::orEqBits(bsl::uint64_t *dstValue,
414 int dstIndex,
415 bsl::uint64_t srcValue,
416 int numBits)
417{
418 BSLS_ASSERT(dstValue);
419 BSLS_ASSERT( 0 <= dstIndex);
420 BSLS_ASSERT( 0 <= numBits);
421 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
422
424 *dstValue |= (srcValue & BitMaskUtil::lt64(numBits)) << dstIndex;
425 }
426}
427
428inline
429void BitStringImpUtil::orEqWord(bsl::uint64_t *dstValue,
430 bsl::uint64_t srcValue)
431{
432 BSLS_ASSERT(dstValue);
433
434 *dstValue |= srcValue;
435}
436
437inline
438void BitStringImpUtil::setEqBits(bsl::uint64_t *dstValue,
439 int dstIndex,
440 bsl::uint64_t srcValue,
441 int numBits)
442{
443 BSLS_ASSERT(dstValue);
444 BSLS_ASSERT(0 <= dstIndex);
445 BSLS_ASSERT(0 <= numBits);
446 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
447
449 const bsl::uint64_t mask = BitMaskUtil::lt64(numBits);
450
451 *dstValue &= ~(mask << dstIndex);
452 *dstValue |= (srcValue & mask) << dstIndex;
453 }
454}
455
456inline
457void BitStringImpUtil::setEqWord(bsl::uint64_t *dstValue,
458 bsl::uint64_t srcValue)
459{
460 BSLS_ASSERT(dstValue);
461
462 *dstValue = srcValue;
463}
464
465inline
466void BitStringImpUtil::xorEqBits(bsl::uint64_t *dstValue,
467 int dstIndex,
468 bsl::uint64_t srcValue,
469 int numBits)
470{
471 BSLS_ASSERT(dstValue);
472 BSLS_ASSERT( 0 <= dstIndex);
473 BSLS_ASSERT( 0 <= numBits);
474 BSLS_ASSERT(dstIndex + numBits <= k_BITS_PER_UINT64);
475
477 *dstValue ^= (srcValue & BitMaskUtil::lt64(numBits)) << dstIndex;
478 }
479}
480
481inline
482void BitStringImpUtil::xorEqWord(bsl::uint64_t *dstValue,
483 bsl::uint64_t srcValue)
484{
485 BSLS_ASSERT(dstValue);
486
487 *dstValue ^= srcValue;
488}
489
490 // Accessors
491
492inline
494{
495 BSLS_ASSERT(0 != value);
496
498}
499
500inline
502{
503 BSLS_ASSERT(0 != value);
504
505 return BitUtil::numTrailingUnsetBits(value);
506}
507
508} // close package namespace
509
510
511#endif
512
513// ----------------------------------------------------------------------------
514// Copyright 2015 Bloomberg Finance L.P.
515//
516// Licensed under the Apache License, Version 2.0 (the "License");
517// you may not use this file except in compliance with the License.
518// You may obtain a copy of the License at
519//
520// http://www.apache.org/licenses/LICENSE-2.0
521//
522// Unless required by applicable law or agreed to in writing, software
523// distributed under the License is distributed on an "AS IS" BASIS,
524// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
525// See the License for the specific language governing permissions and
526// limitations under the License.
527// ----------------------------- END-OF-FILE ----------------------------------
528
529/** @} */
530/** @} */
531/** @} */
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#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:448
static bsl::uint64_t lt64(int index)
Definition bdlb_bitmaskutil.h:382
Definition bdlb_bitstringimputil.h:245
static void setEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:438
static void minusEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:387
static void orEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:429
static int find1AtMaxIndexRaw(bsl::uint64_t value)
Definition bdlb_bitstringimputil.h:493
static void orEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:413
static void setEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:457
static void andEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:378
static void xorEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:466
static void minusEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:404
static int find1AtMinIndexRaw(bsl::uint64_t value)
Definition bdlb_bitstringimputil.h:501
@ k_BITS_PER_UINT64
Definition bdlb_bitstringimputil.h:248
static void xorEqWord(bsl::uint64_t *dstValue, bsl::uint64_t srcValue)
Definition bdlb_bitstringimputil.h:482
static void andEqBits(bsl::uint64_t *dstValue, int dstIndex, bsl::uint64_t srcValue, int numBits)
Definition bdlb_bitstringimputil.h:361
static int numTrailingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:456
static int numLeadingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:407