BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlma_bufferimputil.h
Go to the documentation of this file.
1/// @file bdlma_bufferimputil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlma_bufferimputil.h -*-C++-*-
8#ifndef INCLUDED_BDLMA_BUFFERIMPUTIL
9#define INCLUDED_BDLMA_BUFFERIMPUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlma_bufferimputil bdlma_bufferimputil
15/// @brief Provide pure procedures for allocating memory from a buffer.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlma
19/// @{
20/// @addtogroup bdlma_bufferimputil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlma_bufferimputil-purpose"> Purpose</a>
25/// * <a href="#bdlma_bufferimputil-classes"> Classes </a>
26/// * <a href="#bdlma_bufferimputil-description"> Description </a>
27/// * <a href="#bdlma_bufferimputil-raw-versus-non-raw"> Raw versus Non-Raw </a>
28/// * <a href="#bdlma_bufferimputil-usage"> Usage </a>
29///
30/// # Purpose {#bdlma_bufferimputil-purpose}
31/// Provide pure procedures for allocating memory from a buffer.
32///
33/// # Classes {#bdlma_bufferimputil-classes}
34///
35/// - bdlma::BufferImpUtil: pure procedures for allocating memory from a buffer
36///
37/// @see bdlma_buffermanager
38///
39/// # Description {#bdlma_bufferimputil-description}
40/// This component provides a `struct`, `bdlma::BufferImpUtil`,
41/// that implements procedures for allocating memory from a buffer using an
42/// indicated memory alignment strategy. Each of the procedures take a buffer,
43/// the size of the buffer, a cursor pointing to the free memory within the
44/// buffer, and the allocation size. Two of the procedures,
45/// `allocateFromBuffer` and `allocateFromBufferRaw`, take an additional
46/// argument that specifies the memory alignment strategy to apply. The other
47/// six procedures apply a specific memory alignment strategy as indicated by
48/// their names (e.g., `allocateNaturallyAlignedFromBuffer` and
49/// `allocateMaximallyAlignedFromBufferRaw`). In all cases, a pointer to the
50/// allocated memory is returned, and the cursor passed in is updated to point
51/// to the portion of the buffer that contains the next available free memory.
52///
53/// For example, suppose we initially have a 2-byte aligned buffer having a size
54/// of 5 bytes, and a cursor pointing to the first byte:
55/// @code
56/// 0 1 2 3 4
57/// _____ _____ _____ _____ _____
58/// buffer (size = 5): | F | F | F | F | F | A - allocated
59/// `=====^=====^=====^=====^=====' F - free
60/// ^ W - wasted
61/// |
62/// cursor
63/// @endcode
64/// Using natural alignment, suppose 1 byte is allocated from the buffer using
65/// `allocateFromBuffer`:
66/// @code
67/// BufferImpUtil::allocateFromBuffer(&cursor, buffer, bufferSize, 1
68/// bsls::AlignmentStrategy::BSLS_NATURAL);
69/// @endcode
70/// The cursor will be advanced as follows:
71/// @code
72/// 0 1 2 3 4
73/// _____ _____ _____ _____ _____
74/// buffer (size = 5): | A | F | F | F | F | A - allocated
75/// `=====^=====^=====^=====^=====' F - free
76/// ^ W - wasted
77/// |
78/// cursor
79/// @endcode
80/// Suppose `allocateFromBuffer` is then used to allocate 2 bytes:
81/// @code
82/// BufferImpUtil::allocateFromBuffer(&cursor, buffer, bufferSize, 2,
83/// bsls::AlignmentStrategy::BSLS_NATURAL);
84/// @endcode
85/// The cursor will be advanced as follows (after taking into consideration the
86/// alignment strategy used):
87/// @code
88/// 0 1 2 3 4
89/// _____ _____ _____ _____ _____
90/// buffer (size = 5): | A | W | A | A | F | A - allocated
91/// `=====^=====^=====^=====^=====' F - free
92/// ^ W - wasted
93/// |
94/// cursor
95/// @endcode
96/// The byte at (only) position 1 is skipped because of the natural alignment
97/// strategy (otherwise, more bytes would have been skipped if maximum alignment
98/// was used). See @ref bsls_alignment for more details about memory alignment.
99///
100/// ## Raw versus Non-Raw {#bdlma_bufferimputil-raw-versus-non-raw}
101///
102///
103/// The raw and non-raw versions differ in behavior only when the requested
104/// memory size is larger than the memory available within the provided buffer
105/// (after taking memory alignment into consideration). The raw versions result
106/// in undefined behavior, while the non-raw versions return 0. Note that the
107/// safety of the non-raw versions comes at the extra cost of a conditional
108/// statement. For example, clients of the non-raw versions must check the
109/// return value to ensure successful allocation.
110///
111/// ## Usage {#bdlma_bufferimputil-usage}
112///
113///
114/// This component is typically used by a class that manages a memory buffer.
115/// First, suppose we have a class that maintains a linked list of memory
116/// blocks, details of which are elided:
117/// @code
118/// class BlockList {
119/// // ...
120/// };
121/// @endcode
122/// We can then create our memory manager using `BlockList`:
123/// @code
124/// /// This class allocates memory from an internal pool of memory buffers
125/// /// using natural alignment. All allocated memory is managed internally
126/// /// by the pool and released when the pool is destroyed.
127/// class my_SequentialPool {
128///
129/// // DATA
130/// char *d_buffer_p; // pointer to current buffer
131///
132/// bsls::Types::size_type d_bufferSize; // size (in bytes) of the
133/// // current buffer
134///
135/// bsls::Types::IntPtr d_cursor; // byte offset to unused memory
136/// // in buffer
137///
138/// BlockList d_blockList; // used to replenish memory
139///
140/// private:
141/// // PRIVATE MANIPULATORS
142///
143/// /// Replenish the current buffer with memory that satisfies an
144/// /// allocation request having at least the specified `size` (in
145/// /// bytes).
146/// void replenishBuffer(bsls::Types::size_type size);
147///
148/// public:
149/// // CREATORS
150///
151/// /// Create a memory pool that dispenses heterogeneous blocks of
152/// /// memory (of varying, user-specified sizes). Optionally specify a
153/// /// `basicAllocator` used to supply memory. If `basicAllocator` is
154/// /// 0, the currently installed default allocator is used.
155/// explicit my_SequentialPool(bslma::Allocator *basicAllocator = 0);
156///
157/// /// Destroy this memory pool and release all associated memory.
158/// ~my_SequentialPool();
159///
160/// // MANIPULATORS
161///
162/// /// Return the address of a contiguous block of naturally-aligned
163/// /// memory of the specified `size` (in bytes). The behavior is
164/// /// undefined unless `0 < size`.
165/// void *allocate(bsls::Types::size_type size);
166/// };
167/// @endcode
168/// The implementations of the constructor and destructor are elided since
169/// `allocate` alone is sufficient to illustrate the use of
170/// `bdlma::BufferImpUtil`:
171/// @code
172/// void *my_SequentialPool::allocate(bsls::Types::size_type size)
173/// {
174/// assert(0 < size);
175///
176/// void *address = bdlma::BufferImpUtil::allocateFromBuffer(
177/// &d_cursor,
178/// d_buffer_p,
179/// d_bufferSize,
180/// size,
181/// bsls::Alignment::BSLS_NATURAL);
182/// @endcode
183/// Note that if there is insufficient space in `d_buffer_p`,
184/// `allocateFromBuffer` returns 0:
185/// @code
186/// if (address) {
187/// return address; // RETURN
188/// }
189///
190/// replenishBuffer(size);
191///
192/// return bdlma::BufferImpUtil::allocateFromBufferRaw(
193/// &d_cursor,
194/// d_buffer_p,
195/// size,
196/// bsls::Alignment::BSLS_NATURAL);
197/// }
198/// @endcode
199/// Note that the *raw* version is used because the contract of
200/// `replenishBuffer` guarantees that the buffer will have sufficient space to
201/// satisfy the allocation request of the specified `size`.
202/// @}
203/** @} */
204/** @} */
205
206/** @addtogroup bdl
207 * @{
208 */
209/** @addtogroup bdlma
210 * @{
211 */
212/** @addtogroup bdlma_bufferimputil
213 * @{
214 */
215
216#include <bdlscm_version.h>
217
218#include <bsls_alignment.h>
219#include <bsls_types.h>
220
221
222namespace bdlma {
223
224 // ====================
225 // struct BufferImpUtil
226 // ====================
227
228/// This `struct` provides a namespace for a suite of pure procedures for
229/// allocating memory from a buffer.
230///
231/// See @ref bdlma_bufferimputil
233
234 // CLASS METHODS
235
236 /// Allocate a memory block of the specified `size` (in bytes) from the
237 /// specified `buffer` having the specified `bufferSize` (in bytes) at
238 /// the specified `cursor` position, using the specified alignment
239 /// `strategy`. Return the address of the allocated memory block if
240 /// `buffer` contains sufficient available memory, and 0 otherwise. The
241 /// `cursor` is set to the first byte position immediately after the
242 /// allocated memory if there is sufficient memory, and not modified otherwise.
243 ///
244 /// \pre The behavior is undefined unless `0 < size`,
245 /// `0 <= *cursor`, and `*cursor <= bufferSize`.
247 char *buffer,
248 bsls::Types::size_type bufferSize,
251
252 /// Allocate a maximally-aligned memory block of the specified `size`
253 /// (in bytes) from the specified `buffer` having the specified
254 /// `bufferSize` (in bytes) at the specified `cursor` position. Return
255 /// the address of the allocated memory block if `buffer` contains
256 /// sufficient available memory, and 0 otherwise. The `cursor` is set
257 /// to the first byte position immediately after the allocated memory if
258 /// there is sufficient memory, and not modified otherwise.
259 ///
260 /// \pre The behavior is undefined unless `0 < size`, `0 <= *cursor`, and
261 /// `*cursor <= bufferSize`.
263 bsls::Types::IntPtr *cursor,
264 char *buffer,
265 bsls::Types::size_type bufferSize,
267
268 /// Allocate a naturally-aligned memory block of the specified `size`
269 /// (in bytes) from the specified `buffer` having the specified
270 /// `bufferSize` (in bytes) at the specified `cursor` position. Return
271 /// the address of the allocated memory block if `buffer` contains
272 /// sufficient available memory, and 0 otherwise. The `cursor` is set
273 /// to the first byte position immediately after the allocated memory if
274 /// there is sufficient memory, and not modified otherwise.
275 ///
276 /// \pre The behavior is undefined unless `0 < size`, `0 <= *cursor`, and
277 /// `*cursor <= bufferSize`.
279 bsls::Types::IntPtr *cursor,
280 char *buffer,
281 bsls::Types::size_type bufferSize,
283
284 /// Allocate a 1-byte-aligned memory block of the specified `size` (in
285 /// bytes) from the specified `buffer` having the specified `bufferSize`
286 /// (in bytes) at the specified `cursor` position. Return the address
287 /// of the allocated memory block if `buffer` contains sufficient
288 /// available memory, and 0 otherwise. The `cursor` is set to the first
289 /// byte position immediately after the allocated memory if there is
290 /// sufficient memory, and not modified otherwise.
291 ///
292 /// \pre The behavior is undefined unless `0 < size`, `0 <= *cursor`, and
293 /// `*cursor <= bufferSize`.
295 bsls::Types::IntPtr *cursor,
296 char *buffer,
297 bsls::Types::size_type bufferSize,
299
300 /// Allocate a memory block of the specified `size` (in bytes) from the
301 /// specified `buffer` at the specified `cursor` position, using the
302 /// specified alignment `strategy`. Return the address of the allocated
303 /// memory block. The `cursor` is set to the first byte position
304 /// immediately after the allocated memory.
305 ///
306 /// \pre The behavior is undefined unless `0 < size`, `buffer` contains sufficient available memory,
307 /// and `cursor` refers to a valid position in `buffer`.
309 char *buffer,
312
313 /// Allocate a maximally-aligned memory block of the specified `size`
314 /// (in bytes) from the specified `buffer` at the specified `cursor`
315 /// position. Return the address of the allocated memory block. The
316 /// `cursor` is set to the first byte position immediately after the allocated memory.
317 ///
318 /// \pre The behavior is undefined unless `0 < size`,
319 /// `buffer` contains sufficient available memory, and `cursor` refers
320 /// to a valid position in `buffer`.
322 bsls::Types::IntPtr *cursor,
323 char *buffer,
325
326 /// Allocate a naturally-aligned memory block of the specified `size`
327 /// (in bytes) from the specified `buffer` at the specified `cursor`
328 /// position. Return the address of the allocated memory block. The
329 /// `cursor` is set to the first byte position immediately after the allocated memory.
330 ///
331 /// \pre The behavior is undefined unless `0 < size`,
332 /// `buffer` contains sufficient available memory, and `cursor` refers
333 /// to a valid position in `buffer`.
335 bsls::Types::IntPtr *cursor,
336 char *buffer,
338
339 /// Allocate a 1-byte-aligned memory block of the specified `size` (in
340 /// bytes) from the specified `buffer` at the specified `cursor`
341 /// position. Return the address of the allocated memory block. The
342 /// `cursor` is set to the first byte position immediately after the allocated memory.
343 ///
344 /// \pre The behavior is undefined unless `0 < size`,
345 /// `buffer` contains sufficient available memory, and `cursor` refers
346 /// to a valid position in `buffer`.
348 bsls::Types::IntPtr *cursor,
349 char *buffer,
351};
352
353} // close package namespace
354
355
356#endif
357
358// ----------------------------------------------------------------------------
359// Copyright 2016 Bloomberg Finance L.P.
360//
361// Licensed under the Apache License, Version 2.0 (the "License");
362// you may not use this file except in compliance with the License.
363// You may obtain a copy of the License at
364//
365// http://www.apache.org/licenses/LICENSE-2.0
366//
367// Unless required by applicable law or agreed to in writing, software
368// distributed under the License is distributed on an "AS IS" BASIS,
369// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
370// See the License for the specific language governing permissions and
371// limitations under the License.
372// ----------------------------- END-OF-FILE ----------------------------------
373
374/** @} */
375/** @} */
376/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlma_alignedallocator.h:278
Definition bdlma_bufferimputil.h:232
static void * allocateFromBufferRaw(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type size, bsls::Alignment::Strategy strategy)
static void * allocateMaximallyAlignedFromBufferRaw(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type size)
static void * allocateOneByteAlignedFromBufferRaw(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type size)
static void * allocateFromBuffer(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type bufferSize, bsls::Types::size_type size, bsls::Alignment::Strategy strategy)
static void * allocateOneByteAlignedFromBuffer(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type bufferSize, bsls::Types::size_type size)
static void * allocateNaturallyAlignedFromBuffer(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type bufferSize, bsls::Types::size_type size)
static void * allocateNaturallyAlignedFromBufferRaw(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type size)
static void * allocateMaximallyAlignedFromBuffer(bsls::Types::IntPtr *cursor, char *buffer, bsls::Types::size_type bufferSize, bsls::Types::size_type size)
Strategy
Types of alignment strategy.
Definition bsls_alignment.h:241
std::size_t size_type
Definition bsls_types.h:126
std::ptrdiff_t IntPtr
Definition bsls_types.h:132