[/ Copyright 2014-2017 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) ] [library Boost.Align [quickbook 1.6] [id align] [copyright 2014-2017 Glen Joseph Fernandes] [authors [Fernandes, Glen]] [dirname align] [license Distributed under the Boost Software License, Version 1.0.]] [section Introduction] The Boost Align C++ library provides functions, classes, templates, traits, and macros, for the control, inspection, and diagnostic of memory alignment. [endsect] [section Rationale] [heading Dynamic allocation] C++11 added the ability to specify increased alignment (over-alignment) for class types. Unfortunately, `::operator new` allocation functions, `new` expressions and the Default Allocator, `std::allocator`, do not support dynamic memory allocation of over-aligned data. This library provides allocation functions and allocators that respect the alignment requirements of a type and so are suitable for allocating memory for over-aligned types. [variablelist [[`aligned_alloc(alignment, size)`] [Replaces `::operator new(size, std::nothrow)`]] [[`aligned_free(pointer)`] [Replaces `::operator delete(pointer, std::nothrow)`]] [[`aligned_allocator`][Replaces `std::allocator`]] [[`aligned_allocator_adaptor`][Replaces use of Allocator]] [[`aligned_delete`][Replaces `std::default_delete`]]] [heading Pointer alignment] C++11 provided `std::align` in the standard library to align a pointer value. Unfortunately some C++ standard library implementations do not support it yet (libstdc++ as far as gcc 4.8.0) and other standard library implementations implement it incorrectly (dinkumware in msvc11.0). This library provides it for those implementations and also for C++03 compilers where it is equally useful. [heading Querying alignment] C++11 provided the `std::alignment_of` trait in the standard library to query the alignment requirement of a type. Unfortunately some C++ standard library vendors do not implement it in an entirely standard conforming manner, such as for array types (libc++ as far as clang 3.4). Other vendor implementations report incorrect values for certain types, such as pointer to members (msvc 14.0). This library provides it for those implementations and also for C++03 compilers where it is equally useful. [heading Hinting alignment] Allocating aligned memory is sometimes not enough to ensure that optimal code is generated. Developers use specific compiler intrinsics to notify the compiler of a given alignment property of a memory block. This library provides a macro, `BOOST_ALIGN_ASSUME_ALIGNED`, to abstract that functionality for compilers with the appropriate intrinsics. [heading Checking alignment] This library provides a function, `is_aligned` to test the alignment of a pointer value. It is generally useful in assertions to validate that memory is correctly aligned. [endsect] [section Examples] [heading Aligned allocation] To dynamically allocate storage with desired alignment, you can use the `aligned_alloc` function: [ordered_list [`void* storage = boost::alignment::aligned_alloc(alignment, size);`]] To deallocate storage allocated with the `aligned_alloc` function, use the `aligned_free` function: [ordered_list [`boost::alignment::aligned_free(storage);`]] [heading Aligned allocator] For C++ allocator aware code, you can use the `aligned_allocator` class template for an allocator that respects over-alignment: [ordered_list [`std::vector > vector;`]] This template allows specifying minimum alignment for all dynamic allocations: [ordered_list [`std::vector > vector;`]] [heading Aligned allocator adaptor] To turn an allocator into an allocator that respects over-alignment, you can use the `aligned_allocator_adaptor` class template: [ordered_list [`boost::alignment::aligned_allocator_adaptor second(first);`]] This template allows specifying minimum alignment for all dynamic allocations: [ordered_list [`boost::alignment::aligned_allocator_adaptor second(first);`]] [heading Aligned deleter] For a deleter that can be paired with `aligned_alloc`, you can use the `aligned_delete` class: [ordered_list [`std::unique_ptr pointer;`]] [heading Pointer alignment] To advance a pointer to the next address with the desired alignment: [ordered_list [`void* pointer = storage;`] [`std::size_t space = size;`] [`void* result = boost::alignment::align(64, sizeof(double), pointer, space);`]] [heading Querying alignment] To obtain the alignment of a given type at compie time, you can use: [ordered_list [`boost::alignment::alignment_of::value`]] If your compiler supports C++14 variable templates, you can also use: [ordered_list [`boost::alignment::alignment_of_v`]] [heading Hinting alignment] To inform the compiler about the alignment of a pointer, you can use: [ordered_list [`BOOST_ALIGN_ASSUME_ALIGNED(pointer, 64)`]] [heading Checking alignment] To check alignment of a pointer you can use the `is_aligned` function: [ordered_list [`assert(boost::alignment::is_aligned(pointer, 64));`]] [endsect] [section Reference] [section Functions] [section align] [variablelist [[`void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space);`] [[variablelist [[Header][`#include `]] [[Effects] [If it is possible to fit `size` bytes of storage aligned by `alignment` into the buffer pointed to by `ptr` with length `space`, the function updates `ptr` to point to the first possible address of such storage and decreases `space` by the number of bytes used for alignment. Otherwise, the function does nothing.]] [[Requires] [[itemized_list [`alignment` shall be a power of two] [`ptr` shall point to contiguous storage of at least `space` bytes]]]] [[Returns] [A null pointer if the requested aligned buffer would not fit into the available space, otherwise the adjusted value of `ptr`.]] [[Note] [The function updates its `ptr` and `space` arguments so that it can be called repeatedly with possibly different `alignment` and `size`arguments for the same buffer.]]]]]] [endsect] [section align_up] [variablelist [[`template constexpr T align_up(T value, std::size_t alignment) noexcept;`] [[variablelist [[Header][`#include `]] [[Constraints][`T` is not a pointer type]] [[Requires][`alignment` shall be a power of two]] [[Returns][A value at or after `value` that is a multiple of `alignment`.]]]]]] [endsect] [section align_down] [variablelist [[`template constexpr T align_down(T value, std::size_t alignment) noexcept;`] [[variablelist [[Header][`#include `]] [[Constraints][`T` is not a pointer type]] [[Requires][`alignment` shall be a power of two]] [[Returns] [A value at or before `value` that is a multiple of `alignment`.]]]]]] [endsect] [section aligned_alloc] [variablelist [[`void* aligned_alloc(std::size_t alignment, std::size_t size);`] [[variablelist [[Header][`#include `]] [[Effects] [Allocates space for an object whose alignment is specified by `alignment`, whose size is specified by `size`, and whose value is indeterminate.]] [[Requires][`alignment` shall be a power of two.]] [[Returns][A null pointer or a pointer to the allocated space.]] [[Note] [On certain platforms, the space allocated may be slightly larger than `size` bytes, to allow for alignment.]]]]]] [endsect] [section aligned_free] [variablelist [[`void aligned_free(void* ptr);`] [[variablelist [[Header][`#include `]] [[Effects] [Causes the space pointed to by `ptr` to be deallocated, that is, made available for further allocation. If `ptr` is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the `aligned_alloc()` function, or if the space has been deallocated by a call to `aligned_free()`, the behavior is undefined.]] [[Requires] [`ptr` is a null pointer or a pointer earlier returned by the `aligned_alloc()` function that has not been deallocated by a call to `aligned_free()`.]] [[Returns][The `aligned_free()` function returns no value.]]]]]] [endsect] [section is_aligned] [variablelist [[`bool is_aligned(const volatile void* ptr, std::size_t alignment) noexcept;`] [[variablelist [[Header][`#include `]] [[Requires][`alignment` shall be a power of two.]] [[Returns] [`true` if `ptr` is aligned on the boundary specified by `alignment`, otherwise `false`.]]]]] [[`template constexpr bool is_aligned(T value, std::size_t alignment) noexcept;`] [[variablelist [[Header][`#include `]] [[Constraints][`T` is not a pointer type]] [[Requires][`alignment` shall be a power of two.]] [[Returns] [`true` if the value of `value` is aligned on the boundary specified by `alignment`, otherwise `false`.]]]]]] [endsect] [endsect] [section Classes] [section aligned_allocator] [variablelist [[`template class aligned_allocator;`] [[variablelist [[Header][`#include `]] [[Note] [Using the aligned allocator with a minimum Alignment value is generally only useful with containers that are not node-based such as `vector`. With node-based containers, such as `list`, the node object would have the minimum alignment instead of the value type object.]]]]]] [heading Member types] [ordered_list [`typedef T value_type;`] [`typedef T* pointer;`] [`typedef const T* const_pointer;`] [`typedef void* void_pointer;`] [`typedef const void* const_void_pointer;`] [`typedef std::add_lvalue_reference_t reference;`] [`typedef std::add_lvalue_reference_t const_reference;`] [`typedef std::size_t size_type;`] [`typedef std::ptrdiff_t difference_type;`] [`typedef std::true_type propagate_on_container_move_assignment;`] [`typedef std::true_type is_always_equal;`] [`template struct rebind { typedef aligned_allocator other; };`]] [heading Constructors] [variablelist [[`aligned_allocator() = default;`] [[variablelist [[Effects][Constructs the allocator.]]]]] [[`template aligned_allocator(const aligned_allocator&) noexcept;`] [[variablelist [[Effects][Constructs the allocator.]]]]]] [heading Member functions] Except for the destructor, member functions of the aligned allocator shall not introduce data races as a result of concurrent calls to those member functions from different threads. Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order. [variablelist [[`pointer allocate(size_type size, const_void_pointer = 0);`] [[variablelist [[Returns] [A pointer to the initial element of an array of storage of size `n * sizeof(T)`, aligned on the maximum of the minimum alignment specified and the alignment of objects of type `T`.]] [[Remark] [The storage is obtained by calling `aligned_alloc(std::size_t, std::size_t)`.]] [[Throws][`std::bad_alloc` if the storage cannot be obtained.]]]]] [[`void deallocate(pointer ptr, size_type);`] [[variablelist [[Requires] [`ptr` shall be a pointer value obtained from `allocate()`.]] [[Effects][Deallocates the storage referenced by `ptr`.]] [[Remark][Uses `aligned_free(void*)`.]]]]] [[`size_type max_size() const noexcept;`] [[variablelist [[Returns] [The largest value `N` for which the call `allocate(N)` might succeed.]]]]] [[`template void construct(U* ptr, Args&&... args);`] [[variablelist [[Effects][`::new((void*)ptr) U(std::forward(args)...)`.]]]]] [[`template void destroy(U* ptr);`] [[variablelist [[Effects][`ptr->~U()`.]]]]]] [heading Global operators] [variablelist [[`template bool operator==(const aligned_allocator&, const aligned_allocator&) noexcept;`] [[variablelist [[Returns][`true`]]]]] [[`template bool operator!=(const aligned_allocator&, const aligned_allocator&) noexcept;`] [[variablelist [[Returns][`false`]]]]]] [endsect] [section aligned_allocator_adaptor] [variablelist [[`template class aligned_allocator_adaptor;`] [[variablelist [[Header][`#include `]] [[Note] [This adaptor can be used with a C++11 Allocator whose pointer type is a smart pointer but the adaptor can choose to expose only raw pointer types.]]]]]] [heading Member types] [ordered_list [`typedef typename Allocator::value_type value_type;`] [`typedef value_type* pointer;`] [`typedef const value_type* const_pointer;`] [`typedef void* void_pointer;`] [`typedef const void* const_void_pointer;`] [`typedef std::size_t size_type;`] [`typedef std::ptrdiff_t difference_type;`] [`template struct rebind { typedef aligned_allocator_adaptor::template rebind_alloc, Alignment> other; };`]] [heading Constructors] [variablelist [[`aligned_allocator_adaptor() = default;`] [[variablelist [[Effects][Value-initializes the `Allocator` base class.]]]]] [[`template aligned_allocator_adaptor(A&& alloc) noexcept;`] [[variablelist [[Requires][`Allocator` shall be constructible from `A`.]] [[Effects] [Initializes the `Allocator` base class with `std::forward(alloc)`.]]]]] [[`template aligned_allocator_adaptor(const aligned_allocator_adaptor& other) noexcept;`] [[variablelist [[Requires][`Allocator` shall be constructible from `A`.]] [[Effects][Initializes the `Allocator` base class with `other.base()`.]]]]]] [heading Member functions] [variablelist [[`Allocator& base() noexcept;`] [[variablelist [[Returns][`static_cast(*this)`]]]]] [[`const Allocator& base() const noexcept;`] [[variablelist [[Returns][`static_cast(*this)`]]]]] [[`pointer allocate(size_type size);`] [[variablelist [[Returns] [A pointer to the initial element of an array of storage of size `n * sizeof(value_type)`, aligned on the maximum of the minimum alignment specified and the alignment of objects of type `value_type`.]] [[Remark] [The storage is obtained by calling `A2::allocate()` on an object `a2`, where `a2` of type `A2` is a rebound copy of `base()` where its `value_type` is implementation defined.]] [[Throws] [Throws an exception thrown from `A2::allocate()` if the storage cannot be obtained.]]]]] [[`pointer allocate(size_type size, const_void_pointer hint);`] [[variablelist [[Requires] [`hint` is a value obtained by calling `allocate()` on any equivalent allocator object, or else a null pointer.]] [[Returns] [A pointer to the initial element of an array of storage of size `n * sizeof(value_type)`, aligned on the maximum of the minimum alignment specified and the alignment of objects of type `value_type`.]] [[Remark] [The storage is obtained by calling `A2::allocate()` on an object `a2`, where `a2` of type `A2` is a rebound copy of `base()` where its `value_type` is an implementation defined.]] [[Throws] [Throws an exception thrown from `A2::allocate()` if the storage cannot be obtained.]]]]] [[`void deallocate(pointer ptr, size_type size);`] [[variablelist [[Requires] [[itemized_list [`ptr` shall be a pointer value obtained from `allocate()`] [`size` shall equal the value passed as the first argument to the invocation of `allocate()` which returned `ptr`.]]]] [[Effects][Deallocates the storage referenced by `ptr`.]] [[Note] [Uses `A2::deallocate()` on an object `a2`, where `a2` of type `A2` is a rebound copy of `base()` where its `value_type` is implementation defined.]]]]]] [heading Global operators] [variablelist [[`template bool operator==(const aligned_allocator_adaptor& a1, const aligned_allocator_adaptor& a2) noexcept;`] [[variablelist [[Returns][`a1.base() == a2.base()`]]]]] [[`template bool operator!=(const aligned_allocator_adaptor& a1, const aligned_allocator_adaptor& a2) noexcept;`] [[variablelist [[Returns][`!(a1 == a2)`]]]]]] [endsect] [section aligned_delete] [variablelist [[`class aligned_delete;`] [[variablelist [[Header][`#include `]]]]]] [heading Member operators] [variablelist [[`template void operator()(T* ptr) noexcept(noexcept(ptr->~T()));`] [[variablelist [[Effects] [Calls `~T()` on `ptr` to destroy the object and then calls `aligned_free()` on `ptr` to free the allocated memory.]] [[Note][If `T` is an incomplete type, the program is ill-formed.]]]]]] [endsect] [endsect] [section Traits] [section alignment_of] [variablelist [[`template struct alignment_of;`] [[variablelist [[Header][`#include `]] [[Value] [The alignment requirement of the type `T` as an integral constant of type `std::size_t`. When `T` is a reference array type, the value shall be the alignment of the referenced type. When `T` is an array type, the value shall be the alignment of the element type.]] [[Requires] [`T` shall be a complete object type, or an array thereof, or a reference to one of those types.]]]]]] [endsect] [endsect] [section Macros] [section BOOST_ALIGN_ASSUME_ALIGNED] [variablelist [[`BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)`] [[variablelist [[Header][`#include `]] [[Requires] [[itemized_list [`alignment` shall be a power of two] [`ptr` shall be mutable]]]] [[Effects] [`ptr` may be modified in an implementation specific way to inform the compiler of its alignment.]]]]]] [endsect] [endsect] [endsect] [section Vocabulary] [heading \[basic.align\]] Object types have /alignment requirements/ which place restrictions on the addresses at which an object of that type may be allocated. An /alignment/ is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier. A /fundamental alignment/ is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to `alignof(std::max_align_t)`. The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. \[['Example:] [ordered_list [`struct B { long double d; };`] [`struct D : virtual B { char c; };`]] When `D` is the type of a complete object, it will have a subobject of type `B`, so it must be aligned appropriately for a `long double`. If `D` appears as a subobject of another object that also has `B` as a virtual base class, the `B` subobject might be part of a different subobject, reducing the alignment requirements on the `D` subobject. \u2014['end example]\] The result of the `alignof` operator reflects the alignment requirement of the type in the complete-object case. An /extended alignment/ is represented by an alignment greater than `alignof(std::max_align_t)`. It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an /over-aligned type/. \[['Note:] Every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member). \u2014['end note]\] Alignments are represented as values of the type `std::size_t`. Valid alignments include only those values returned by an `alignof` expression for the fundamental types plus an additional implementation-defined set of values, which may be empty. Every alignment value shall be a non-negative integral power of two. Alignments have an order from /weaker/ to /stronger/ or /stricter/ alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement. The alignment requirement of a complete type can be queried using an `alignof` expression. Furthermore, the types `char`, `signed char`, and `unsigned char` shall have the weakest alignment requirement. \[['Note:] This enables the character types to be used as the underlying type for an aligned memory area. \u2014['end note]\] Comparing alignments is meaningful and provides the obvious results: * Two alignments are equal when their numeric values are equal. * Two alignments are different when their numeric values are not equal. * When an alignment is larger than another it represents a stricter alignment. \[['Note:] The runtime pointer alignment function can be used to obtain an aligned pointer within a buffer; the aligned-storage templates in the library can be used to obtain aligned storage. \u2014['end note]\] If a request for a specific extended alignment in a specific context is not supported by an implementation, the program is ill-formed. Additionally, a request for runtime allocation of dynamic storage for which the requested alignment cannot be honored shall be treated as an allocation failure. [endsect] [section Compatibility] This library has been tested with the following C++ implementations: [variablelist [[Compilers][gcc, clang, msvc, intel]] [[Libraries][libstdc++, libc++, dinkumware]] [[Systems][linux, windows, osx]] [[Platforms][x64, x86, arm]] [[Standards][c++98, c++03, c++11, c++14, c++17]]] [endsect] [section Acknowledgments] Thank you to everyone who reviewed the design, code, examples, tests, or documentation, including: * Peter Dimov * Andrey Semashev * Bjorn Reese * Steven Watanabe * Antony Polukhin * Lars Viklund * Michael Spencer * Paul A. Bristow Thank you to Ahmed Charles for serving as the review manager for the formal review of the library. [endsect] [section History] [variablelist [[Boost 1.61] [Functions for aligning up, down, and testing alignment of integral values.]] [[Boost 1.59] [Joel Falcou and Charly Chevalier contributed the alignment hint macro.]] [[Boost 1.56] [Glen Fernandes implemented and contributed the Align library to Boost.]]] [endsect]