BDE 4.14.0 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.
234struct Alignment {
235
236 // TYPES
237
238 /// Types of alignment strategy.
239 enum Strategy {
240 /// Align memory block based on the most restrictive alignment
241 /// requirements of the host platform.
243
244 /// Align memory block on an address that is the largest power of
245 /// two that evenly divides the size (in bytes) of the block.
247
248 /// Align memory block based on the least restrictive alignment
249 /// requirements of the host platform (1-byte aligned).
251 };
252
253#ifndef BDE_OMIT_INTERNAL_DEPRECATED
254 /// Define the minimum alignment that satisfies all types.
255 ///
256 /// @deprecated This `enum` is deprecated. Use
257 /// `AlignmentUtil::BSLS_MAX_ALIGNMENT` instead.
258 enum {
260 };
261
262 /// Primitive type with most stringent alignment requirement.
263 ///
264 /// @deprecated Use @ref AlignmentUtil::MaxAlignedType instead.
266
267 /// `struct` with most stringent alignment requirement.
268 ///
269 /// @deprecated Use @ref Alignment::MaxAlignedType instead.
273#endif // BDE_OMIT_INTERNAL_DEPRECATED
274
275 // CLASS METHODS
276
277 /// Return the string representation of the specified enumerator
278 /// `value`. The string representation of `value` matches its
279 /// corresponding enumerator name with the "BSLS_" prefix elided. For
280 /// example:
281 /// @code
282 /// bsl::cout << Alignment::toAscii(Alignment::BSLS_NATURAL);
283 /// @endcode
284 /// will print the following on standard output:
285 /// @code
286 /// NATURAL
287 /// @endcode
288 static const char *toAscii(Alignment::Strategy value);
289
290#ifndef BDE_OMIT_INTERNAL_DEPRECATED
291 /// Calculate a usable alignment for an object of specified `size` bytes
292 /// in the absence of compile-time knowledge of the object's alignment
293 /// requirements. Return the largest power of two that evenly divides
294 /// size, up to a maximum of `MAX_ALIGNMENT`. It is guaranteed that an
295 /// object of `size` bytes can be safely aligned on this return value.
296 /// Depending on the machine architecture and compiler options, the
297 /// returned alignment may be more than required for two reasons:
298 /// @code
299 /// 1. The object may be composed entirely of elements, such as
300 /// 'char', which have minimal alignment restrictions.
301 ///
302 /// 2. The architecture may have lenient alignment requirements.
303 /// Even if this is the case, aligning on a stricter boundary may
304 /// improve performance.
305 /// @endcode
306 /// The behavior is undefined unless `0 < size`.
307 ///
308 /// @deprecated Use @ref AlignmentUtil::calculateAlignmentFromSize instead.
309 static int calculateAlignmentFromSize(int size);
310
311 /// Return the smallest non-negative offset in bytes that, when added to
312 /// the specified `address`, yields the specified `alignment`. The
313 /// behavior is undefined unless `0 < alignment` and `alignment` is a
314 /// power of 2.
315 ///
316 /// @deprecated Use @ref AlignmentUtil::calculateAlignmentOffset instead.
317 static int calculateAlignmentOffset(const void *address, int alignment);
318
319 /// Return `true` if the specified `address` is aligned on a 2-byte
320 /// boundary (i.e., the integer value of `address` is divisible by 2),
321 /// and `false` otherwise.
322 ///
323 /// @deprecated Use @ref AlignmentUtil::is2ByteAligned instead.
324 static bool is2ByteAligned(const void *address);
325
326 /// Return `true` if the specified `address` is aligned on a 4-byte
327 /// boundary (i.e., the integer value of `address` is divisible by 4),
328 /// and `false` otherwise.
329 ///
330 /// @deprecated Use @ref AlignmentUtil::is4ByteAligned instead.
331 static bool is4ByteAligned(const void *address);
332
333 /// Return `true` if the specified `address` is aligned on an 8-byte
334 /// boundary (i.e., the integer value of `address` is divisible by 8),
335 /// and `false` otherwise.
336 ///
337 /// @deprecated Use @ref AlignmentUtil::is8ByteAligned instead.
338 static bool is8ByteAligned(const void *address);
339#endif // BDE_OMIT_INTERNAL_DEPRECATED
340};
341
342} // close package namespace
343
344#ifndef BDE_OMIT_INTERNAL_DEPRECATED
345
346namespace bsls {
347
348// ============================================================================
349// INLINE FUNCTION DEFINITIONS
350// ============================================================================
351
352 // ----------------
353 // struct Alignment
354 // ----------------
355
356// CLASS METHODS
357inline
362
363inline
365 int alignment)
366{
367 return AlignmentUtil::calculateAlignmentOffset(address, alignment);
368}
369
370inline
371bool Alignment::is2ByteAligned(const void *address)
372{
373 return AlignmentUtil::is2ByteAligned(address);
374}
375
376inline
377bool Alignment::is4ByteAligned(const void *address)
378{
379 return AlignmentUtil::is4ByteAligned(address);
380}
381
382inline
383bool Alignment::is8ByteAligned(const void *address)
384{
385 return AlignmentUtil::is8ByteAligned(address);
386}
387
388} // close package namespace
389
390#endif // BDE_OMIT_INTERNAL_DEPRECATED
391
392#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
393// ============================================================================
394// BACKWARD COMPATIBILITY
395// ============================================================================
396
397/// This alias is defined for backward compatibility.
399#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
400
401
402
403#endif
404
405// ----------------------------------------------------------------------------
406// Copyright 2013 Bloomberg Finance L.P.
407//
408// Licensed under the Apache License, Version 2.0 (the "License");
409// you may not use this file except in compliance with the License.
410// You may obtain a copy of the License at
411//
412// http://www.apache.org/licenses/LICENSE-2.0
413//
414// Unless required by applicable law or agreed to in writing, software
415// distributed under the License is distributed on an "AS IS" BASIS,
416// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
417// See the License for the specific language governing permissions and
418// limitations under the License.
419// ----------------------------- END-OF-FILE ----------------------------------
420
421/** @} */
422/** @} */
423/** @} */
bsls::Alignment bsls_Alignment
This alias is defined for backward compatibility.
Definition bsls_alignment.h:398
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691
static bool is2ByteAligned(const void *address)
Definition bsls_alignmentutil.h:434
static bool is4ByteAligned(const void *address)
Definition bsls_alignmentutil.h:440
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:282
static int calculateAlignmentOffset(const void *address, int alignment)
Definition bsls_alignmentutil.h:408
@ BSLS_MAX_ALIGNMENT
Definition bsls_alignmentutil.h:275
static bool is8ByteAligned(const void *address)
Definition bsls_alignmentutil.h:446
static int calculateAlignmentFromSize(std::size_t size)
Definition bsls_alignmentutil.h:344
Definition bsls_alignment.h:270
MaxAlignedType d_align
Definition bsls_alignment.h:271
Definition bsls_alignment.h:234
static const char * toAscii(Alignment::Strategy value)
static int calculateAlignmentOffset(const void *address, int alignment)
Definition bsls_alignment.h:364
static bool is2ByteAligned(const void *address)
Definition bsls_alignment.h:371
static int calculateAlignmentFromSize(int size)
Definition bsls_alignment.h:358
@ MAX_ALIGNMENT
Definition bsls_alignment.h:259
static bool is8ByteAligned(const void *address)
Definition bsls_alignment.h:383
AlignmentUtil::MaxAlignedType MaxAlignedType
Definition bsls_alignment.h:265
static bool is4ByteAligned(const void *address)
Definition bsls_alignment.h:377
Strategy
Types of alignment strategy.
Definition bsls_alignment.h:239
@ BSLS_NATURAL
Definition bsls_alignment.h:246
@ BSLS_MAXIMUM
Definition bsls_alignment.h:242
@ BSLS_BYTEALIGNED
Definition bsls_alignment.h:250