BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_alignment.h
Go to the documentation of this file.
1/// @file bsls_alignment.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_alignment.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ALIGNMENT
9#define INCLUDED_BSLS_ALIGNMENT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_alignment bsls_alignment
15/// @brief Provide a namespace for enumerating memory alignment strategies.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_alignment
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_alignment-purpose"> Purpose</a>
25/// * <a href="#bsls_alignment-classes"> Classes </a>
26/// * <a href="#bsls_alignment-description"> Description </a>
27/// * <a href="#bsls_alignment-alignment-strategy"> Alignment Strategy </a>
28/// * <a href="#bsls_alignment-usage"> Usage </a>
29///
30/// # Purpose {#bsls_alignment-purpose}
31/// Provide a namespace for enumerating memory alignment strategies.
32///
33/// # Classes {#bsls_alignment-classes}
34///
35/// - bsls::Alignment: namespace for enumerated alignment strategy values
36///
37/// @see bsls_alignmentutil
38///
39/// # Description {#bsls_alignment-description}
40/// This component provides a namespace, `bsls::Alignment`, for
41/// enumerating alignment strategies, and provides a function, `toAscii`, that
42/// converts each of the enumerators to its corresponding string representation.
43///
44/// ## Alignment Strategy {#bsls_alignment-alignment-strategy}
45///
46///
47/// This component supports three alignment strategies: 1) MAXIMUM ALIGNMENT,
48/// 2) NATURAL ALIGNMENT, and 3) 1-BYTE ALIGNMENT.
49///
50/// 1. MAXIMUM ALIGNMENT: This strategy, as indicated by the enumerator
51/// `BSLS_MAXIMUM`, specifies that a memory block be aligned as per the
52/// *most* restrictive alignment requirement on the host platform.
53/// 2. NATURAL ALIGNMENT: This strategy, as indicated by the enumerator
54/// `BSLS_NATURAL`, specifies that a memory block be aligned based on the
55/// size (in bytes) of that block. An object of a fundamental type (`int`,
56/// etc.) is *naturally* *aligned* when its size evenly divides its address.
57/// An object of an aggregate type has natural alignment if the alignment of
58/// the most-restrictively aligned sub-object evenly divides the address of
59/// the aggregate. Natural alignment is always at least as restrictive as
60/// the compiler's required alignment.
61/// 3. 1-BYTE ALIGNMENT: This strategy, as indicated by the enumerator
62/// `BSLS_BYTEALIGNED`, specifies that a memory block may be aligned
63/// arbitrarily on any 1-byte boundary. This is the *least* restrictive
64/// alignment requirement.
65///
66/// ## Usage {#bsls_alignment-usage}
67///
68///
69/// Suppose that we want to create a static function, `allocateFromBuffer`, that
70/// takes a buffer, the size of the buffer, a cursor indicating a position
71/// within the buffer, an allocation request size, and a memory alignment
72/// strategy; `allocateFromBuffer` returns a pointer to a block of memory,
73/// wholly contained within the buffer, having the specified size and alignment.
74/// As a side-effect, the cursor is updated to refer to the next available free
75/// byte in the buffer. Such a function could be used by a memory manager to
76/// satisfy allocation requests from internally-managed buffers. Clients of
77/// this function indicate which alignment strategy to use based on their
78/// specific requirements.
79///
80/// Our `allocateFromBuffer` function depends on an alignment utility,
81/// `my_AlignmentUtil`, whose minimal interface is limited to that required by
82/// this usage example. (See the @ref bsls_alignmentutil component for a more
83/// realistic alignment utility.):
84/// @code
85/// struct my_AlignmentUtil {
86/// // This 'struct' provides a namespace for basic types and utilities
87/// // related to memory alignment.
88///
89/// // TYPES
90///
91/// /// Provide the *minimal* value that satisfies the alignment
92/// /// requirements for *all* types on the host platform. Note that 8
93/// /// is used for illustration purposes only; an actual implementation
94/// /// would employ template meta-programming to deduce the value at
95/// /// compile time.
96/// enum {
97/// MY_MAX_PLATFORM_ALIGNMENT = 8
98/// };
99///
100/// // CLASS METHODS
101///
102/// /// Calculate a usable alignment for a memory block of the specified
103/// /// `size` (in bytes) in the absence of compile-time knowledge of
104/// /// the block's alignment requirements. Return the largest power of
105/// /// two that evenly divides `size`, up to a maximum of
106/// /// `MY_MAX_PLATFORM_ALIGNMENT`. It is guaranteed that a block of
107/// /// `size` bytes can be safely aligned on the return value. The
108/// /// behavior is undefined unless `0 < size`.
109/// static int calculateAlignmentFromSize(int size);
110///
111/// /// Return the smallest non-negative offset (in bytes) that, when
112/// /// added to the specified `address`, yields the specified
113/// /// `alignment`. The behavior is undefined unless `0 != alignment`
114/// /// and `alignment` is a non-negative, integral power of 2.
115/// static int calculateAlignmentOffset(const void *address,
116/// int alignment);
117/// };
118/// @endcode
119/// The definition of our `allocateFromBuffer` function is as follows:
120/// @code
121/// /// Allocate a memory block of the specified `size` (in bytes) from the
122/// /// specified `buffer` having the specified `bufferSize` at the
123/// /// specified `cursor` position, using the specified alignment
124/// /// `strategy`. Return the address of the allocated memory block if
125/// /// `buffer` contains sufficient available memory, and 0 otherwise. The
126/// /// `cursor` is set to the first byte position immediately after the
127/// /// allocated memory (which might be 1 byte past the end of `buffer`) if
128/// /// there is sufficient memory, and is not modified otherwise. The
129/// /// behavior is undefined unless `0 <= bufferSize`, `0 < size`, and
130/// /// `cursor` refers to a valid position in `buffer`.
131/// static void *allocateFromBuffer(int *cursor,
132/// char *buffer,
133/// int bufferSize,
134/// int size,
135/// bsls::Alignment::Strategy strategy)
136/// {
137/// @endcode
138/// First we assert the function pre-conditions:
139/// @code
140/// assert(cursor);
141/// assert(buffer);
142/// assert(0 <= bufferSize);
143/// assert(0 < size);
144/// @endcode
145/// Then, based on the alignment `strategy`, we calculate the alignment value
146/// that can satisfy the allocation request. In the case of
147/// `bsls::Alignment::BSLS_NATURAL`, we calculate the alignment from `size`; for
148/// `bsls::Alignment::BSLS_MAXIMUM`, we use the platform-dependent
149/// `my_AlignmentUtil::MY_MAX_PLATFORM_ALIGNMENT` value; and for
150/// `bsls::Alignment::BSLS_BYTEALIGNED`, we simply use 1:
151/// @code
152/// const int alignment =
153/// strategy == bsls::Alignment::BSLS_NATURAL
154/// ? my_AlignmentUtil::calculateAlignmentFromSize(size)
155/// : strategy == bsls::Alignment::BSLS_MAXIMUM
156/// ? my_AlignmentUtil::MY_MAX_PLATFORM_ALIGNMENT
157/// : 1;
158/// @endcode
159/// Now we calculate the offset from the current `cursor` value that can satisfy
160/// the `alignment` requirements:
161/// @code
162/// const int offset = my_AlignmentUtil::calculateAlignmentOffset(
163/// buffer + *cursor,
164/// alignment);
165///
166/// @endcode
167/// Next we check if the available free memory in `buffer` can satisfy the
168/// allocation request; 0 is returned if the request cannot be satisfied:
169/// @code
170/// if (*cursor + offset + size > bufferSize) {
171/// return 0; // RETURN
172/// }
173///
174/// void *result = &buffer[*cursor + offset];
175/// *cursor += offset + size;
176///
177/// @endcode
178/// Finally, return the address of the correctly aligned memory block:
179/// @code
180/// return result;
181/// }
182/// @endcode
183/// The `allocateFromBuffer` function may be used by a memory manager that needs
184/// to appropriately align memory blocks that are allocated from
185/// internally-managed buffers. For an example, see the @ref bslma_bufferimputil
186/// component.
187/// @}
188/** @} */
189/** @} */
190
191/** @addtogroup bsl
192 * @{
193 */
194/** @addtogroup bsls
195 * @{
196 */
197/** @addtogroup bsls_alignment
198 * @{
199 */
200
201#ifndef BDE_OMIT_INTERNAL_DEPRECATED
202
203#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
205#include <bsls_alignmentimp.h>
206#include <bsls_alignmenttotype.h>
207#include <bsls_platform.h>
208
209#include <cstddef> // for std::size_t
210#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
211
212// Temporarily define the legacy 'bsls_AlignmentOf' to refer to its
213// replacement, 'bsls::AlignmentFromType'.
214
215#ifndef bsls_AlignmentOf
216#define bsls_AlignmentOf bsls::AlignmentFromType
217#endif
218
219// required for some code below wrapped in ifndef BDE_OMIT_INTERNAL_DEPRECATED
220
221#include <bsls_alignmentutil.h>
222#endif // BDE_OMIT_INTERNAL_DEPRECATED
223
224
225
226namespace bsls {
227
228 // ================
229 // struct Alignment
230 // ================
231
232/// This `struct` provides a namespace for enumerating the set of strategies
233/// for aligning arbitrary blocks of memory.
234///
235/// See @ref bsls_alignment
236struct Alignment {
237
238 // TYPES
239
240 /// Types of alignment strategy.
241 enum Strategy {
242 /// Align memory block based on the most restrictive alignment
243 /// requirements of the host platform.
245
246 /// Align memory block on an address that is the largest power of
247 /// two that evenly divides the size (in bytes) of the block.
249
250 /// Align memory block based on the least restrictive alignment
251 /// requirements of the host platform (1-byte aligned).
253 };
254
255#ifndef BDE_OMIT_INTERNAL_DEPRECATED
256 /// Define the minimum alignment that satisfies all types.
257 ///
258 /// @deprecated This `enum` is deprecated. Use
259 /// `AlignmentUtil::BSLS_MAX_ALIGNMENT` instead.
260 enum {
262 };
263
264 /// Primitive type with most stringent alignment requirement.
265 ///
266 /// @deprecated Use @ref AlignmentUtil::MaxAlignedType instead.
268
269 /// `struct` with most stringent alignment requirement.
270 ///
271 /// @deprecated Use @ref Alignment::MaxAlignedType instead.
272 ///
273 /// See @ref bsls_alignment
277#endif // BDE_OMIT_INTERNAL_DEPRECATED
278
279 // CLASS METHODS
280
281 /// Return the string representation of the specified enumerator
282 /// `value`. The string representation of `value` matches its
283 /// corresponding enumerator name with the "BSLS_" prefix elided. For
284 /// example:
285 /// @code
286 /// bsl::cout << Alignment::toAscii(Alignment::BSLS_NATURAL);
287 /// @endcode
288 /// will print the following on standard output:
289 /// @code
290 /// NATURAL
291 /// @endcode
292 static const char *toAscii(Alignment::Strategy value);
293
294#ifndef BDE_OMIT_INTERNAL_DEPRECATED
295 /// Calculate a usable alignment for an object of specified `size` bytes
296 /// in the absence of compile-time knowledge of the object's alignment
297 /// requirements. Return the largest power of two that evenly divides
298 /// size, up to a maximum of `MAX_ALIGNMENT`. It is guaranteed that an
299 /// object of `size` bytes can be safely aligned on this return value.
300 /// Depending on the machine architecture and compiler options, the
301 /// returned alignment may be more than required for two reasons:
302 /// @code
303 /// 1. The object may be composed entirely of elements, such as
304 /// 'char', which have minimal alignment restrictions.
305 ///
306 /// 2. The architecture may have lenient alignment requirements.
307 /// Even if this is the case, aligning on a stricter boundary may
308 /// improve performance.
309 /// @endcode
310 ///
311 /// \pre The behavior is undefined unless `0 < size`.
312 ///
313 /// @deprecated Use @ref AlignmentUtil::calculateAlignmentFromSize instead.
314 static int calculateAlignmentFromSize(int size);
315
316 /// Return the smallest non-negative offset in bytes that, when added to
317 /// the specified `address`, yields the specified `alignment`.
318 ///
319 /// \pre The behavior is undefined unless `0 < alignment` and `alignment` is a
320 /// power of 2.
321 ///
322 /// @deprecated Use @ref AlignmentUtil::calculateAlignmentOffset instead.
323 static int calculateAlignmentOffset(const void *address, int alignment);
324
325 /// Return `true` if the specified `address` is aligned on a 2-byte
326 /// boundary (i.e., the integer value of `address` is divisible by 2),
327 /// and `false` otherwise.
328 ///
329 /// @deprecated Use @ref AlignmentUtil::is2ByteAligned instead.
330 static bool is2ByteAligned(const void *address);
331
332 /// Return `true` if the specified `address` is aligned on a 4-byte
333 /// boundary (i.e., the integer value of `address` is divisible by 4),
334 /// and `false` otherwise.
335 ///
336 /// @deprecated Use @ref AlignmentUtil::is4ByteAligned instead.
337 static bool is4ByteAligned(const void *address);
338
339 /// Return `true` if the specified `address` is aligned on an 8-byte
340 /// boundary (i.e., the integer value of `address` is divisible by 8),
341 /// and `false` otherwise.
342 ///
343 /// @deprecated Use @ref AlignmentUtil::is8ByteAligned instead.
344 static bool is8ByteAligned(const void *address);
345#endif // BDE_OMIT_INTERNAL_DEPRECATED
346};
347
348} // close package namespace
349
350#ifndef BDE_OMIT_INTERNAL_DEPRECATED
351
352namespace bsls {
353
354// ============================================================================
355// INLINE FUNCTION DEFINITIONS
356// ============================================================================
357
358 // ----------------
359 // struct Alignment
360 // ----------------
361
362// CLASS METHODS
363inline
368
369inline
371 int alignment)
372{
373 return AlignmentUtil::calculateAlignmentOffset(address, alignment);
374}
375
376inline
377bool Alignment::is2ByteAligned(const void *address)
378{
379 return AlignmentUtil::is2ByteAligned(address);
380}
381
382inline
383bool Alignment::is4ByteAligned(const void *address)
384{
385 return AlignmentUtil::is4ByteAligned(address);
386}
387
388inline
389bool Alignment::is8ByteAligned(const void *address)
390{
391 return AlignmentUtil::is8ByteAligned(address);
392}
393
394} // close package namespace
395
396#endif // BDE_OMIT_INTERNAL_DEPRECATED
397
398#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
399// ============================================================================
400// BACKWARD COMPATIBILITY
401// ============================================================================
402
403/// This alias is defined for backward compatibility.
405#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
406
407
408
409#endif
410
411// ----------------------------------------------------------------------------
412// Copyright 2013 Bloomberg Finance L.P.
413//
414// Licensed under the Apache License, Version 2.0 (the "License");
415// you may not use this file except in compliance with the License.
416// You may obtain a copy of the License at
417//
418// http://www.apache.org/licenses/LICENSE-2.0
419//
420// Unless required by applicable law or agreed to in writing, software
421// distributed under the License is distributed on an "AS IS" BASIS,
422// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
423// See the License for the specific language governing permissions and
424// limitations under the License.
425// ----------------------------- END-OF-FILE ----------------------------------
426
427/** @} */
428/** @} */
429/** @} */
bsls::Alignment bsls_Alignment
This alias is defined for backward compatibility.
Definition bsls_alignment.h:404
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlt_iso8601util.h:707
static bool is2ByteAligned(const void *address)
Definition bsls_alignmentutil.h:487
static bool is4ByteAligned(const void *address)
Definition bsls_alignmentutil.h:493
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:307
static int calculateAlignmentOffset(const void *address, int alignment)
Definition bsls_alignmentutil.h:462
@ BSLS_MAX_ALIGNMENT
Definition bsls_alignmentutil.h:300
static bool is8ByteAligned(const void *address)
Definition bsls_alignmentutil.h:499
static int calculateAlignmentFromSize(std::size_t size)
Definition bsls_alignmentutil.h:398
Definition bsls_alignment.h:274
MaxAlignedType d_align
Definition bsls_alignment.h:275
Definition bsls_alignment.h:236
static const char * toAscii(Alignment::Strategy value)
static int calculateAlignmentOffset(const void *address, int alignment)
Definition bsls_alignment.h:370
static bool is2ByteAligned(const void *address)
Definition bsls_alignment.h:377
static int calculateAlignmentFromSize(int size)
Definition bsls_alignment.h:364
static bool is8ByteAligned(const void *address)
Definition bsls_alignment.h:389
AlignmentUtil::MaxAlignedType MaxAlignedType
Definition bsls_alignment.h:267
@ MAX_ALIGNMENT
Definition bsls_alignment.h:261
static bool is4ByteAligned(const void *address)
Definition bsls_alignment.h:383
Strategy
Types of alignment strategy.
Definition bsls_alignment.h:241
@ BSLS_NATURAL
Definition bsls_alignment.h:248
@ BSLS_MAXIMUM
Definition bsls_alignment.h:244
@ BSLS_BYTEALIGNED
Definition bsls_alignment.h:252