BDE 4.39.x 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 specified `flags`.
122 ///
123 /// \pre The behavior is undefined unless
124 /// `flags <= k_Mask`.
126 unsigned flags = 0);
127
128 /// Create a `NullableAllocatedValue_PointerBitsPair` having the same
129 /// value as the specified `original` object.
131 const NullableAllocatedValue_PointerBitsPair& original) = default;
132
133 /// Destroy this object.
135
136 // ACCESSORS
137
138 /// Return `true` if this object and the specified `other` have the same
139 /// value, and `false` otherwise. Two
140 /// `NullableAllocatedValue_PointerBitsPair` objects have the same value
141 /// when their pointer and flags are the same.
143
144 /// Return the held pointer.
145 t_TYPE* getPointer () const;
146
147 /// Return the value of the flag specified by `idx`.
148 ///
149 /// \pre The behavior is undefined unless `idx < t_NUM_BITS`.
150 bool readFlag(unsigned idx) const;
151
152 // MANIPULATORS
153
154 /// Assign to this object the value of the specified `rhs` object, and
155 /// return a reference providing modifiable access to this object.
157 const NullableAllocatedValue_PointerBitsPair& rhs) = default;
158
159 /// Clear the flag specified by `idx`.
160 /// \pre The behavior is undefined unless
161 /// `idx < t_NUM_BITS`.
162 void clearFlag(unsigned idx);
163
164 /// Set the flag specified by `idx`.
165 /// \pre The behavior is undefined unless
166 /// `idx < t_NUM_BITS`.
167 void setFlag(unsigned idx);
168
169 /// Set the held pointer to the value of the specified `new_ptr`.
170 void setPointer (t_TYPE *new_ptr);
171
172 /// Efficiently exchange the value of this object with the value of the
173 /// specified `other` object. This method provides the no-throw
174 /// exception-safety guarantee.
176
177 };
178
179// FREE FUNCTIONS
180
181/// Return `true` if the specified `lhs` and `rhs` objects have the same
182/// value, and `false` otherwise. Two
183/// `NullableAllocatedValue_PointerBitsPair` objects have the same value
184/// when their pointer and flags are the same.
185template <class t_TYPE, unsigned t_NUM_BITS>
186bool operator==(
189
190/// Return `false` if the specified `lhs` and `rhs` objects have the same
191/// value, and `true` otherwise. Two
192/// `NullableAllocatedValue_PointerBitsPair` objects have the same value
193/// when their pointer and flags are the same.
194template <class t_TYPE, unsigned t_NUM_BITS>
195bool operator!=(
198
199/// Exchange the values of the specified `a` and `b` objects. This function
200/// provides the no-throw exception-safety guarantee.
201template <class t_TYPE, unsigned t_NUM_BITS>
204
205} // close package namespace
206
207
208// ============================================================================
209// INLINE DEFINITIONS
210// ============================================================================
211
212 // --------------------------------------------
213 // class NullableAllocatedValue_PointerBitsPair
214 // --------------------------------------------
215
216
217// CREATORS
218template <class t_TYPE, unsigned t_NUM_BITS>
219inline
222: d_Value(0)
223{
224 // ensure that t_TYPE is sufficiently aligned to store t_NUM_BITS flags
226 static_cast<bsl::size_t>(k_Mask) <
227 static_cast<bsl::size_t>(bsls::AlignmentFromType<t_TYPE>::VALUE));
228}
229
230template <class t_TYPE, unsigned t_NUM_BITS>
231inline
234: d_Value(reinterpret_cast<uintptr_t>(ptr))
235{
236 BSLS_ASSERT_OPT((d_Value & k_Mask) == 0); // pointer is correctly aligned
237 BSLS_ASSERT_OPT(flags <= k_Mask); // flags are too large to fit
238 d_Value |= (flags & k_Mask); // set the flags
239}
240
241// ACCESSORS
242template <class t_TYPE, unsigned t_NUM_BITS>
243inline
249
250
251template <class t_TYPE, unsigned t_NUM_BITS>
252inline
255{
256 return reinterpret_cast<t_TYPE *>(d_Value & ~uintptr_t(k_Mask));
257}
258
259template <class t_TYPE, unsigned t_NUM_BITS>
260inline
262 ::readFlag(unsigned idx) const
263{
264 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
265 return 0 != (d_Value & (1 << idx));
266}
267
268// MANIPULATORS
269template <class t_TYPE, unsigned t_NUM_BITS>
270inline
272 ::clearFlag(unsigned idx)
273{
274 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
275
276 const uintptr_t mask = 1U << idx;
277 d_Value &= ~mask;
278}
279
280template <class t_TYPE, unsigned t_NUM_BITS>
281inline
283 ::setFlag(unsigned idx)
284{
285 BSLS_ASSERT_OPT(idx <= t_NUM_BITS);
286
287 const uintptr_t mask = 1U << idx;
288 d_Value |= mask;
289}
290
291template <class t_TYPE, unsigned t_NUM_BITS>
292inline
294 ::setPointer(t_TYPE *new_ptr)
295{
296 const uintptr_t value = reinterpret_cast<uintptr_t>(new_ptr);
297 BSLS_ASSERT_OPT((value & k_Mask) == 0); // pointer is sufficiently aligned
298
299 // Copy the existing flags over the new pointer
300 d_Value = value | (d_Value & k_Mask);
301}
302
303template <class t_TYPE, unsigned t_NUM_BITS>
304inline
310
311
312// FREE FUNCTIONS
313template <class t_TYPE, unsigned t_NUM_BITS>
314inline
318{
319 return lhs.equal(rhs);
320}
321
322template <class t_TYPE, unsigned t_NUM_BITS>
323inline
327{
328 return !(lhs == rhs);
329}
330
331template <class t_TYPE, unsigned t_NUM_BITS>
332inline
333void bdlb::swap(
336{
337 a.swap(b);
338}
339
340
341
342#endif // ! defined(INCLUDED_BDLB_NULLABLEALLOCATEDVALUE_POINTERBITSPAIR)
343
344// ----------------------------------------------------------------------------
345// Copyright 2023 Bloomberg Finance L.P.
346//
347// Licensed under the Apache License, Version 2.0 (the "License");
348// you may not use this file except in compliance with the License.
349// You may obtain a copy of the License at
350//
351// http://www.apache.org/licenses/LICENSE-2.0
352//
353// Unless required by applicable law or agreed to in writing, software
354// distributed under the License is distributed on an "AS IS" BASIS,
355// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
356// See the License for the specific language governing permissions and
357// limitations under the License.
358// ----------------------------- END-OF-FILE ----------------------------------
359
360/** @} */
361/** @} */
362/** @} */
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:182
void setFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:283
void clearFlag(unsigned idx)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:272
NullableAllocatedValue_PointerBitsPair()
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:221
bool readFlag(unsigned idx) const
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:262
t_TYPE * getPointer() const
Return the held pointer.
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:254
bool equal(const NullableAllocatedValue_PointerBitsPair &other) const
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:244
void swap(NullableAllocatedValue_PointerBitsPair &other)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:305
NullableAllocatedValue_PointerBitsPair(t_TYPE *ptr, unsigned flags=0)
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:233
void setPointer(t_TYPE *new_ptr)
Set the held pointer to the value of the specified new_ptr.
Definition bdlb_nullableallocatedvalue_pointerbitspair.h:294
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
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:378