Функция выравнивания может использоваться для поиска первого адреса заданного значения выравнивания в заданном буфере заданного размера. Он корректирует предоставленный указатель, возвращает это значение и уменьшает пространство на сумму, авансированную, если выравнивание удается, при условии достаточного пространства в буфере. В противном случае он дает нулевой указатель для обозначения отказа из-за недостаточного пространства.
#include <boost/align/align.hpp>
#include <boost/align/alignment_of.hpp>
#include <new>
struct alignas(16) type {
float data[4];
};
void use(void* ptr, std::size_t size)
{
auto p = boost::alignment::align(16, sizeof(type), ptr, size);
if (p) {
auto q = ::new(p) type;
q->~type();
}
}
int main()
{
char c[64];
use(c, sizeof c);
}
Рассмотрим эти функции выравнивания включенных версий<std::malloc
>,<std::free
>или<::operatornew(std::size_t,conststd::no_throw_t&)
>,<::operatordelete(void*)
>. Выровненная функция распределения выделяет пространство с заданным размером и выравниванием. Выровненная функция распределения может затем распределить это пространство.
#include <boost/align/aligned_alloc.hpp>
int main()
{
void* p = boost::alignment::aligned_alloc(16, 100);
if (p) {
boost::alignment::aligned_free(p);
}
}
Рассматривайте этот шаблон класса как превосходную версию распределителя по умолчанию<std::allocator
>, потому что он может использоваться с типами, которые чрезмерно выровнены.
#include <boost/align/aligned_allocator.hpp>
#include <vector>
struct alignas(16) type {
float data[4];
};
int main()
{
std::vector<type,
boost::alignment::aligned_allocator<type> > v;
v.emplace_back();
}
Дополнительный параметр шаблона этого класса позволяет указать минимальное выравнивание для использования для распределений. Минимальное выравнивание по умолчанию составляет 1.
#include <boost/align/aligned_allocator.hpp>
#include <vector>
int main()
{
std::vector<char, boost::alignment::
aligned_allocator<char, 16> > v;
v.emplace_back();
}
Этот шаблон класса может превратить любой существующий тип распределителя, C++11 или C++03, в тот, который поддерживает типы, которые переупорядочены.
#include <boost/align/aligned_allocator_adaptor.hpp>
#include <vector>
template<class T, class Allocator>
class utility {
public:
void add() {
v.emplace_back();
}
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;
u.add();
}
Дополнительный параметр шаблона этого класса позволяет указать минимальное выравнивание для использования для распределений. Минимальное выравнивание по умолчанию составляет 1.
#include <boost/align/aligned_allocator_adaptor.hpp>
#include <vector>
template<class T, class Allocator, std::size_t Alignment>
class utility {
public:
void add() {
v.v.emplace_back();
}
private:
std::vector<T, boost::alignment::
aligned_allocator_adaptor<Allocator, Alignment> > v;
};
int main()
{
utility<char, std::allocator<char>, 16> u;
u.add();
}
Рассматривайте этот класс как выравнивающую версию шаблона класса<std::default_delete
>. Это удалитель, который разрушает объект, а затем распределяет пространство с помощью нашей выровненной функции распределения. Он должен использоваться с построенными объектами, которые были выделены с нашей выровненной функцией распределения, и полезен для таких типов, как<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(16, sizeof(type));
if (p) {
type* q = ::new(p) type;
std::unique_ptr<type, boost::alignment::aligned_delete>(q);
}
}
Эта черта типа может использоваться для запроса требования выравнивания типа во время компиляции.
#include <boost/align/alignment_of.hpp>
#include <type_traits>
template<class T>
class utility {
public:
void construct() {
void* p = &v;
::new(p) T();
}
private:
std::aligned_storage_t<sizeof(T),
boost::alignment::alignment_of<T>::value> v;
};
struct alignas(16) type {
float data[4];
};
int main()
{
utility<type> u;
u.construct();
}
Этот макрос используется для уведомления компилятора о выравнивании заданной переменной указателя. Это полезно для руководства по оптимизации компиляторов для векторизации или применения других конкретных компиляторов, оптимизации, связанной с выравниванием.
#include <boost/align/assume_aligned.hpp>
void use(double* array, std::size_t size)
{
BOOST_ALIGN_ASSUME_ALIGNED(array, 16);
for (std::size_t i = 0; i < size; i++) {
array[i]++;
}
}
int main()
{
alignas(16) double d[4] { };
use(d, 4);
}
Эта функция используется для сравнения выравнивания указателя. Это полезно в утверждениях, которые подтверждают, что значение указателя выровнено на данной границе.
#include <boost/align/is_aligned.hpp>
#include <cassert>
void use(void* ptr)
{
assert(boost::alignment::is_aligned(ptr, 16));
}
int main()
{
alignas(16) char c[64];
use(c);
}