BDE 4.14.0 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/// class my_SequentialPool {
125/// // This class allocates memory from an internal pool of memory buffers
126/// // using natural alignment. All allocated memory is managed internally
127/// // by the pool and released when the pool is destroyed.
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/// void replenishBuffer(bsls::Types::size_type size);
143/// // Replenish the current buffer with memory that satisfies an
144/// // allocation request having at least the specified 'size' (in
145/// // bytes).
146///
147/// public:
148/// // CREATORS
149/// explicit my_SequentialPool(bslma::Allocator *basicAllocator = 0);
150/// // Create a memory pool that dispenses heterogeneous blocks of
151/// // memory (of varying, user-specified sizes). Optionally specify a
152/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
153/// // 0, the currently installed default allocator is used.
154///
155/// ~my_SequentialPool();
156/// // Destroy this memory pool and release all associated memory.
157///
158/// // MANIPULATORS
159/// void *allocate(bsls::Types::size_type size);
160/// // Return the address of a contiguous block of naturally-aligned
161/// // memory of the specified 'size' (in bytes). The behavior is
162/// // undefined unless '0 < size'.
163/// };
164/// @endcode
165/// The implementations of the constructor and destructor are elided since
166/// `allocate` alone is sufficient to illustrate the use of
167/// `bdlma::BufferImpUtil`:
168/// @code
169/// void *my_SequentialPool::allocate(bsls::Types::size_type size)
170/// {
171/// assert(0 < size);
172///
173/// void *address = bdlma::BufferImpUtil::allocateFromBuffer(
174/// &d_cursor,
175/// d_buffer_p,
176/// d_bufferSize,
177/// size,
178/// bsls::Alignment::BSLS_NATURAL);
179/// @endcode
180/// Note that if there is insufficient space in `d_buffer_p`,
181/// `allocateFromBuffer` returns 0:
182/// @code
183/// if (address) {
184/// return address; // RETURN
185/// }
186///
187/// replenishBuffer(size);
188///
189/// return bdlma::BufferImpUtil::allocateFromBufferRaw(
190/// &d_cursor,
191/// d_buffer_p,
192/// size,
193/// bsls::Alignment::BSLS_NATURAL);
194/// }
195/// @endcode
196/// Note that the *raw* version is used because the contract of
197/// `replenishBuffer` guarantees that the buffer will have sufficient space to
198/// satisfy the allocation request of the specified `size`.
199/// @}
200/** @} */
201/** @} */
202
203/** @addtogroup bdl
204 * @{
205 */
206/** @addtogroup bdlma
207 * @{
208 */
209/** @addtogroup bdlma_bufferimputil
210 * @{
211 */
212
213#include <bdlscm_version.h>
214
215#include <bsls_alignment.h>
216#include <bsls_types.h>
217
218
219namespace bdlma {
220
221 // ====================
222 // struct BufferImpUtil
223 // ====================
224
225/// This `struct` provides a namespace for a suite of pure procedures for
226/// allocating memory from a buffer.
228
229 // CLASS METHODS
230
231 /// Allocate a memory block of the specified `size` (in bytes) from the
232 /// specified `buffer` having the specified `bufferSize` (in bytes) at
233 /// the specified `cursor` position, using the specified alignment
234 /// `strategy`. Return the address of the allocated memory block if
235 /// `buffer` contains sufficient available memory, and 0 otherwise. The
236 /// `cursor` is set to the first byte position immediately after the
237 /// allocated memory if there is sufficient memory, and not modified
238 /// otherwise. The behavior is undefined unless `0 < size`,
239 /// `0 <= *cursor`, and `*cursor <= bufferSize`.
241 char *buffer,
242 bsls::Types::size_type bufferSize,
245
246 /// Allocate a maximally-aligned memory block of the specified `size`
247 /// (in bytes) from the specified `buffer` having the specified
248 /// `bufferSize` (in bytes) at the specified `cursor` position. Return
249 /// the address of the allocated memory block if `buffer` contains
250 /// sufficient available memory, and 0 otherwise. The `cursor` is set
251 /// to the first byte position immediately after the allocated memory if
252 /// there is sufficient memory, and not modified otherwise. The
253 /// behavior is undefined unless `0 < size`, `0 <= *cursor`, and
254 /// `*cursor <= bufferSize`.
256 bsls::Types::IntPtr *cursor,
257 char *buffer,
258 bsls::Types::size_type bufferSize,
260
261 /// Allocate a naturally-aligned memory block of the specified `size`
262 /// (in bytes) from the specified `buffer` having the specified
263 /// `bufferSize` (in bytes) at the specified `cursor` position. Return
264 /// the address of the allocated memory block if `buffer` contains
265 /// sufficient available memory, and 0 otherwise. The `cursor` is set
266 /// to the first byte position immediately after the allocated memory if
267 /// there is sufficient memory, and not modified otherwise. The
268 /// behavior is undefined unless `0 < size`, `0 <= *cursor`, and
269 /// `*cursor <= bufferSize`.
271 bsls::Types::IntPtr *cursor,
272 char *buffer,
273 bsls::Types::size_type bufferSize,
275
276 /// Allocate a 1-byte-aligned memory block of the specified `size` (in
277 /// bytes) from the specified `buffer` having the specified `bufferSize`
278 /// (in bytes) at the specified `cursor` position. Return the address
279 /// of the allocated memory block if `buffer` contains sufficient
280 /// available memory, and 0 otherwise. The `cursor` is set to the first
281 /// byte position immediately after the allocated memory if there is
282 /// sufficient memory, and not modified otherwise. The behavior is
283 /// undefined unless `0 < size`, `0 <= *cursor`, and
284 /// `*cursor <= bufferSize`.
286 bsls::Types::IntPtr *cursor,
287 char *buffer,
288 bsls::Types::size_type bufferSize,
290
291 /// Allocate a memory block of the specified `size` (in bytes) from the
292 /// specified `buffer` at the specified `cursor` position, using the
293 /// specified alignment `strategy`. Return the address of the allocated
294 /// memory block. The `cursor` is set to the first byte position
295 /// immediately after the allocated memory. The behavior is undefined
296 /// unless `0 < size`, `buffer` contains sufficient available memory,
297 /// and `cursor` refers to a valid position in `buffer`.
299 char *buffer,
302
303 /// Allocate a maximally-aligned memory block of the specified `size`
304 /// (in bytes) from the specified `buffer` at the specified `cursor`
305 /// position. Return the address of the allocated memory block. The
306 /// `cursor` is set to the first byte position immediately after the
307 /// allocated memory. The behavior is undefined unless `0 < size`,
308 /// `buffer` contains sufficient available memory, and `cursor` refers
309 /// to a valid position in `buffer`.
311 bsls::Types::IntPtr *cursor,
312 char *buffer,
314
315 /// Allocate a naturally-aligned memory block of the specified `size`
316 /// (in bytes) from the specified `buffer` at the specified `cursor`
317 /// position. Return the address of the allocated memory block. The
318 /// `cursor` is set to the first byte position immediately after the
319 /// allocated memory. The behavior is undefined unless `0 < size`,
320 /// `buffer` contains sufficient available memory, and `cursor` refers
321 /// to a valid position in `buffer`.
323 bsls::Types::IntPtr *cursor,
324 char *buffer,
326
327 /// Allocate a 1-byte-aligned memory block of the specified `size` (in
328 /// bytes) from the specified `buffer` at the specified `cursor`
329 /// position. Return the address of the allocated memory block. The
330 /// `cursor` is set to the first byte position immediately after the
331 /// allocated memory. 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
340} // close package namespace
341
342
343#endif
344
345// ----------------------------------------------------------------------------
346// Copyright 2016 Bloomberg Finance L.P.
347//
348// Licensed under the Apache License, Version 2.0 (the "License");
349// you may not use this file except in compliance with the License.
350// You may obtain a copy of the License at
351//
352// http://www.apache.org/licenses/LICENSE-2.0
353//
354// Unless required by applicable law or agreed to in writing, software
355// distributed under the License is distributed on an "AS IS" BASIS,
356// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
357// See the License for the specific language governing permissions and
358// limitations under the License.
359// ----------------------------- END-OF-FILE ----------------------------------
360
361/** @} */
362/** @} */
363/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlma_alignedallocator.h:276
Definition bdlma_bufferimputil.h:227
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:239
std::size_t size_type
Definition bsls_types.h:124
std::ptrdiff_t IntPtr
Definition bsls_types.h:130