1[/ 2Copyright 2014-2017 Glen Joseph Fernandes 3(glenjofe@gmail.com) 4 5Distributed under the Boost Software License, Version 1.0. 6(http://www.boost.org/LICENSE_1_0.txt) 7] 8 9[library Boost.Align 10[quickbook 1.6] 11[id align] 12[copyright 2014-2017 Glen Joseph Fernandes] 13[authors [Fernandes, Glen]] 14[dirname align] 15[license Distributed under the Boost Software License, Version 1.0.]] 16 17[section Introduction] 18 19The Boost Align C++ library provides functions, classes, templates, traits, 20and macros, for the control, inspection, and diagnostic of memory alignment. 21 22[endsect] 23 24[section Rationale] 25 26[heading Dynamic allocation] 27 28C++11 added the ability to specify increased alignment (over-alignment) for 29class types. Unfortunately, `::operator new` allocation functions, `new` 30expressions and the Default Allocator, `std::allocator`, do not support 31dynamic memory allocation of over-aligned data. This library provides 32allocation functions and allocators that respect the alignment requirements of 33a type and so are suitable for allocating memory for over-aligned types. 34 35[variablelist 36[[`aligned_alloc(alignment, size)`] 37[Replaces `::operator new(size, std::nothrow)`]] 38[[`aligned_free(pointer)`] 39[Replaces `::operator delete(pointer, std::nothrow)`]] 40[[`aligned_allocator<T>`][Replaces `std::allocator<T>`]] 41[[`aligned_allocator_adaptor<Allocator>`][Replaces use of Allocator]] 42[[`aligned_delete`][Replaces `std::default_delete<T>`]]] 43 44[heading Pointer alignment] 45 46C++11 provided `std::align` in the standard library to align a pointer value. 47Unfortunately some C++ standard library implementations do not support it yet 48(libstdc++ as far as gcc 4.8.0) and other standard library implementations 49implement it incorrectly (dinkumware in msvc11.0). This library provides it 50for those implementations and also for C++03 compilers where it is equally 51useful. 52 53[heading Querying alignment] 54 55C++11 provided the `std::alignment_of` trait in the standard library to query 56the alignment requirement of a type. Unfortunately some C++ standard library 57vendors do not implement it in an entirely standard conforming manner, such as 58for array types (libc++ as far as clang 3.4). Other vendor implementations 59report incorrect values for certain types, such as pointer to members (msvc 6014.0). This library provides it for those implementations and also for C++03 61compilers where it is equally useful. 62 63[heading Hinting alignment] 64 65Allocating aligned memory is sometimes not enough to ensure that optimal code 66is generated. Developers use specific compiler intrinsics to notify the 67compiler of a given alignment property of a memory block. This library 68provides a macro, `BOOST_ALIGN_ASSUME_ALIGNED`, to abstract that functionality 69for compilers with the appropriate intrinsics. 70 71[heading Checking alignment] 72 73This library provides a function, `is_aligned` to test the alignment of a 74pointer value. It is generally useful in assertions to validate that memory is 75correctly aligned. 76 77[endsect] 78 79[section Examples] 80 81[heading Aligned allocation] 82 83To dynamically allocate storage with desired alignment, you can use the 84`aligned_alloc` function: 85 86[ordered_list 87[`void* storage = boost::alignment::aligned_alloc(alignment, size);`]] 88 89To deallocate storage allocated with the `aligned_alloc` function, use 90the `aligned_free` function: 91 92[ordered_list [`boost::alignment::aligned_free(storage);`]] 93 94[heading Aligned allocator] 95 96For C++ allocator aware code, you can use the `aligned_allocator` class 97template for an allocator that respects over-alignment: 98 99[ordered_list 100[`std::vector<int128_t, 101boost::alignment::aligned_allocator<int128_t> > vector;`]] 102 103This template allows specifying minimum alignment for all dynamic allocations: 104 105[ordered_list 106[`std::vector<double, 107boost::alignment::aligned_allocator<double, 64> > vector;`]] 108 109[heading Aligned allocator adaptor] 110 111To turn an allocator into an allocator that respects over-alignment, you can 112use the `aligned_allocator_adaptor` class template: 113 114[ordered_list 115[`boost::alignment::aligned_allocator_adaptor<First> second(first);`]] 116 117This template allows specifying minimum alignment for all dynamic 118allocations: 119 120[ordered_list 121[`boost::alignment::aligned_allocator_adaptor<First, 64> second(first);`]] 122 123[heading Aligned deleter] 124 125For a deleter that can be paired with `aligned_alloc`, you can use the 126`aligned_delete` class: 127 128[ordered_list 129[`std::unique_ptr<double, boost::alignment::aligned_delete> pointer;`]] 130 131[heading Pointer alignment] 132 133To advance a pointer to the next address with the desired alignment: 134 135[ordered_list 136[`void* pointer = storage;`] 137[`std::size_t space = size;`] 138[`void* result = boost::alignment::align(64, sizeof(double), pointer, 139space);`]] 140 141[heading Querying alignment] 142 143To obtain the alignment of a given type at compie time, you can use: 144 145[ordered_list [`boost::alignment::alignment_of<int128_t>::value`]] 146 147If your compiler supports C++14 variable templates, you can also use: 148 149[ordered_list [`boost::alignment::alignment_of_v<int128_t>`]] 150 151[heading Hinting alignment] 152 153To inform the compiler about the alignment of a pointer, you can use: 154 155[ordered_list [`BOOST_ALIGN_ASSUME_ALIGNED(pointer, 64)`]] 156 157[heading Checking alignment] 158 159To check alignment of a pointer you can use the `is_aligned` function: 160 161[ordered_list [`assert(boost::alignment::is_aligned(pointer, 64));`]] 162 163[endsect] 164 165[section Reference] 166 167[section Functions] 168 169[section align] 170 171[variablelist 172[[`void* align(std::size_t alignment, std::size_t size, void*& ptr, 173std::size_t& space);`] 174[[variablelist 175[[Header][`#include <boost/align/align.hpp>`]] 176[[Effects] 177[If it is possible to fit `size` bytes of storage aligned by `alignment` into 178the buffer pointed to by `ptr` with length `space`, the function updates `ptr` 179to point to the first possible address of such storage and decreases `space` by 180the number of bytes used for alignment. Otherwise, the function does nothing.]] 181[[Requires] 182[[itemized_list 183[`alignment` shall be a power of two] 184[`ptr` shall point to contiguous storage of at least `space` bytes]]]] 185[[Returns] 186[A null pointer if the requested aligned buffer would not fit into the 187available space, otherwise the adjusted value of `ptr`.]] 188[[Note] 189[The function updates its `ptr` and `space` arguments so that it can be called 190repeatedly with possibly different `alignment` and `size`arguments for the same 191buffer.]]]]]] 192 193[endsect] 194 195[section align_up] 196 197[variablelist 198[[`template<class T> constexpr T align_up(T value, std::size_t alignment) 199noexcept;`] 200[[variablelist 201[[Header][`#include <boost/align/align_up.hpp>`]] 202[[Constraints][`T` is not a pointer type]] 203[[Requires][`alignment` shall be a power of two]] 204[[Returns][A value at or after `value` that is a multiple of `alignment`.]]]]]] 205 206[endsect] 207 208[section align_down] 209 210[variablelist 211[[`template<class T> constexpr T align_down(T value, std::size_t alignment) 212noexcept;`] 213[[variablelist 214[[Header][`#include <boost/align/align_down.hpp>`]] 215[[Constraints][`T` is not a pointer type]] 216[[Requires][`alignment` shall be a power of two]] 217[[Returns] 218[A value at or before `value` that is a multiple of `alignment`.]]]]]] 219 220[endsect] 221 222[section aligned_alloc] 223 224[variablelist 225[[`void* aligned_alloc(std::size_t alignment, std::size_t size);`] 226[[variablelist 227[[Header][`#include <boost/align/aligned_alloc.hpp>`]] 228[[Effects] 229[Allocates space for an object whose alignment is specified by `alignment`, 230whose size is specified by `size`, and whose value is indeterminate.]] 231[[Requires][`alignment` shall be a power of two.]] 232[[Returns][A null pointer or a pointer to the allocated space.]] 233[[Note] 234[On certain platforms, the space allocated may be slightly larger than 235`size` bytes, to allow for alignment.]]]]]] 236 237[endsect] 238 239[section aligned_free] 240 241[variablelist 242[[`void aligned_free(void* ptr);`] 243[[variablelist 244[[Header][`#include <boost/align/aligned_alloc.hpp>`]] 245[[Effects] 246[Causes the space pointed to by `ptr` to be deallocated, that is, made 247available for further allocation. If `ptr` is a null pointer, no action occurs. 248Otherwise, if the argument does not match a pointer earlier returned by the 249`aligned_alloc()` function, or if the space has been deallocated by a call to 250`aligned_free()`, the behavior is undefined.]] 251[[Requires] 252[`ptr` is a null pointer or a pointer earlier returned by the `aligned_alloc()` 253function that has not been deallocated by a call to `aligned_free()`.]] 254[[Returns][The `aligned_free()` function returns no value.]]]]]] 255 256[endsect] 257 258[section is_aligned] 259 260[variablelist 261[[`bool is_aligned(const volatile void* ptr, std::size_t alignment) noexcept;`] 262[[variablelist 263[[Header][`#include <boost/align/is_aligned.hpp>`]] 264[[Requires][`alignment` shall be a power of two.]] 265[[Returns] 266[`true` if `ptr` is aligned on the boundary specified by `alignment`, otherwise 267`false`.]]]]] 268[[`template<class T> constexpr bool is_aligned(T value, std::size_t alignment) 269noexcept;`] 270[[variablelist 271[[Header][`#include <boost/align/is_aligned.hpp>`]] 272[[Constraints][`T` is not a pointer type]] 273[[Requires][`alignment` shall be a power of two.]] 274[[Returns] 275[`true` if the value of `value` is aligned on the boundary specified by 276`alignment`, otherwise `false`.]]]]]] 277 278[endsect] 279 280[endsect] 281 282[section Classes] 283 284[section aligned_allocator] 285 286[variablelist 287[[`template<class T, std::size_t Alignment = 1> class aligned_allocator;`] 288[[variablelist 289[[Header][`#include <boost/align/aligned_allocator.hpp>`]] 290[[Note] 291[Using the aligned allocator with a minimum Alignment value is generally only 292useful with containers that are not node-based such as `vector`. With 293node-based containers, such as `list`, the node object would have the minimum 294alignment instead of the value type object.]]]]]] 295 296[heading Member types] 297 298[ordered_list 299[`typedef T value_type;`] 300[`typedef T* pointer;`] 301[`typedef const T* const_pointer;`] 302[`typedef void* void_pointer;`] 303[`typedef const void* const_void_pointer;`] 304[`typedef std::add_lvalue_reference_t<T> reference;`] 305[`typedef std::add_lvalue_reference_t<const T> const_reference;`] 306[`typedef std::size_t size_type;`] 307[`typedef std::ptrdiff_t difference_type;`] 308[`typedef std::true_type propagate_on_container_move_assignment;`] 309[`typedef std::true_type is_always_equal;`] 310[`template<class U> struct rebind { typedef aligned_allocator<U, Alignment> 311other; };`]] 312 313[heading Constructors] 314 315[variablelist 316[[`aligned_allocator() = default;`] 317[[variablelist [[Effects][Constructs the allocator.]]]]] 318[[`template<class U> aligned_allocator(const aligned_allocator<U, Alignment>&) 319noexcept;`] 320[[variablelist [[Effects][Constructs the allocator.]]]]]] 321 322[heading Member functions] 323 324Except for the destructor, member functions of the aligned allocator shall not 325introduce data races as a result of concurrent calls to those member functions 326from different threads. Calls to these functions that allocate or deallocate a 327particular unit of storage shall occur in a single total order, and each such 328deallocation call shall happen before the next allocation (if any) in this 329order. 330 331[variablelist 332[[`pointer allocate(size_type size, const_void_pointer = 0);`] 333[[variablelist 334[[Returns] 335[A pointer to the initial element of an array of storage of size 336`n * sizeof(T)`, aligned on the maximum of the minimum alignment specified and 337the alignment of objects of type `T`.]] 338[[Remark] 339[The storage is obtained by calling `aligned_alloc(std::size_t, 340std::size_t)`.]] 341[[Throws][`std::bad_alloc` if the storage cannot be obtained.]]]]] 342[[`void deallocate(pointer ptr, size_type);`] 343[[variablelist 344[[Requires] 345[`ptr` shall be a pointer value obtained from `allocate()`.]] 346[[Effects][Deallocates the storage referenced by `ptr`.]] 347[[Remark][Uses `aligned_free(void*)`.]]]]] 348[[`size_type max_size() const noexcept;`] 349[[variablelist 350[[Returns] 351[The largest value `N` for which the call `allocate(N)` might succeed.]]]]] 352[[`template<class U, class... Args> void construct(U* ptr, Args&&... args);`] 353[[variablelist 354[[Effects][`::new((void*)ptr) U(std::forward<Args>(args)...)`.]]]]] 355[[`template<class U> void destroy(U* ptr);`] 356[[variablelist [[Effects][`ptr->~U()`.]]]]]] 357 358[heading Global operators] 359 360[variablelist 361[[`template<class T1, class T2, std::size_t Alignment> bool operator==(const 362aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&) 363noexcept;`] 364[[variablelist [[Returns][`true`]]]]] 365[[`template<class T1, class T2, std::size_t Alignment> bool operator!=(const 366aligned_allocator<T1, Alignment>&, const aligned_allocator<T2, Alignment>&) 367noexcept;`] 368[[variablelist [[Returns][`false`]]]]]] 369 370[endsect] 371 372[section aligned_allocator_adaptor] 373 374[variablelist 375[[`template<class Allocator, std::size_t Alignment = 1> class 376aligned_allocator_adaptor;`] 377[[variablelist 378[[Header][`#include <boost/align/aligned_allocator_adaptor.hpp>`]] 379[[Note] 380[This adaptor can be used with a C++11 Allocator whose pointer type is a smart 381pointer but the adaptor can choose to expose only raw pointer types.]]]]]] 382 383[heading Member types] 384 385[ordered_list 386[`typedef typename Allocator::value_type value_type;`] 387[`typedef value_type* pointer;`] 388[`typedef const value_type* const_pointer;`] 389[`typedef void* void_pointer;`] 390[`typedef const void* const_void_pointer;`] 391[`typedef std::size_t size_type;`] 392[`typedef std::ptrdiff_t difference_type;`] 393[`template<class U> struct rebind { typedef aligned_allocator_adaptor<typename 394std::allocator_traits<Allocator>::template rebind_alloc<U>, Alignment> 395other; };`]] 396 397[heading Constructors] 398 399[variablelist 400[[`aligned_allocator_adaptor() = default;`] 401[[variablelist [[Effects][Value-initializes the `Allocator` base class.]]]]] 402[[`template<class A> aligned_allocator_adaptor(A&& alloc) noexcept;`] 403[[variablelist [[Requires][`Allocator` shall be constructible from `A`.]] 404[[Effects] 405[Initializes the `Allocator` base class with `std::forward<A>(alloc)`.]]]]] 406[[`template<class U> aligned_allocator_adaptor(const 407aligned_allocator_adaptor<U, Alignment>& other) noexcept;`] 408[[variablelist 409[[Requires][`Allocator` shall be constructible from `A`.]] 410[[Effects][Initializes the `Allocator` base class with `other.base()`.]]]]]] 411 412[heading Member functions] 413 414[variablelist 415[[`Allocator& base() noexcept;`] 416[[variablelist [[Returns][`static_cast<Allocator&>(*this)`]]]]] 417[[`const Allocator& base() const noexcept;`] 418[[variablelist [[Returns][`static_cast<const Allocator&>(*this)`]]]]] 419[[`pointer allocate(size_type size);`] 420[[variablelist 421[[Returns] 422[A pointer to the initial element of an array of storage of size 423`n * sizeof(value_type)`, aligned on the maximum of the minimum alignment 424specified and the alignment of objects of type `value_type`.]] 425[[Remark] 426[The storage is obtained by calling `A2::allocate()` on an object `a2`, where 427`a2` of type `A2` is a rebound copy of `base()` where its `value_type` is 428implementation defined.]] 429[[Throws] 430[Throws an exception thrown from `A2::allocate()` if the storage cannot be 431obtained.]]]]] 432[[`pointer allocate(size_type size, const_void_pointer hint);`] 433[[variablelist 434[[Requires] 435[`hint` is a value obtained by calling `allocate()` on any equivalent allocator 436object, or else a null pointer.]] 437[[Returns] 438[A pointer to the initial element of an array of storage of size 439`n * sizeof(value_type)`, aligned on the maximum of the minimum alignment 440specified and the alignment of objects of type `value_type`.]] 441[[Remark] 442[The storage is obtained by calling `A2::allocate()` on an object `a2`, where 443`a2` of type `A2` is a rebound copy of `base()` where its `value_type` is an 444implementation defined.]] 445[[Throws] 446[Throws an exception thrown from `A2::allocate()` if the storage cannot be 447obtained.]]]]] 448[[`void deallocate(pointer ptr, size_type size);`] 449[[variablelist 450[[Requires] 451[[itemized_list 452[`ptr` shall be a pointer value obtained from `allocate()`] 453[`size` shall equal the value passed as the first argument to the invocation of 454`allocate()` which returned `ptr`.]]]] 455[[Effects][Deallocates the storage referenced by `ptr`.]] 456[[Note] 457[Uses `A2::deallocate()` on an object `a2`, where `a2` of type `A2` is a 458rebound copy of `base()` where its `value_type` is implementation 459defined.]]]]]] 460 461[heading Global operators] 462 463[variablelist 464[[`template<class A1, class A2, std::size_t Alignment> bool operator==(const 465aligned_allocator_adaptor<A1, Alignment>& a1, const 466aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`] 467[[variablelist [[Returns][`a1.base() == a2.base()`]]]]] 468[[`template<class A1, class A2, std::size_t Alignment> bool operator!=(const 469aligned_allocator_adaptor<A1, Alignment>& a1, const 470aligned_allocator_adaptor<A2, Alignment>& a2) noexcept;`] 471[[variablelist [[Returns][`!(a1 == a2)`]]]]]] 472 473[endsect] 474 475[section aligned_delete] 476 477[variablelist 478[[`class aligned_delete;`] 479[[variablelist [[Header][`#include <boost/align/aligned_delete.hpp>`]]]]]] 480 481[heading Member operators] 482 483[variablelist 484[[`template<class T> void operator()(T* ptr) noexcept(noexcept(ptr->~T()));`] 485[[variablelist 486[[Effects] 487[Calls `~T()` on `ptr` to destroy the object and then calls `aligned_free()` on 488`ptr` to free the allocated memory.]] 489[[Note][If `T` is an incomplete type, the program is ill-formed.]]]]]] 490 491[endsect] 492 493[endsect] 494 495[section Traits] 496 497[section alignment_of] 498 499[variablelist 500[[`template<class T> struct alignment_of;`] 501[[variablelist 502[[Header][`#include <boost/align/alignment_of.hpp>`]] 503[[Value] 504[The alignment requirement of the type `T` as an integral constant of type 505`std::size_t`. When `T` is a reference array type, the value shall be the 506alignment of the referenced type. When `T` is an array type, the value shall be 507the alignment of the element type.]] 508[[Requires] 509[`T` shall be a complete object type, or an array thereof, or a reference to 510one of those types.]]]]]] 511 512[endsect] 513 514[endsect] 515 516[section Macros] 517 518[section BOOST_ALIGN_ASSUME_ALIGNED] 519 520[variablelist 521[[`BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)`] 522[[variablelist 523[[Header][`#include <boost/align/assume_aligned.hpp>`]] 524[[Requires] 525[[itemized_list [`alignment` shall be a power of two] 526[`ptr` shall be mutable]]]] 527[[Effects] 528[`ptr` may be modified in an implementation specific way to inform the compiler 529of its alignment.]]]]]] 530 531[endsect] 532 533[endsect] 534 535[endsect] 536 537[section Vocabulary] 538 539[heading \[basic.align\]] 540 541Object types have /alignment requirements/ which place restrictions on the 542addresses at which an object of that type may be allocated. An /alignment/ is 543an implementation-defined integer value representing the number of bytes 544between successive addresses at which a given object can be allocated. An 545object type imposes an alignment requirement on every object of that type; 546stricter alignment can be requested using the alignment specifier. 547 548A /fundamental alignment/ is represented by an alignment less than or equal to 549the greatest alignment supported by the implementation in all contexts, which 550is equal to `alignof(std::max_align_t)`. The alignment required for a type 551might be different when it is used as the type of a complete object and when 552it is used as the type of a subobject. 553\[['Example:] 554[ordered_list 555[`struct B { long double d; };`] 556[`struct D : virtual B { char c; };`]] 557When `D` is the type of a complete object, it will have a subobject of type 558`B`, so it must be aligned appropriately for a `long double`. If `D` appears 559as a subobject of another object that also has `B` as a virtual base class, 560the `B` subobject might be part of a different subobject, reducing the 561alignment requirements on the `D` subobject. \u2014['end example]\] The result 562of the `alignof` operator reflects the alignment requirement of the type in 563the complete-object case. 564 565An /extended alignment/ is represented by an alignment greater than 566`alignof(std::max_align_t)`. It is implementation-defined whether any extended 567alignments are supported and the contexts in which they are supported. A type 568having an extended alignment requirement is an /over-aligned type/. \[['Note:] 569Every over-aligned type is or contains a class type to which extended 570alignment applies (possibly through a non-static data member). \u2014['end 571note]\] 572 573Alignments are represented as values of the type `std::size_t`. Valid 574alignments include only those values returned by an `alignof` expression for 575the fundamental types plus an additional implementation-defined set of values, 576which may be empty. Every alignment value shall be a non-negative integral 577power of two. 578 579Alignments have an order from /weaker/ to /stronger/ or /stricter/ alignments. 580Stricter alignments have larger alignment values. An address that satisfies an 581alignment requirement also satisfies any weaker valid alignment requirement. 582 583The alignment requirement of a complete type can be queried using an `alignof` 584expression. Furthermore, the types `char`, `signed char`, and `unsigned char` 585shall have the weakest alignment requirement. \[['Note:] This enables the 586character types to be used as the underlying type for an aligned memory area. 587\u2014['end note]\] 588 589Comparing alignments is meaningful and provides the obvious results: 590 591* Two alignments are equal when their numeric values are equal. 592* Two alignments are different when their numeric values are not equal. 593* When an alignment is larger than another it represents a stricter 594 alignment. 595 596\[['Note:] The runtime pointer alignment function can be used to obtain an 597aligned pointer within a buffer; the aligned-storage templates in the library 598can be used to obtain aligned storage. \u2014['end note]\] 599 600If a request for a specific extended alignment in a specific context is not 601supported by an implementation, the program is ill-formed. Additionally, a 602request for runtime allocation of dynamic storage for which the requested 603alignment cannot be honored shall be treated as an allocation failure. 604 605[endsect] 606 607[section Compatibility] 608 609This library has been tested with the following C++ implementations: 610 611[variablelist 612[[Compilers][gcc, clang, msvc, intel]] 613[[Libraries][libstdc++, libc++, dinkumware]] 614[[Systems][linux, windows, osx]] 615[[Platforms][x64, x86, arm]] 616[[Standards][c++98, c++03, c++11, c++14, c++17]]] 617 618[endsect] 619 620[section Acknowledgments] 621 622Thank you to everyone who reviewed the design, code, examples, tests, or 623documentation, including: 624 625* Peter Dimov 626* Andrey Semashev 627* Bjorn Reese 628* Steven Watanabe 629* Antony Polukhin 630* Lars Viklund 631* Michael Spencer 632* Paul A. Bristow 633 634Thank you to Ahmed Charles for serving as the review manager for the formal 635review of the library. 636 637[endsect] 638 639[section History] 640 641[variablelist 642[[Boost 1.61] 643[Functions for aligning up, down, and testing alignment of integral values.]] 644[[Boost 1.59] 645[Joel Falcou and Charly Chevalier contributed the alignment hint macro.]] 646[[Boost 1.56] 647[Glen Fernandes implemented and contributed the Align library to Boost.]]] 648 649[endsect] 650