BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_nullableallocatedvalue_pointerbitspair.h
Go to the documentation of this file.
1/// @file bdlb_nullableallocatedvalue_pointerbitspair.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_nullableallocatedvalue_pointerbitspair.h -*-C++-*-
8
9#ifndef INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_POINTERBITSPAIR
10#define INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_POINTERBITSPAIR
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bdlb_nullableallocatedvalue_pointerbitspair bdlb_nullableallocatedvalue_pointerbitspair
16/// @brief Provide a mechanism for using the unused bits of a pointer.
17/// @addtogroup bdl
18/// @{
19/// @addtogroup bdlb
20/// @{
21/// @addtogroup bdlb_nullableallocatedvalue_pointerbitspair
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bdlb_nullableallocatedvalue_pointerbitspair-purpose"> Purpose</a>
26/// * <a href="#bdlb_nullableallocatedvalue_pointerbitspair-classes"> Classes </a>
27/// * <a href="#bdlb_nullableallocatedvalue_pointerbitspair-description"> Description </a>
28///
29/// # Purpose {#bdlb_nullableallocatedvalue_pointerbitspair-purpose}
30/// Provide a mechanism for using the unused bits of a pointer.
31///
32/// # Classes {#bdlb_nullableallocatedvalue_pointerbitspair-classes}
33///
34/// - bdlb::NullableAllocatedValue_PointerBitsPair: pointer and bits together.
35///
36/// @see bdlb_nullablesllocatedvalue
37///
38/// # Description {#bdlb_nullableallocatedvalue_pointerbitspair-description}
39/// This private, subordinate component to
40/// @ref bdlb_nullableallocatedvalue provides a templated class,
41/// `bdlb::NullableAllocatedValue_PointerBitsPair`, that allows access to the
42/// otherwise unused bits in a pointer to an object. The
43/// `bdlb::NullableAllocatedValue` class template uses
44/// `bdlb::NullableAllocatedValue_PointerBitsPair` to store some state about the
45/// object in the `pointer to allocator` field, saving 4 to 8 bytes (depending
46/// on the platform) for each instantiation.
47///
48/// `bldb::NullableAllocatedValue_PointerBitsPair` is a non-allocator-aware,
49/// value-semantic type.
50/// @}
51/** @} */
52/** @} */
53
54/** @addtogroup bdl
55 * @{
56 */
57/** @addtogroup bdlb
58 * @{
59 */
60/** @addtogroup bdlb_nullableallocatedvalue_pointerbitspair
61 * @{
62 */
63
64#include <bslscm_version.h>
65
66#include <bslalg_swaputil.h>
67
68#include <bslmf_assert.h>
69
70#include <bsls_assert.h>
73#include <bsls_platform.h>
74
75#include <bsl_cstddef.h> // bsl::size_t
76
77#include <cstddef>
78#include <cstdlib>
79#include <typeinfo>
80
81#include <stdint.h> // uintptr_t
82
83
84namespace bdlb {
85
86 // =======================
87 // class Pointer_Bits_Pair
88 // =======================
89
90/// This is a component-private class. Do not use.
91///
92/// This regular, value-semantic class provides a mechanism for storing a
93/// number of bit flags in the otherwise unused bits of a pointer to the
94/// template parameter class `t_TYPE`. The number of bits that can be
95/// stored is dependent upon the required alignment of the class `t_TYPE`.
96///
97/// See @ref bdlb_nullableallocatedvalue_pointerbitspair
98template <class t_TYPE, unsigned t_NUM_BITS>
100
101 // DATA
102
103 /// `k_Mask` is a bitmask constant containing a `1` for each of the
104 /// positions in the stored value where a flag can be stored, and a `0`
105 /// for all of the other positions.
106 enum { k_Mask = (1 << t_NUM_BITS ) - 1 };
107
108 // Contains the pointer value and the flag bits; or-ed together.
109 uintptr_t d_Value;
110
111 BSLMF_ASSERT(t_NUM_BITS > 0); // Can't store zero bits
112 BSLMF_ASSERT(t_NUM_BITS <= 8); // Too many bits
113
114 public:
115 // CREATORS
116
117 /// Construct an object holding a null pointer value and all flags set
118 /// to false.
120
121 /// Construct an object holding the specified `ptr` and optionally
122 /// specified `flags`. The behavior is undefined unless
123 /// `flags <= k_Mask`.
125 unsigned flags = 0);
126
127 /// Create a `NullableAllocatedValue_PointerBitsPair` having the same
128 /// value as the specified `original` object.
130 const NullableAllocatedValue_PointerBitsPair& original) = default;
131
132 /// Destroy this object.
134
135 // ACCESSORS
136
137 /// Return `true` if this object and the specified `other` have the same
138 /// value, and `false` otherwise. Two
139 /// `NullableAllocatedValue_PointerBitsPair` objects have the same value
140 /// when their pointer and flags are the same.
142
143 /// Return the held pointer.
144 t_TYPE* getPointer () const;
145
146 /// Return the value of the flag specified by `idx`. The behavior is
147 /// undefined unless `idx < t_NUM_BITS`.
148 bool readFlag(unsigned idx) const;
149
150 // MANIPULATORS
151
152 /// Assign to this object the value of the specified `rhs` object, and
153 /// return a reference providing modifiable access to this object.
155 const NullableAllocatedValue_PointerBitsPair& rhs) = default;
156
157 /// Clear the flag specified by `idx`. The behavior is undefined unless
158 /// `idx < t_NUM_BITS`.
159 void clearFlag(unsigned idx);
160
161 /// Set the flag specified by `idx`. The behavior is undefined unless
162 /// `idx < t_NUM_BITS`.
163 void setFlag(unsigned idx);
164
165 /// Set the held pointer to the value of the specified `new_ptr`.
166 void setPointer (t_TYPE *new_ptr);
167
168 /// Efficiently exchange the value of this object with the value of the
169 /// specified `other` object. This method provides the no-throw
170 /// exception-safety guarantee.
172
173 };
174
175// FREE FUNCTIONS
176
177/// Return `true` if the specified `lhs` and `rhs` objects have the same
178/// value, and `false` otherwise. Two
179/// `NullableAllocatedValue_PointerBitsPair` objects have the same value
180/// when their pointer and flags are the same.
181template <class t_TYPE, unsigned t_NUM_BITS>
182bool operator==(
185
186/// Return `false` if the specified `lhs` and `rhs` objects have the same
187/// value, and `true` otherwise. Two
188/// `NullableAllocatedValue_PointerBitsPair` objects have the same value
189/// when their pointer and flags are the same.
190template <class t_TYPE, unsigned t_NUM_BITS>
191bool operator!=(
194
195/// Exchange the values of the specified `a` and `b` objects. This function
196/// provides the no-throw exception-safety guarantee.
197template <class t_TYPE, unsigned t_NUM_BITS>
200
201} // close package namespace
202
203
204// ============================================================================
205// INLINE DEFINITIONS
206// ============================================================================
207
208 // --------------------------------------------
209 // class NullableAllocatedValue_PointerBitsPair
210 // --------------------------------------------
211
212
213// CREATORS
214template <class t_TYPE, unsigned t_NUM_BITS>
215inline
218: d_Value(0)
219{
220 // ensure that t_TYPE is sufficiently aligned to store t_NUM_BITS flags
222 static_cast<bsl::size_t>(k_Mask) <
223 static_cast<bsl::size_t>(bsls::AlignmentFromType<t_TYPE>::VALUE));
224}
225
226template <class t_TYPE, unsigned t_NUM_BITS>
227inline
230: d_Value(reinterpret_cast<uintptr_t>(ptr))
231{
232 BSLS_ASSERT_OPT((d_Value & k_Mask) == 0); // pointer is correctly aligned
233 BSLS_ASSERT_OPT(flags <= k_Mask); // flags are too large to fit
234 d_Value |= (flags & k_Mask); // set the flags
235}
236
237// ACCESSORS
238template <class t_TYPE, unsigned t_NUM_BITS>
239inline
245
246
247template <class t_TYPE, unsigned t_NUM_BITS>
248inline
251{
252 return reinterpret_cast<t_TYPE *>(d_Value & ~uintptr_t(k_Mask));
253}
254
255template <class t_TYPE, unsigned t_NUM_BITS>
256inline
258 ::readFlag(unsigned idx) const
259{
260 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
261 return 0 != (d_Value & (1 << idx));
262}
263
264// MANIPULATORS
265template <class t_TYPE, unsigned t_NUM_BITS>
266inline
268 ::clearFlag(unsigned idx)
269{
270 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
271
272 const uintptr_t mask = 1U << idx;
273 d_Value &= ~mask;
274}
275
276template <class t_TYPE, unsigned t_NUM_BITS>
277inline
279 ::setFlag(unsigned idx)
280{
281 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
282
283 const uintptr_t mask = 1U << idx;
284 d_Value |= mask;
285}
286
287template <class t_TYPE, unsigned t_NUM_BITS>
288inline
290 ::setPointer(t_TYPE *new_ptr)
291{
292 const uintptr_t value = reinterpret_cast<uintptr_t>(new_ptr);
293 BSLS_ASSERT_OPT((value & k_Mask) == 0); // pointer is sufficiently aligned
294
295 // Copy the existing flags over the new pointer
296 d_Value = value | (d_Value & k_Mask);
297}
298
299template <class t_TYPE, unsigned t_NUM_BITS>
300inline
306
307
308// FREE FUNCTIONS
309template <class t_TYPE, unsigned t_NUM_BITS>
310inline
314{
315 return lhs.equal(rhs);
316}
317
318template <class t_TYPE, unsigned t_NUM_BITS>
319inline
323{
324 return !(lhs == rhs);
325}
326
327template <class t_TYPE, unsigned t_NUM_BITS>
328inline
329void bdlb::swap(
332{
333 a.swap(b);
334}
335
336
337
338#endif // ! defined(INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_POINTERBITSPAIR)
339
340// ----------------------------------------------------------------------------
341// Copyright 2023 Bloomberg Finance L.P.
342//
343// Licensed under the Apache License, Version 2.0 (the "License");
344// you may not use this file except in compliance with the License.
345// You may obtain a copy of the License at
346//
347// http://www.apache.org/licenses/LICENSE-2.0
348//
349// Unless required by applicable law or agreed to in writing, software
350// distributed under the License is distributed on an "AS IS" BASIS,
351// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
352// See the License for the specific language governing permissions and
353// limitations under the License.
354// ----------------------------- END-OF-FILE ----------------------------------
355
356/** @} */
357/** @} */
358/** @} */
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:99
NullableAllocatedValue_PointerBitsPair(const NullableAllocatedValue_PointerBitsPair &original)=default
NullableAllocatedValue_PointerBitsPair & operator=(const NullableAllocatedValue_PointerBitsPair &rhs)=default
~NullableAllocatedValue_PointerBitsPair()=default
Destroy this object.
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
void setFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:279
void clearFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:268
NullableAllocatedValue_PointerBitsPair()
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:217
bool readFlag(unsigned idx) const
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:258
t_TYPE * getPointer() const
Return the held pointer.
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:250
bool equal(const NullableAllocatedValue_PointerBitsPair &other) const
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:240
void swap(NullableAllocatedValue_PointerBitsPair &other)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:301
NullableAllocatedValue_PointerBitsPair(t_TYPE *ptr, unsigned flags=0)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:229
void setPointer(t_TYPE *new_ptr)
Set the held pointer to the value of the specified new_ptr.
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:290
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:1856
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_algorithmworkaroundutil.h:74
bool operator!=(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
void swap(NullableAllocatedValue< TYPE > &a, NullableAllocatedValue< TYPE > &b)
bool operator==(const BigEndianInt16 &lhs, const BigEndianInt16 &rhs)
Definition bsls_alignmentfromtype.h:376