blob: aff16a29aeb1b572b3aef5d456ac6ea3414cf13f [file] [log] [blame]
[/
(c) 2014 Glen Joseph Fernandes
glenjofe at gmail dot com
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
]
[library Boost.Align
[quickbook 1.6]
[id align]
[copyright 2014 Glen Fernandes]
[authors [Fernandes, Glen]]
[dirname align]
[license Distributed under the
[@http://boost.org/LICENSE_1_0.txt
Boost Software License, Version 1.0].
]
]
[section Introduction]
This library provides an alignment function, aligned
allocation and deallocation functions, an aligned
allocator, an aligned allocator adaptor, an aligned
deleter, a type trait to query alignment requirements,
and a function to verify pointer value alignment.
[table The Boost.Align Library
[ [Component] [Description] ]
[ [`align`]
[Pointer alignment function]
]
[ [`aligned_alloc`, `aligned_free`]
[Aligned allocation and deallocation functions]
]
[ [`aligned_allocator`]
[Alignment aware allocator]
]
[ [`aligned_allocator_adaptor`]
[Alignment aware allocator adaptor]
]
[ [`aligned_delete`]
[Deleter for constructed objects allocated with
the alignment function]
]
[ [`alignment_of`]
[Type trait to query alignment requirement of a
type at compile time]
]
[ [`is_aligned`]
[Pointer alignment verification function]
]
]
[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, allocators,
allocator adaptors, and deleters, that are alignment
aware.
[table Boost.Align solutions
[ [Problem] [Solution] ]
[ [`::operator new(std::size_t,
const std::no_throw_t&)`]
[`aligned_alloc(std::size_t, std::size_t)`]
]
[ [`::operator delete(void*)`]
[`aligned_free(void*)`]
]
[ [`std::allocator<T>`]
[`aligned_allocator<T>`]
]
[ [`Allocator`]
[`aligned_allocator_adaptor<Allocator>`]
]
[ [`std::default_delete<T>`]
[`aligned_delete`]
]
]
[heading Alignment functions]
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
msvc 11.0). This library provides it for those
implementations and also for C++03 compilers where it is
equally useful.
[heading Alignment traits]
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). This library provides it for those implementations
and also for C++03 compilers where it is equally useful.
[heading Alignment testing]
This library provides a function to test the alignment
of a pointer value. It is generally useful in assertions
to validate that memory is correctly aligned.
[endsect]
[section Tutorial]
[section align]
The alignment function can be used to find the first
address of a given alignment value within a given buffer
of a given size. It adjusts the pointer provided, returns
that value, and decreases space by the amount advanced,
if the alignment succeeds, provided sufficient space in
the buffer. Otherwise it yields a null pointer to
indicate failure due to insufficient space.
``
#include <boost/align/align.hpp>
template<class T>
inline T* make(void* ptr, std::size_t space)
{
void* p = boost::alignment::
align(alignof(T), sizeof(T), ptr, space);
if (p) {
return ::new(p) T();
} else {
return nullptr;
}
}
struct alignas(16) type {
float data[4];
};
int main()
{
char c[48];
type* p = make<type>(c, sizeof c);
if (p) {
p->~type();
}
}
``
[endsect]
[section:aligned_alloc aligned_alloc and aligned_free]
Consider these functions alignment enabled versions of
`std::malloc(std::size_t)` and `std::free(void*)` or
`::operator new(std::size_t, const std::no_throw_t&)` and
`::operator delete(void*)`. The aligned allocation
function allocates space with the specified size and
alignment. The aligned deallocation function can then
deallocate this space.
``
#include <boost/align/aligned_alloc.hpp>
void use(void* ptr, std::size_t size)
{
(void)ptr;
(void)size;
}
int main()
{
void* p = boost::alignment::aligned_alloc(16, 100);
if (p) {
use(p, 100);
boost::alignment::aligned_free(p);
}
}
``
[endsect]
[section aligned_allocator]
Consider this class template a superior version of
the default allocator, `std::allocator`, because it
can be used with types that are over-aligned.
``
#include <boost/align/aligned_allocator.hpp>
#include <vector>
struct alignas(16) type {
float data[4];
};
void use(type* ptr, std::size_t size)
{
(void)ptr;
(void)size;
}
int main()
{
std::vector<type, boost::alignment::
aligned_allocator<type> > v(100);
use(&v[0], v.size());
}
``
The optional template parameter of this class allows
specifying a minimum alignment to use for allocations.
The default minimum alignment is 1.
``
#include <boost/align/aligned_allocator.hpp>
#include <vector>
void use(char* ptr, std::size_t size)
{
(void)ptr;
(void)size;
}
int main()
{
std::vector<char, boost::alignment::
aligned_allocator<char, 16> > v(100);
use(&v[0], v.size());
}
``
[endsect]
[section aligned_allocator_adaptor]
This class template can turn any existing allocator
type, C++11 or C++03, stateful or stateless, into one
that supports types which are over-aligned.
``
#include <boost/align/aligned_allocator_adaptor.hpp>
#include <vector>
template<class T, class Allocator>
class utility {
public:
utility(std::size_t size)
: v(size) {
}
private:
std::vector<T, boost::alignment::
aligned_allocator_adaptor<Allocator> > v;
};
struct alignas(16) type {
float data[4];
};
int main()
{
utility<type, std::allocator<type> > u(100);
(void)u;
}
``
The optional template parameter of this class allows
specifying a minimum alignment to use for allocations.
The default minimum alignment is 1.
``
#include <boost/align/aligned_allocator_adaptor.hpp>
#include <vector>
template<class T, class Allocator, std::size_t Alignment>
class utility {
public:
utility(std::size_t size)
: v(size) {
}
private:
std::vector<T, boost::alignment::
aligned_allocator_adaptor<Allocator, Alignment> > v;
};
int main()
{
utility<char, std::allocator<char>, 16> u(100);
(void)u;
}
``
[endsect]
[section aligned_delete]
Consider this class an alignment aware version of the
`std::default_delete` deleter class template. It is a
deleter that destroys the object and then deallocates
space using our aligned deallocation function. It should
be used with constructed objects that were allocated
with our aligned allocation function and is useful with
deleter enabled types like `std::unique_ptr`.
``
#include <boost/align/aligned_delete.hpp>
#include <memory>
struct alignas(16) type {
float data[4];
};
int main()
{
void* p = boost::alignment::
aligned_alloc(alignof(type), sizeof(type));
if (p) {
type* q = ::new(p) type();
std::unique_ptr<type,
boost::alignment::aligned_delete> u(q);
(void)u;
}
}
``
[endsect]
[section alignment_of]
This type trait can be used to query the alignment
requirement of a type at compile time. It is useful
in static assertions to validate type alignment.
``
#include <boost/align/alignment_of.hpp>
template<class T>
class utility {
static_assert(boost::alignment::
alignment_of<T>::value == 16, "");
public:
utility()
: object() {
}
private:
T object;
};
struct alignas(16) type {
float data[4];
};
int main()
{
utility<type> u;
(void)u;
}
``
[endsect]
[section is_aligned]
This function is used to compare the alignment of a
pointer. It is useful in assertions that validate a
pointer value is aligned on a given boundary.
``
#include <boost/align/is_aligned.hpp>
#include <cassert>
void use(void* ptr, std::size_t size)
{
assert(boost::alignment::is_aligned(ptr, 16));
(void)size;
}
int main()
{
alignas(16) char c[100];
use(c, sizeof c);
}
``
[endsect]
[endsect]
[section Examples]
[section:aligned_ptr aligned_ptr and make_aligned]
This example presents an alternative to `std::unique_ptr`
for objects allocated with the aligned allocation
function. It is defined simply by providing an alias
template which uses `std::unique_ptr` with our aligned
deleter in place of the default `std::default_delete`
deleter. It also presents an alternative to
`std::make_unique` for the creation of these aligned
unique pointer objects. It is implemented using our
aligned allocation function.
[heading Implementation]
``
#include <boost/align/aligned_alloc.hpp>
#include <boost/align/aligned_delete.hpp>
#include <memory>
template<class T>
using aligned_ptr = std::unique_ptr<T,
boost::alignment::aligned_delete>;
template<class T, class... Args>
inline aligned_ptr<T> make_aligned(Args&&... args)
{
auto p = boost::alignment::
aligned_alloc(alignof(T), sizeof(T));
if (!p) {
throw std::bad_alloc();
}
try {
auto q = ::new(p) T(std::forward<Args>(args)...);
return aligned_ptr<T>(q);
} catch (...) {
boost::alignment::aligned_free(p);
throw;
}
}
``
[heading Usage]
``
struct alignas(16) type {
float data[4];
};
int main()
{
auto p = make_aligned<type>();
p->data[0] = 1.0f;
}
``
[endsect]
[section aligned_vector]
This example presents an alternative to `std::vector`
that can be used with over-aligned types, and allows
specifying a minimum alignment. It is defined simply
by providing an alias template which uses `std::vector`
with our aligned allocator.
[heading Implementation]
``
#include <boost/align/aligned_allocator.hpp>
#include <vector>
template<class T, std::size_t Alignment = 1>
using aligned_vector = std::vector<T,
boost::alignment::aligned_allocator<T, Alignment> >;
``
[heading Usage]
``
enum {
cache_line = 64
};
int main()
{
aligned_vector<char, cache_line> v(32);
v[0] = 1;
}
``
[endsect]
[endsect]
[section Reference]
[section align]
The alignment function is used to obtain a pointer to
the first address within the specified buffer that is a
multiple of the specified alignment value. This function
exists in the C++11 standard library but is provided in
this library for those C++11 and C++03 library
implementations which do not yet support it.
[heading:synopsis Header <boost/align/align.hpp>]
``
namespace boost {
namespace alignment {
void* align(std::size_t alignment, std::size_t size,
void*& ptr, std::size_t& space);
}
}
``
[heading:align Function align]
``
void* align(std::size_t alignment, std::size_t size,
void*& ptr, std::size_t& space);
``
[: [*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 fundamental alignment value
or an extended alignment value, and 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:aligned_alloc aligned_alloc and aligned_free]
The aligned allocation function is a replacement for
`::operator new(std::size_t, const std::no_throw_t&)`
that allows requesting aligned memory. The deallocation
function replaces the corresponding
`::operator delete(void*)` function. This functionality
is not yet provided by the C++ standard.
[heading:synopsis Header <boost/align/aligned_alloc.hpp>]
``
namespace boost {
namespace alignment {
void* aligned_alloc(std::size_t alignment,
std::size_t size);
void aligned_free(void* ptr);
}
}
``
[heading:aligned_alloc Function aligned_alloc]
``
void* aligned_alloc(std::size_t alignment,
std::size_t size);
``
[: [*Effects:] Allocates space for an object whose
alignment is specified by `alignment`, whose size is
specified by `size`, and whose value is indeterminate.
The value of `alignment` shall be a power of two.
[*Requires:] `alignment` shall be a power of two.
[*Returns:] A null pointer or a pointer to the
allocated space.
[*Note:] On certain platforms, the alignment may be
rounded up to `alignof(void*)` and the space allocated
may be slightly larger than `size` bytes, by an
additional `sizeof(void*)` and `alignment - `1 bytes.
]
[heading:aligned_free Function aligned_free]
``
void aligned_free(void* ptr);
``
[: [*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 aligned_allocator]
The aligned allocator is a replacement for the default
allocator, `std::allocator`, that supports value types
which are over-aligned. It also allows specifying a
minimum alignment value used for all allocations, via
the optional template parameter. An alignment aware
allocator is not yet provided by the C++ standard.
[tip Using the aligned allocator with a minimum
alignment value is generally only suitable 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:synopsis Header
<boost/align/aligned_allocator.hpp>]
``
namespace boost {
namespace alignment {
template<class T, std::size_t Alignment = 1>
class aligned_allocator;
template<std::size_t Alignment>
class aligned_allocator<void, Alignment>;
template<class T1, class T2, std::size_t Alignment>
bool operator==(const aligned_allocator<T1,
Alignment>&, const aligned_allocator<T2,
Alignment>&) noexcept;
template<class T1, class T2, std::size_t Alignment>
bool operator!=(const aligned_allocator<T1,
Alignment>&, const aligned_allocator<T2,
Alignment>&) noexcept;
}
}
``
[heading:aligned_allocator Class template
aligned_allocator]
``
template<class T, std::size_t Alignment = 1>
class aligned_allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
template<class U>
struct rebind {
typedef aligned_allocator<U, Alignment> other;
};
aligned_allocator() noexcept = default;
template<class U>
aligned_allocator(const aligned_allocator<U,
Alignment>&) noexcept;
pointer address(reference value) const noexcept;
const_pointer address(const_reference value)
const noexcept;
pointer allocate(size_type size,
const_void_pointer = 0);
void deallocate(pointer ptr, size_type);
size_type max_size() const noexcept;
template<class U, class... Args>
void construct(U* ptr, Args&&... args);
template<class U>
void destroy(U* ptr);
};
template<std::size_t Alignment>
class aligned_allocator<void, Alignment> {
public:
typedef void value_type;
typedef void* pointer;
typedef const void* const_pointer;
template<class U>
struct rebind {
typedef aligned_allocator<U, Alignment> other;
};
};
``
[heading Members]
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.
``
pointer address(reference value) const noexcept;
``
[: [*Returns:] The actual address of the object
referenced by `value`, even in the presence of an
overloaded `operator&`.
]
``
const_pointer address(const_reference value)
const noexcept;
``
[: [*Returns:] The actual address of the object
referenced by `value`, even in the presence of an
overloaded `operator&`.
]
``
pointer allocate(size_type size,
const_void_pointer = 0);
``
[: [*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);
``
[: [*Requires:] `ptr` shall be a pointer value obtained
from `allocate()`.
[*Effects:] Deallocates the storage referenced by
`ptr`.
[*Remark:] Uses `alignment::aligned_free(void*)`.
]
``
size_type max_size() const noexcept;
``
[: [*Returns:] The largest value `N` for which the call
`allocate(N)` might succeed. ]
``
template<class U, class... Args>
void construct(U* ptr, Args&&... args);
``
[: [*Effects:]
`::new((void*)ptr) U(std::forward<Args>(args)...)` ]
``
template<class U>
void destroy(U* ptr);
``
[: [*Effects:] `ptr->~U()` ]
[heading Globals]
``
template<class T1, class T2, std::size_t Alignment>
bool operator==(const aligned_allocator<T1,
Alignment>&, const aligned_allocator<T2,
Alignment>&) noexcept;
``
[: [*Returns:] `true`. ]
``
template<class T1, class T2, std::size_t Alignment>
bool operator!=(const aligned_allocator<T1,
Alignment>&, const aligned_allocator<T2,
Alignment>&) noexcept;
``
[: [*Returns:] `false`. ]
[endsect]
[section aligned_allocator_adaptor]
The aligned allocator adaptor can turn any existing C++03
or C++11 allocator into one that supports value types that
are over-aligned. It also allows specifying a minimum
alignment value used for all allocations, via the
optional template parameter. An alignment aware allocator
adaptor is not yet provided by the C++ standard.
[tip This adaptor can be used with a C++11 allocator
whose pointer type is a smart pointer but the adaptor
will expose only raw pointer types.]
[heading:synopsis Header
<boost/align/aligned_allocator_adaptor.hpp>]
``
namespace boost {
namespace alignment {
template<class Allocator, std::size_t Alignment = 1>
class aligned_allocator_adaptor;
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;
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;
}
}
``
[heading:aligned_allocator_adaptor Class template
aligned_allocator_adaptor]
``
template<class Allocator, std::size_t Alignment = 1>
class aligned_allocator_adaptor
: public Allocator {
typedef std::allocator_traits<Allocator>
Traits; // exposition only
public:
typedef typename Traits::value_type value_type;
typedef typename Traits::size_type size_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::ptrdiff_t difference_type;
template<class U>
struct rebind {
typedef aligned_allocator_adaptor<typename Traits::
template rebind_alloc<U>, Alignment> other;
};
aligned_allocator_adaptor() = default;
template<class A>
explicit aligned_allocator_adaptor(A&& alloc)
noexcept;
template<class U>
aligned_allocator_adaptor(const
aligned_allocator_adaptor<U, Alignment>& other)
noexcept;
Allocator& base() noexcept;
const Allocator& base() const noexcept;
pointer allocate(size_type size);
pointer allocate(size_type size,
const_void_pointer hint);
void deallocate(pointer ptr, size_type size);
};
``
[heading Constructors]
``
aligned_allocator_adaptor() = default;
``
[: [*Effects:] Value-initializes the `Allocator` base
class.
]
``
template<class A>
explicit aligned_allocator_adaptor(A&& alloc)
noexcept;
``
[: [*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;
``
[: [*Requires:] `Allocator` shall be constructible
from `A`.
[*Effects:] Initializes the `Allocator` base class
with `other.base()`.
]
[heading Members]
``
Allocator& base() noexcept;
``
[: [*Returns:] `static_cast<Allocator&>(*this)` ]
``
const Allocator& base() const noexcept;
``
[: [*Returns:] `static_cast<const Allocator&>(*this)` ]
``
pointer allocate(size_type size);
``
[: [*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 unspecified.
[*Throws:] Throws an exception thrown from
`A2::allocate` if the storage cannot be obtained.
]
``
pointer allocate(size_type size,
const_void_pointer hint);
``
[: [*Requires:] `hint` is a value obtained by calling
`allocate()` on any equivalent aligned allocator
adaptor object, or else `nullptr`.
[*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 unspecified.
[*Throws:] Throws an exception thrown from
`A2::allocate` if the storage cannot be obtained.
]
``
void deallocate(pointer ptr, size_type size);
``
[: [*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 unspecified.
]
[heading Globals]
``
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;
``
[: [*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;
``
[: [*Returns:] `!(a1 == a2)` ]
[endsect]
[section aligned_delete]
The aligned deleter class is convenient utility for
destroying and then deallocating constructed objects
that were allocated using aligned allocation function
provided in this library. It serves as a replacement
for the `std::default_delete` class.
[heading:synopsis Header
<boost/align/aligned_delete.hpp>]
``
namespace boost {
namespace alignment {
class aligned_delete;
}
}
``
[heading:aligned_delete Class aligned_delete]
``
class aligned_delete {
public:
template<class T>
void operator()(T* ptr) const
noexcept(noexcept(ptr->~T()));
};
``
[heading Members]
``
template<class T>
void operator()(T* ptr) const
noexcept(noexcept(ptr->~T()));
``
[: [*Effects:] Calls `~T()` on `ptr` to destroy the
object and then calls `alignment::aligned_free` on
`ptr` to free the allocated memory.
[*Note:] If `T` is an incomplete type, the program
is ill-formed.
]
[endsect]
[section alignment_of]
The alignment type trait is used to query the alignment
requirement of a type at compile time. It is provided by
the C++11 standard library but is provided in this library
for C++11 and C++03 implementations that do not provide
this functionality.
[heading:synopsis Header <boost/align/alignment_of.hpp>]
``
namespace boost {
namespace alignment {
template<class T>
struct alignment_of;
}
}
``
[heading:alignment_of Type trait alignment_of]
``
template<class T>
struct alignment_of
: std::integral_constant<std::size_t, unspecified> {
};
``
[: [*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]
[section is_aligned]
The alignment validation function indicates whether or
not an address is a multiple of the specified alignment
value. It is generally useful in assertions to verify
memory is correctly aligned. This functionality is
not yet provided by the C++ standard.
[heading:synopsis Header <boost/align/is_aligned.hpp>]
``
namespace boost {
namespace alignment {
bool is_aligned(std::size_t alignment,
const void* ptr) noexcept;
}
}
``
[heading:is_aligned Function is_aligned]
``
bool is_aligned(std::size_t alignment,
const void* ptr) noexcept;
``
[: [*Requires:] `alignment` shall be a power of two.
[*Returns:] `true` if the value of `ptr` is aligned
on the boundary specified by `alignment`, otherwise
`false`.
]
[endsect]
[endsect]
[section Vocabulary]
[heading:basic_align \[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.
[tip
``
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. ]
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).]
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.]
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.]
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]
Boost.Align has been tested with GCC, Clang, Visual C++,
and Intel C++, on Linux, Windows, and OS X. It supports
any conforming C++11 or C++03 compilers.
[table Compilers Tested
[ [Compiler]
[Version]
[Library]
[Platform]
[Hardware]
[Standard]
]
[ [clang]
[3.0 - 3.5]
[libstdc++, libc++]
[linux, darwin]
[x86, x64]
[c++11, c++03]
]
[ [gcc]
[4.4 - 4.9]
[libstdc++]
[linux, windows]
[x86, x64, arm]
[c++11, c++03]
]
[ [intel]
[11.1 - 13.1]
[libstdc++]
[linux]
[x86, x64]
[default]
]
[ [msvc]
[8.0 - 12.0]
[dinkumware]
[windows]
[x86, x64]
[default]
]
]
[endsect]
[section Acknowledgments]
Glen Fernandes authored the library and contributed it
to the Boost C++ library collection.
[heading Library Reviews]
The following developers reviewed the design, code,
examples, tests, and documentation.
* Peter Dimov
* Andrey Semashev
* Bjorn Reese
* Steven Watanabe
* Antony Polukhin
* Lars Viklund
* Michael Spencer
* Paul A. Bristow
[heading Review Manager]
Ahmed Charles generously served as review manager for
the formal review of the library.
[endsect]
[section History]
[heading Update 1.0]
* Updates to the tutorial and reference documentation.
[heading Version 1.0]
* Glen Fernandes implemented the Boost.Align library.
[endsect]