BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma_memoryresourceimpsupport.h
Go to the documentation of this file.
1/// @file bslma_memoryresourceimpsupport.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_memoryresourceimpsupport.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_MEMORYRESOURCEIMPSUPPORT
9#define INCLUDED_BSLMA_MEMORYRESOURCEIMPSUPPORT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_memoryresourceimpsupport bslma_memoryresourceimpsupport
15/// @brief Provide support for implementing memory resources
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_memoryresourceimpsupport
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_memoryresourceimpsupport-purpose"> Purpose</a>
25/// * <a href="#bslma_memoryresourceimpsupport-classes"> Classes </a>
26/// * <a href="#bslma_memoryresourceimpsupport-description"> Description </a>
27/// * <a href="#bslma_memoryresourceimpsupport-usage"> Usage </a>
28/// * <a href="#bslma_memoryresourceimpsupport-example-1-write-a-memory_resource-using-singularpointer"> Example 1: Write a memory_resource using singularPointer </a>
29///
30/// # Purpose {#bslma_memoryresourceimpsupport-purpose}
31/// Provide support for implementing memory resources
32///
33/// # Classes {#bslma_memoryresourceimpsupport-classes}
34///
35/// - bslma::MemoryResourceImpSupport - namespace for resource support functions
36///
37/// @see bslma_memoryresource, bslma_allocator
38///
39/// # Description {#bslma_memoryresourceimpsupport-description}
40/// This component provides support functions and types for
41/// implementing a class derived from `bsl::memory_resource`. Currently, it
42/// provides a utility function, `singularPointer`, that provides a pointer
43/// suitable for an `allocate` function to return when a zero-sized allocation
44/// is requested.
45///
46/// ## Usage {#bslma_memoryresourceimpsupport-usage}
47///
48///
49/// This section illustrates intended use of this component.
50///
51/// ### Example 1: Write a memory_resource using singularPointer {#bslma_memoryresourceimpsupport-example-1-write-a-memory_resource-using-singularpointer}
52///
53///
54/// In this example, we derive a `NewDeleteResource` class, derived from
55/// `bsl::memory_resource`, that allocates and deallocate using `operator new`
56/// and `operator delete`, respectively, and uses `singularPointer()` as a
57/// special value when allocating and allocating zero bytes.
58///
59/// First, we define the class interface, which implements the protected virtual
60/// functions `do_allocate`, `do_deallocate`, and `do_is_equal`:
61/// @code
62/// #include <bslma_memoryresource.h>
63/// #include <bslma_memoryresourceimpsupport.h>
64/// #include <bsls_alignmentutil.h>
65/// #include <bsls_assert.h>
66///
67/// /// Memory resource that allocates using `operator new`.
68/// class NewDeleteResource : public bsl::memory_resource {
69/// protected:
70/// // PROTECTED MANIPULATORS
71///
72/// /// Return the specified `size` bytes with the specified `alignment`
73/// /// allocated from the global heap using `operator new`. The behavior
74/// /// is undefined unless the specified `alignment` is less than or equal
75/// /// to the maximum platform alignment.
76/// void *do_allocate(std::size_t size, std::size_t alignment)
77/// BSLS_KEYWORD_OVERRIDE;
78///
79/// /// Deallocate the memory block specified by `p` having the specified
80/// /// `size` and `alignment` from the global heap using `operator
81/// /// delete`. The behavior is undefined unless `p` was returned from a
82/// /// previous call to `allocate`, using the same `size` and `alignment`.
83/// void do_deallocate(void *p, std::size_t size, std::size_t alignment)
84/// BSLS_KEYWORD_OVERRIDE;
85///
86/// /// Return `true` if `x` is a `NewDeleteResource` and `false`
87/// /// otherwise.
88/// bool do_is_equal(const bsl::memory_resource& x) const
89/// BSLS_KEYWORD_NOEXCEPT BSLS_KEYWORD_OVERRIDE;
90/// };
91/// @endcode
92/// Next, we implement the `do_allocate` method, which forwards most requests to
93/// `operator new`. Section [basic.stc.dynamic.allocation] of the C++ standard,
94/// however states that the return value of an allocation function when the
95/// requested size is zero is a *non-null* pointer to a suitably aligned block
96/// of storage, so we use `singularPointer` to provide the address in such
97/// circumstances:
98/// @code
99/// #include <new> // `align_val_t` and aligned `new`
100///
101/// void *NewDeleteResource::do_allocate(std::size_t size,
102/// std::size_t alignment)
103/// {
104/// if (0 == size) {
105/// return bslma::MemoryResourceImpSupport::singularPointer();
106/// }
107///
108/// #ifdef __cpp_aligned_new
109/// return ::operator new(size, std::align_val_t(alignment));
110/// #else
111/// (void) alignment;
112/// BSLS_ASSERT(alignment <= bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT);
113/// return ::operator new(size);
114/// #endif
115/// }
116/// @endcode
117/// Next, we implement the `do_deallocate` method, which forwards most requests
118/// to `operator delete`, but does nothing if the incoming pointer was the
119/// result of a zero-sized allocation:
120/// @code
121/// void NewDeleteResource::do_deallocate(void *p,
122/// std::size_t size,
123/// std::size_t alignment)
124/// {
125/// (void) size; // Not used in OPT build
126///
127/// if (bslma::MemoryResourceImpSupport::singularPointer() == p) {
128/// BSLS_ASSERT(0 == size);
129/// return;
130/// }
131///
132/// BSLS_ASSERT(0 < size);
133/// #ifdef __cpp_aligned_new
134/// ::operator delete(p, std::align_val_t(alignment));
135/// #else
136/// (void) (size, alignment);
137/// BSLS_ASSERT(alignment <= bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT);
138/// ::operator delete(p);
139/// #endif
140/// }
141/// @endcode
142/// Next, we complete the implementation with `do_is_equal`. All instances of
143/// `NewDeleteResource` compare equal, so we need only check that the argument
144/// is a `NewDeleteResource`. As a short-cut, we check if the address of `b` is
145/// the same as `this`, to quickly catch the common case that they are both
146/// pointers to the singleton object:
147/// @code
148/// bool NewDeleteResource::do_is_equal(const bsl::memory_resource& b) const
149/// BSLS_KEYWORD_NOEXCEPT
150/// {
151/// return this == &b || 0 != dynamic_cast<const NewDeleteResource *>(&b);
152/// }
153/// @endcode
154/// Now, when we call `allocate`, we observe that each non-zero allocation
155/// yields a different pointer, whereas all of the zero allocations yield the
156/// same address.
157/// @code
158/// int main()
159/// {
160/// NewDeleteResource r;
161/// void *p1 = r.allocate(1, 1);
162/// void *p2 = r.allocate(8);
163/// assert(p1 != p2);
164///
165/// void *p3 = r.allocate(0, 1);
166/// void *p4 = r.allocate(0, 4);
167/// assert(p3 != p1);
168/// assert(p3 != p2);
169/// assert(p3 == p4);
170/// @endcode
171/// Finally, when we deallocate memory, we would expect nothing to happen when
172/// deallocating the zero-sized blocks `p3` and `p4`:
173/// @code
174/// r.deallocate(p1, 1, 1);
175/// r.deallocate(p2, 8);
176/// r.deallocate(p3, 0, 1);
177/// r.deallocate(p4, 0, 4);
178/// }
179/// @endcode
180/// @}
181/** @} */
182/** @} */
183
184/** @addtogroup bsl
185 * @{
186 */
187/** @addtogroup bslma
188 * @{
189 */
190/** @addtogroup bslma_memoryresourceimpsupport
191 * @{
192 */
193
194#include <bslscm_version.h>
195
196#include <bsls_alignmentutil.h>
197#include <bsls_keyword.h>
198
199
200namespace bslma {
201
202 // ===========================================
203 // struct MemoryResourceImpSupport_AlignedData
204 // ===========================================
205
206/// COMPONENT-PRIVATE struct -- DO NOT USE. Maximally aligned `struct` holding
207/// an unsigned 64-bit integer. This `struct` is exposed in the component
208/// header so that `MemoryResourceImpSupport::singularPointer` can be
209/// implemented as `constexpr` and `inline`.
210///
211/// See @ref bslma_memoryresourceimpsupport
216
217 // ==============================
218 // class MemoryResourceImpSupport
219 // ==============================
220
221/// Namespace for functions that support implementing a memory resource.
222///
223/// See @ref bslma_memoryresourceimpsupport
225
226 private:
227
228 // PRIVATE CLASS DATA
229
230 /// Singleton used to produce singular address distinct from all other
231 /// addresses.
232 static const MemoryResourceImpSupport_AlignedData s_singularObject;
233
234 public:
235 // CLASS METHODS
236
237 /// Return a maximally aligned, non-null pointer that cannnot organically
238 /// result from any operation other than calling this function; i.e., it is
239 /// a *singular* pointer. Within a single program execution, no other
240 /// current or future object, of any storage duration, will have an address
241 /// matching this function's return value. The returned address may be
242 /// used by an allocation function to indicate a *non-allocation*, e.g., the result of allocating zero bytes.
243 ///
244 /// \pre The behavior is undefined if the returned pointer is dereferenced.
245 ///
246 /// \note Note that the same address is
247 /// returned each time this function is called.
249};
250
251// ============================================================================
252// TEMPLATE AND INLINE FUNCTION IMPLEMENTATIONS
253// ============================================================================
254
255// CLASS METHODS
256
258{
259 // The singleton object is 'const', so any attempt to construct an object
260 // through the returned pointer should result in a protection error.
261 return const_cast<unsigned long long *>(&s_singularObject.d_data);
262}
263
264} // close package namespace
265
266
267// FREE OPERATORS
268
269
270
271#endif // ! defined(INCLUDED_BSLMA_MEMORYRESOURCEIMPSUPPORT)
272
273// ----------------------------------------------------------------------------
274// Copyright 2024 Bloomberg Finance L.P.
275//
276// Licensed under the Apache License, Version 2.0 (the "License");
277// you may not use this file except in compliance with the License.
278// You may obtain a copy of the License at
279//
280// http://www.apache.org/licenses/LICENSE-2.0
281//
282// Unless required by applicable law or agreed to in writing, software
283// distributed under the License is distributed on an "AS IS" BASIS,
284// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
285// See the License for the specific language governing permissions and
286// limitations under the License.
287// ----------------------------- END-OF-FILE ----------------------------------
288
289/** @} */
290/** @} */
291/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
Definition baljsn_encoder_testtypes.h:76
Definition bslma_memoryresourceimpsupport.h:212
unsigned long long d_data
Definition bslma_memoryresourceimpsupport.h:213
bsls::AlignmentUtil::MaxAlignedType d_alignment
Definition bslma_memoryresourceimpsupport.h:214
Definition bslma_memoryresourceimpsupport.h:224
static BSLS_KEYWORD_CONSTEXPR void * singularPointer()
Definition bslma_memoryresourceimpsupport.h:257
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:307