| [/ |
| 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<T>`][Replaces `std::allocator<T>`]] |
| [[`aligned_allocator_adaptor<Allocator>`][Replaces use of Allocator]] |
| [[`aligned_delete`][Replaces `std::default_delete<T>`]]] |
| |
| [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<int128_t, |
| boost::alignment::aligned_allocator<int128_t> > vector;`]] |
| |
| This template allows specifying minimum alignment for all dynamic allocations: |
| |
| [ordered_list |
| [`std::vector<double, |
| boost::alignment::aligned_allocator<double, 64> > 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<First> second(first);`]] |
| |
| This template allows specifying minimum alignment for all dynamic |
| allocations: |
| |
| [ordered_list |
| [`boost::alignment::aligned_allocator_adaptor<First, 64> 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<double, boost::alignment::aligned_delete> 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<int128_t>::value`]] |
| |
| If your compiler supports C++14 variable templates, you can also use: |
| |
| [ordered_list [`boost::alignment::alignment_of_v<int128_t>`]] |
| |
| [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 <boost/align/align.hpp>`]] |
| [[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<class T> constexpr T align_up(T value, std::size_t alignment) |
| noexcept;`] |
| [[variablelist |
| [[Header][`#include <boost/align/align_up.hpp>`]] |
| [[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<class T> constexpr T align_down(T value, std::size_t alignment) |
| noexcept;`] |
| [[variablelist |
| [[Header][`#include <boost/align/align_down.hpp>`]] |
| [[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 <boost/align/aligned_alloc.hpp>`]] |
| [[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 <boost/align/aligned_alloc.hpp>`]] |
| [[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 <boost/align/is_aligned.hpp>`]] |
| [[Requires][`alignment` shall be a power of two.]] |
| [[Returns] |
| [`true` if `ptr` is aligned on the boundary specified by `alignment`, otherwise |
| `false`.]]]]] |
| [[`template<class T> constexpr bool is_aligned(T value, std::size_t alignment) |
| noexcept;`] |
| [[variablelist |
| [[Header][`#include <boost/align/is_aligned.hpp>`]] |
| [[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 T, std::size_t Alignment = 1> class aligned_allocator;`] |
| [[variablelist |
| [[Header][`#include <boost/align/aligned_allocator.hpp>`]] |
| [[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<T> reference;`] |
| [`typedef std::add_lvalue_reference_t<const 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<class U> struct rebind { typedef aligned_allocator<U, Alignment> |
| other; };`]] |
| |
| [heading Constructors] |
| |
| [variablelist |
| [[`aligned_allocator() = default;`] |
| [[variablelist [[Effects][Constructs the allocator.]]]]] |
| [[`template<class U> aligned_allocator(const aligned_allocator<U, Alignment>&) |
| 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<class U, class... Args> void construct(U* ptr, Args&&... args);`] |
| [[variablelist |
| [[Effects][`::new((void*)ptr) U(std::forward<Args>(args)...)`.]]]]] |
| [[`template<class U> void destroy(U* ptr);`] |
| [[variablelist [[Effects][`ptr->~U()`.]]]]]] |
| |
| [heading Global operators] |
| |
| [variablelist |
| [[`template<class T1, class T2, std::size_t Alignment> bool operator==(const |
| aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&) |
| noexcept;`] |
| [[variablelist [[Returns][`true`]]]]] |
| [[`template<class T1, class T2, std::size_t Alignment> bool operator!=(const |
| aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&) |
| noexcept;`] |
| [[variablelist [[Returns][`false`]]]]]] |
| |
| [endsect] |
| |
| [section aligned_allocator_adaptor] |
| |
| [variablelist |
| [[`template<class Allocator, std::size_t Alignment = 1> class |
| aligned_allocator_adaptor;`] |
| [[variablelist |
| [[Header][`#include <boost/align/aligned_allocator_adaptor.hpp>`]] |
| [[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<class U> struct rebind { typedef aligned_allocator_adaptor<typename |
| std::allocator_traits<Allocator>::template rebind_alloc<U>, Alignment> |
| other; };`]] |
| |
| [heading Constructors] |
| |
| [variablelist |
| [[`aligned_allocator_adaptor() = default;`] |
| [[variablelist [[Effects][Value-initializes the `Allocator` base class.]]]]] |
| [[`template<class A> aligned_allocator_adaptor(A&& alloc) noexcept;`] |
| [[variablelist [[Requires][`Allocator` shall be constructible from `A`.]] |
| [[Effects] |
| [Initializes the `Allocator` base class with `std::forward<A>(alloc)`.]]]]] |
| [[`template<class U> aligned_allocator_adaptor(const |
| aligned_allocator_adaptor<U, Alignment>& 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<Allocator&>(*this)`]]]]] |
| [[`const Allocator& base() const noexcept;`] |
| [[variablelist [[Returns][`static_cast<const Allocator&>(*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<class A1, class A2, std::size_t Alignment> bool operator==(const |
| aligned_allocator_adaptor<A1, Alignment>& a1, const |
| aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`] |
| [[variablelist [[Returns][`a1.base() == a2.base()`]]]]] |
| [[`template<class A1, class A2, std::size_t Alignment> bool operator!=(const |
| aligned_allocator_adaptor<A1, Alignment>& a1, const |
| aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`] |
| [[variablelist [[Returns][`!(a1 == a2)`]]]]]] |
| |
| [endsect] |
| |
| [section aligned_delete] |
| |
| [variablelist |
| [[`class aligned_delete;`] |
| [[variablelist [[Header][`#include <boost/align/aligned_delete.hpp>`]]]]]] |
| |
| [heading Member operators] |
| |
| [variablelist |
| [[`template<class T> 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<class T> struct alignment_of;`] |
| [[variablelist |
| [[Header][`#include <boost/align/alignment_of.hpp>`]] |
| [[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 <boost/align/assume_aligned.hpp>`]] |
| [[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] |