123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- [/
- 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]
|