• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2Copyright 2014-2017 Glen Joseph Fernandes
3(glenjofe@gmail.com)
4
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7]
8
9[library Boost.Align
10[quickbook 1.6]
11[id align]
12[copyright 2014-2017 Glen Joseph Fernandes]
13[authors [Fernandes, Glen]]
14[dirname align]
15[license Distributed under the Boost Software License, Version 1.0.]]
16
17[section Introduction]
18
19The Boost Align C++ library provides functions, classes, templates, traits,
20and macros, for the control, inspection, and diagnostic of memory alignment.
21
22[endsect]
23
24[section Rationale]
25
26[heading Dynamic allocation]
27
28C++11 added the ability to specify increased alignment (over-alignment) for
29class types. Unfortunately, `::operator new` allocation functions, `new`
30expressions and the Default Allocator, `std::allocator`, do not support
31dynamic memory allocation of over-aligned data. This library provides
32allocation functions and allocators that respect the alignment requirements of
33a type and so are suitable for allocating memory for over-aligned types.
34
35[variablelist
36[[`aligned_alloc(alignment, size)`]
37[Replaces `::operator new(size, std::nothrow)`]]
38[[`aligned_free(pointer)`]
39[Replaces `::operator delete(pointer, std::nothrow)`]]
40[[`aligned_allocator<T>`][Replaces `std::allocator<T>`]]
41[[`aligned_allocator_adaptor<Allocator>`][Replaces use of Allocator]]
42[[`aligned_delete`][Replaces `std::default_delete<T>`]]]
43
44[heading Pointer alignment]
45
46C++11 provided `std::align` in the standard library to align a pointer value.
47Unfortunately some C++ standard library implementations do not support it yet
48(libstdc++ as far as gcc 4.8.0) and other standard library implementations
49implement it incorrectly (dinkumware in msvc11.0). This library provides it
50for those implementations and also for C++03 compilers where it is equally
51useful.
52
53[heading Querying alignment]
54
55C++11 provided the `std::alignment_of` trait in the standard library to query
56the alignment requirement of a type. Unfortunately some C++ standard library
57vendors do not implement it in an entirely standard conforming manner, such as
58for array types (libc++ as far as clang 3.4). Other vendor implementations
59report incorrect values for certain types, such as pointer to members (msvc
6014.0). This library provides it for those implementations and also for C++03
61compilers where it is equally useful.
62
63[heading Hinting alignment]
64
65Allocating aligned memory is sometimes not enough to ensure that optimal code
66is generated. Developers use specific compiler intrinsics to notify the
67compiler of a given alignment property of a memory block. This library
68provides a macro, `BOOST_ALIGN_ASSUME_ALIGNED`, to abstract that functionality
69for compilers with the appropriate intrinsics.
70
71[heading Checking alignment]
72
73This library provides a function, `is_aligned` to test the alignment of a
74pointer value. It is generally useful in assertions to validate that memory is
75correctly aligned.
76
77[endsect]
78
79[section Examples]
80
81[heading Aligned allocation]
82
83To dynamically allocate storage with desired alignment, you can use the
84`aligned_alloc` function:
85
86[ordered_list
87[`void* storage = boost::alignment::aligned_alloc(alignment, size);`]]
88
89To deallocate storage allocated with the `aligned_alloc` function, use
90the `aligned_free` function:
91
92[ordered_list [`boost::alignment::aligned_free(storage);`]]
93
94[heading Aligned allocator]
95
96For C++ allocator aware code, you can use the `aligned_allocator` class
97template for an allocator that respects over-alignment:
98
99[ordered_list
100[`std::vector<int128_t,
101boost::alignment::aligned_allocator<int128_t> > vector;`]]
102
103This template allows specifying minimum alignment for all dynamic allocations:
104
105[ordered_list
106[`std::vector<double,
107boost::alignment::aligned_allocator<double, 64> > vector;`]]
108
109[heading Aligned allocator adaptor]
110
111To turn an allocator into an allocator that respects over-alignment, you can
112use the `aligned_allocator_adaptor` class template:
113
114[ordered_list
115[`boost::alignment::aligned_allocator_adaptor<First> second(first);`]]
116
117This template allows specifying minimum alignment for all dynamic
118allocations:
119
120[ordered_list
121[`boost::alignment::aligned_allocator_adaptor<First, 64> second(first);`]]
122
123[heading Aligned deleter]
124
125For a deleter that can be paired with `aligned_alloc`, you can use the
126`aligned_delete` class:
127
128[ordered_list
129[`std::unique_ptr<double, boost::alignment::aligned_delete> pointer;`]]
130
131[heading Pointer alignment]
132
133To advance a pointer to the next address with the desired alignment:
134
135[ordered_list
136[`void* pointer = storage;`]
137[`std::size_t space = size;`]
138[`void* result = boost::alignment::align(64, sizeof(double), pointer,
139space);`]]
140
141[heading Querying alignment]
142
143To obtain the alignment of a given type at compie time, you can use:
144
145[ordered_list [`boost::alignment::alignment_of<int128_t>::value`]]
146
147If your compiler supports C++14 variable templates, you can also use:
148
149[ordered_list [`boost::alignment::alignment_of_v<int128_t>`]]
150
151[heading Hinting alignment]
152
153To inform the compiler about the alignment of a pointer, you can use:
154
155[ordered_list [`BOOST_ALIGN_ASSUME_ALIGNED(pointer, 64)`]]
156
157[heading Checking alignment]
158
159To check alignment of a pointer you can use the `is_aligned` function:
160
161[ordered_list [`assert(boost::alignment::is_aligned(pointer, 64));`]]
162
163[endsect]
164
165[section Reference]
166
167[section Functions]
168
169[section align]
170
171[variablelist
172[[`void* align(std::size_t alignment, std::size_t size, void*& ptr,
173std::size_t& space);`]
174[[variablelist
175[[Header][`#include <boost/align/align.hpp>`]]
176[[Effects]
177[If it is possible to fit `size` bytes of storage aligned by `alignment` into
178the buffer pointed to by `ptr` with length `space`, the function updates `ptr`
179to point to the first possible address of such storage and decreases `space` by
180the number of bytes used for alignment. Otherwise, the function does nothing.]]
181[[Requires]
182[[itemized_list
183[`alignment` shall be a power of two]
184[`ptr` shall point to contiguous storage of at least `space` bytes]]]]
185[[Returns]
186[A null pointer if the requested aligned buffer would not fit into the
187available space, otherwise the adjusted value of `ptr`.]]
188[[Note]
189[The function updates its `ptr` and `space` arguments so that it can be called
190repeatedly with possibly different `alignment` and `size`arguments for the same
191buffer.]]]]]]
192
193[endsect]
194
195[section align_up]
196
197[variablelist
198[[`template<class T> constexpr T align_up(T value, std::size_t alignment)
199noexcept;`]
200[[variablelist
201[[Header][`#include <boost/align/align_up.hpp>`]]
202[[Constraints][`T` is not a pointer type]]
203[[Requires][`alignment` shall be a power of two]]
204[[Returns][A value at or after `value` that is a multiple of `alignment`.]]]]]]
205
206[endsect]
207
208[section align_down]
209
210[variablelist
211[[`template<class T> constexpr T align_down(T value, std::size_t alignment)
212noexcept;`]
213[[variablelist
214[[Header][`#include <boost/align/align_down.hpp>`]]
215[[Constraints][`T` is not a pointer type]]
216[[Requires][`alignment` shall be a power of two]]
217[[Returns]
218[A value at or before `value` that is a multiple of `alignment`.]]]]]]
219
220[endsect]
221
222[section aligned_alloc]
223
224[variablelist
225[[`void* aligned_alloc(std::size_t alignment, std::size_t size);`]
226[[variablelist
227[[Header][`#include <boost/align/aligned_alloc.hpp>`]]
228[[Effects]
229[Allocates space for an object whose alignment is specified by `alignment`,
230whose size is specified by `size`, and whose value is indeterminate.]]
231[[Requires][`alignment` shall be a power of two.]]
232[[Returns][A null pointer or a pointer to the allocated space.]]
233[[Note]
234[On certain platforms, the space allocated may be slightly larger than
235`size` bytes, to allow for alignment.]]]]]]
236
237[endsect]
238
239[section aligned_free]
240
241[variablelist
242[[`void aligned_free(void* ptr);`]
243[[variablelist
244[[Header][`#include <boost/align/aligned_alloc.hpp>`]]
245[[Effects]
246[Causes the space pointed to by `ptr` to be deallocated, that is, made
247available for further allocation. If `ptr` is a null pointer, no action occurs.
248Otherwise, if the argument does not match a pointer earlier returned by the
249`aligned_alloc()` function, or if the space has been deallocated by a call to
250`aligned_free()`, the behavior is undefined.]]
251[[Requires]
252[`ptr` is a null pointer or a pointer earlier returned by the `aligned_alloc()`
253function that has not been deallocated by a call to `aligned_free()`.]]
254[[Returns][The `aligned_free()` function returns no value.]]]]]]
255
256[endsect]
257
258[section is_aligned]
259
260[variablelist
261[[`bool is_aligned(const volatile void* ptr, std::size_t alignment) noexcept;`]
262[[variablelist
263[[Header][`#include <boost/align/is_aligned.hpp>`]]
264[[Requires][`alignment` shall be a power of two.]]
265[[Returns]
266[`true` if `ptr` is aligned on the boundary specified by `alignment`, otherwise
267`false`.]]]]]
268[[`template<class T> constexpr bool is_aligned(T value, std::size_t alignment)
269noexcept;`]
270[[variablelist
271[[Header][`#include <boost/align/is_aligned.hpp>`]]
272[[Constraints][`T` is not a pointer type]]
273[[Requires][`alignment` shall be a power of two.]]
274[[Returns]
275[`true` if the value of `value` is aligned on the boundary specified by
276`alignment`, otherwise `false`.]]]]]]
277
278[endsect]
279
280[endsect]
281
282[section Classes]
283
284[section aligned_allocator]
285
286[variablelist
287[[`template<class T, std::size_t Alignment = 1> class aligned_allocator;`]
288[[variablelist
289[[Header][`#include <boost/align/aligned_allocator.hpp>`]]
290[[Note]
291[Using the aligned allocator with a minimum Alignment value is generally only
292useful with containers that are not node-based such as `vector`. With
293node-based containers, such as `list`, the node object would have the minimum
294alignment instead of the value type object.]]]]]]
295
296[heading Member types]
297
298[ordered_list
299[`typedef T value_type;`]
300[`typedef T* pointer;`]
301[`typedef const T* const_pointer;`]
302[`typedef void* void_pointer;`]
303[`typedef const void* const_void_pointer;`]
304[`typedef std::add_lvalue_reference_t<T> reference;`]
305[`typedef std::add_lvalue_reference_t<const T> const_reference;`]
306[`typedef std::size_t size_type;`]
307[`typedef std::ptrdiff_t difference_type;`]
308[`typedef std::true_type propagate_on_container_move_assignment;`]
309[`typedef std::true_type is_always_equal;`]
310[`template<class U> struct rebind { typedef aligned_allocator<U, Alignment>
311other; };`]]
312
313[heading Constructors]
314
315[variablelist
316[[`aligned_allocator() = default;`]
317[[variablelist [[Effects][Constructs the allocator.]]]]]
318[[`template<class U> aligned_allocator(const aligned_allocator<U, Alignment>&)
319noexcept;`]
320[[variablelist [[Effects][Constructs the allocator.]]]]]]
321
322[heading Member functions]
323
324Except for the destructor, member functions of the aligned allocator shall not
325introduce data races as a result of concurrent calls to those member functions
326from different threads. Calls to these functions that allocate or deallocate a
327particular unit of storage shall occur in a single total order, and each such
328deallocation call shall happen before the next allocation (if any) in this
329order.
330
331[variablelist
332[[`pointer allocate(size_type size, const_void_pointer = 0);`]
333[[variablelist
334[[Returns]
335[A pointer to the initial element of an array of storage of size
336`n * sizeof(T)`, aligned on the maximum of the minimum alignment specified and
337the alignment of objects of type `T`.]]
338[[Remark]
339[The storage is obtained by calling `aligned_alloc(std::size_t,
340std::size_t)`.]]
341[[Throws][`std::bad_alloc` if the storage cannot be obtained.]]]]]
342[[`void deallocate(pointer ptr, size_type);`]
343[[variablelist
344[[Requires]
345[`ptr` shall be a pointer value obtained from `allocate()`.]]
346[[Effects][Deallocates the storage referenced by `ptr`.]]
347[[Remark][Uses `aligned_free(void*)`.]]]]]
348[[`size_type max_size() const noexcept;`]
349[[variablelist
350[[Returns]
351[The largest value `N` for which the call `allocate(N)` might succeed.]]]]]
352[[`template<class U, class... Args> void construct(U* ptr, Args&&... args);`]
353[[variablelist
354[[Effects][`::new((void*)ptr) U(std::forward<Args>(args)...)`.]]]]]
355[[`template<class U> void destroy(U* ptr);`]
356[[variablelist [[Effects][`ptr->~U()`.]]]]]]
357
358[heading Global operators]
359
360[variablelist
361[[`template<class T1, class T2, std::size_t Alignment> bool operator==(const
362aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&)
363noexcept;`]
364[[variablelist [[Returns][`true`]]]]]
365[[`template<class T1, class T2, std::size_t Alignment> bool operator!=(const
366aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&)
367noexcept;`]
368[[variablelist [[Returns][`false`]]]]]]
369
370[endsect]
371
372[section aligned_allocator_adaptor]
373
374[variablelist
375[[`template<class Allocator, std::size_t Alignment = 1> class
376aligned_allocator_adaptor;`]
377[[variablelist
378[[Header][`#include <boost/align/aligned_allocator_adaptor.hpp>`]]
379[[Note]
380[This adaptor can be used with a C++11 Allocator whose pointer type is a smart
381pointer but the adaptor can choose to expose only raw pointer types.]]]]]]
382
383[heading Member types]
384
385[ordered_list
386[`typedef typename Allocator::value_type value_type;`]
387[`typedef value_type* pointer;`]
388[`typedef const value_type* const_pointer;`]
389[`typedef void* void_pointer;`]
390[`typedef const void* const_void_pointer;`]
391[`typedef std::size_t size_type;`]
392[`typedef std::ptrdiff_t difference_type;`]
393[`template<class U> struct rebind { typedef aligned_allocator_adaptor<typename
394std::allocator_traits<Allocator>::template rebind_alloc<U>, Alignment>
395other; };`]]
396
397[heading Constructors]
398
399[variablelist
400[[`aligned_allocator_adaptor() = default;`]
401[[variablelist [[Effects][Value-initializes the `Allocator` base class.]]]]]
402[[`template<class A> aligned_allocator_adaptor(A&& alloc) noexcept;`]
403[[variablelist [[Requires][`Allocator` shall be constructible from `A`.]]
404[[Effects]
405[Initializes the `Allocator` base class with `std::forward<A>(alloc)`.]]]]]
406[[`template<class U> aligned_allocator_adaptor(const
407aligned_allocator_adaptor<U, Alignment>& other) noexcept;`]
408[[variablelist
409[[Requires][`Allocator` shall be constructible from `A`.]]
410[[Effects][Initializes the `Allocator` base class with `other.base()`.]]]]]]
411
412[heading Member functions]
413
414[variablelist
415[[`Allocator& base() noexcept;`]
416[[variablelist [[Returns][`static_cast<Allocator&>(*this)`]]]]]
417[[`const Allocator& base() const noexcept;`]
418[[variablelist [[Returns][`static_cast<const Allocator&>(*this)`]]]]]
419[[`pointer allocate(size_type size);`]
420[[variablelist
421[[Returns]
422[A pointer to the initial element of an array of storage of size
423`n * sizeof(value_type)`, aligned on the maximum of the minimum alignment
424specified and the alignment of objects of type `value_type`.]]
425[[Remark]
426[The storage is obtained by calling `A2::allocate()` on an object `a2`, where
427`a2` of type `A2` is a rebound copy of `base()` where its `value_type` is
428implementation defined.]]
429[[Throws]
430[Throws an exception thrown from `A2::allocate()` if the storage cannot be
431obtained.]]]]]
432[[`pointer allocate(size_type size, const_void_pointer hint);`]
433[[variablelist
434[[Requires]
435[`hint` is a value obtained by calling `allocate()` on any equivalent allocator
436object, or else a null pointer.]]
437[[Returns]
438[A pointer to the initial element of an array of storage of size
439`n * sizeof(value_type)`, aligned on the maximum of the minimum alignment
440specified and the alignment of objects of type `value_type`.]]
441[[Remark]
442[The storage is obtained by calling `A2::allocate()` on an object `a2`, where
443`a2` of type `A2` is a rebound copy of `base()` where its `value_type` is an
444implementation defined.]]
445[[Throws]
446[Throws an exception thrown from `A2::allocate()` if the storage cannot be
447obtained.]]]]]
448[[`void deallocate(pointer ptr, size_type size);`]
449[[variablelist
450[[Requires]
451[[itemized_list
452[`ptr` shall be a pointer value obtained from `allocate()`]
453[`size` shall equal the value passed as the first argument to the invocation of
454`allocate()` which returned `ptr`.]]]]
455[[Effects][Deallocates the storage referenced by `ptr`.]]
456[[Note]
457[Uses `A2::deallocate()` on an object `a2`, where `a2` of type `A2` is a
458rebound copy of `base()` where its `value_type` is implementation
459defined.]]]]]]
460
461[heading Global operators]
462
463[variablelist
464[[`template<class A1, class A2, std::size_t Alignment> bool operator==(const
465aligned_allocator_adaptor<A1, Alignment>& a1, const
466aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`]
467[[variablelist [[Returns][`a1.base() == a2.base()`]]]]]
468[[`template<class A1, class A2, std::size_t Alignment> bool operator!=(const
469aligned_allocator_adaptor<A1, Alignment>& a1, const
470aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`]
471[[variablelist [[Returns][`!(a1 == a2)`]]]]]]
472
473[endsect]
474
475[section aligned_delete]
476
477[variablelist
478[[`class aligned_delete;`]
479[[variablelist [[Header][`#include <boost/align/aligned_delete.hpp>`]]]]]]
480
481[heading Member operators]
482
483[variablelist
484[[`template<class T> void operator()(T* ptr) noexcept(noexcept(ptr->~T()));`]
485[[variablelist
486[[Effects]
487[Calls `~T()` on `ptr` to destroy the object and then calls `aligned_free()` on
488`ptr` to free the allocated memory.]]
489[[Note][If `T` is an incomplete type, the program is ill-formed.]]]]]]
490
491[endsect]
492
493[endsect]
494
495[section Traits]
496
497[section alignment_of]
498
499[variablelist
500[[`template<class T> struct alignment_of;`]
501[[variablelist
502[[Header][`#include <boost/align/alignment_of.hpp>`]]
503[[Value]
504[The alignment requirement of the type `T` as an integral constant of type
505`std::size_t`. When `T` is a reference array type, the value shall be the
506alignment of the referenced type. When `T` is an array type, the value shall be
507the alignment of the element type.]]
508[[Requires]
509[`T` shall be a complete object type, or an array thereof, or a reference to
510one of those types.]]]]]]
511
512[endsect]
513
514[endsect]
515
516[section Macros]
517
518[section BOOST_ALIGN_ASSUME_ALIGNED]
519
520[variablelist
521[[`BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)`]
522[[variablelist
523[[Header][`#include <boost/align/assume_aligned.hpp>`]]
524[[Requires]
525[[itemized_list [`alignment` shall be a power of two]
526[`ptr` shall be mutable]]]]
527[[Effects]
528[`ptr` may be modified in an implementation specific way to inform the compiler
529of its alignment.]]]]]]
530
531[endsect]
532
533[endsect]
534
535[endsect]
536
537[section Vocabulary]
538
539[heading \[basic.align\]]
540
541Object types have /alignment requirements/ which place restrictions on the
542addresses at which an object of that type may be allocated. An /alignment/ is
543an implementation-defined integer value representing the number of bytes
544between successive addresses at which a given object can be allocated. An
545object type imposes an alignment requirement on every object of that type;
546stricter alignment can be requested using the alignment specifier.
547
548A /fundamental alignment/ is represented by an alignment less than or equal to
549the greatest alignment supported by the implementation in all contexts, which
550is equal to `alignof(std::max_align_t)`. The alignment required for a type
551might be different when it is used as the type of a complete object and when
552it is used as the type of a subobject.
553\[['Example:]
554[ordered_list
555[`struct B { long double d; };`]
556[`struct D : virtual B { char c; };`]]
557When `D` is the type of a complete object, it will have a subobject of type
558`B`, so it must be aligned appropriately for a `long double`. If `D` appears
559as a subobject of another object that also has `B` as a virtual base class,
560the `B` subobject might be part of a different subobject, reducing the
561alignment requirements on the `D` subobject. \u2014['end example]\] The result
562of the `alignof` operator reflects the alignment requirement of the type in
563the complete-object case.
564
565An /extended alignment/ is represented by an alignment greater than
566`alignof(std::max_align_t)`. It is implementation-defined whether any extended
567alignments are supported and the contexts in which they are supported. A type
568having an extended alignment requirement is an /over-aligned type/. \[['Note:]
569Every over-aligned type is or contains a class type to which extended
570alignment applies (possibly through a non-static data member). \u2014['end
571note]\]
572
573Alignments are represented as values of the type `std::size_t`. Valid
574alignments include only those values returned by an `alignof` expression for
575the fundamental types plus an additional implementation-defined set of values,
576which may be empty. Every alignment value shall be a non-negative integral
577power of two.
578
579Alignments have an order from /weaker/ to /stronger/ or /stricter/ alignments.
580Stricter alignments have larger alignment values. An address that satisfies an
581alignment requirement also satisfies any weaker valid alignment requirement.
582
583The alignment requirement of a complete type can be queried using an `alignof`
584expression. Furthermore, the types `char`, `signed char`, and `unsigned char`
585shall have the weakest alignment requirement. \[['Note:] This enables the
586character types to be used as the underlying type for an aligned memory area.
587\u2014['end note]\]
588
589Comparing alignments is meaningful and provides the obvious results:
590
591* Two alignments are equal when their numeric values are equal.
592* Two alignments are different when their numeric values are not equal.
593* When an alignment is larger than another it represents a stricter
594  alignment.
595
596\[['Note:] The runtime pointer alignment function can be used to obtain an
597aligned pointer within a buffer; the aligned-storage templates in the library
598can be used to obtain aligned storage. \u2014['end note]\]
599
600If a request for a specific extended alignment in a specific context is not
601supported by an implementation, the program is ill-formed. Additionally, a
602request for runtime allocation of dynamic storage for which the requested
603alignment cannot be honored shall be treated as an allocation failure.
604
605[endsect]
606
607[section Compatibility]
608
609This library has been tested with the following C++ implementations:
610
611[variablelist
612[[Compilers][gcc, clang, msvc, intel]]
613[[Libraries][libstdc++, libc++, dinkumware]]
614[[Systems][linux, windows, osx]]
615[[Platforms][x64, x86, arm]]
616[[Standards][c++98, c++03, c++11, c++14, c++17]]]
617
618[endsect]
619
620[section Acknowledgments]
621
622Thank you to everyone who reviewed the design, code, examples, tests, or
623documentation, including:
624
625* Peter Dimov
626* Andrey Semashev
627* Bjorn Reese
628* Steven Watanabe
629* Antony Polukhin
630* Lars Viklund
631* Michael Spencer
632* Paul A. Bristow
633
634Thank you to Ahmed Charles for serving as the review manager for the formal
635review of the library.
636
637[endsect]
638
639[section History]
640
641[variablelist
642[[Boost 1.61]
643[Functions for aligning up, down, and testing alignment of integral values.]]
644[[Boost 1.59]
645[Joel Falcou and Charly Chevalier contributed the alignment hint macro.]]
646[[Boost 1.56]
647[Glen Fernandes implemented and contributed the Align library to Boost.]]]
648
649[endsect]
650