Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Edit:</strong> I removed the inheritance of <code>std::allocator</code> as suggested by GManNickG and made the alignment parameter a compile time thing.</p> <p>I recently wrote this piece of code. It's not tested as much as I would like it so go on and report errors. :-)</p> <pre><code>enum class Alignment : size_t { Normal = sizeof(void*), SSE = 16, AVX = 32, }; namespace detail { void* allocate_aligned_memory(size_t align, size_t size); void deallocate_aligned_memory(void* ptr) noexcept; } template &lt;typename T, Alignment Align = Alignment::AVX&gt; class AlignedAllocator; template &lt;Alignment Align&gt; class AlignedAllocator&lt;void, Align&gt; { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template &lt;class U&gt; struct rebind { typedef AlignedAllocator&lt;U, Align&gt; other; }; }; template &lt;typename T, Alignment Align&gt; class AlignedAllocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T&amp; reference; typedef const T&amp; const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::true_type propagate_on_container_move_assignment; template &lt;class U&gt; struct rebind { typedef AlignedAllocator&lt;U, Align&gt; other; }; public: AlignedAllocator() noexcept {} template &lt;class U&gt; AlignedAllocator(const AlignedAllocator&lt;U, Align&gt;&amp;) noexcept {} size_type max_size() const noexcept { return (size_type(~0) - size_type(Align)) / sizeof(T); } pointer address(reference x) const noexcept { return std::addressof(x); } const_pointer address(const_reference x) const noexcept { return std::addressof(x); } pointer allocate(size_type n, typename AlignedAllocator&lt;void, Align&gt;::const_pointer = 0) { const size_type alignment = static_cast&lt;size_type&gt;( Align ); void* ptr = detail::allocate_aligned_memory(alignment , n * sizeof(T)); if (ptr == nullptr) { throw std::bad_alloc(); } return reinterpret_cast&lt;pointer&gt;(ptr); } void deallocate(pointer p, size_type) noexcept { return detail::deallocate_aligned_memory(p); } template &lt;class U, class ...Args&gt; void construct(U* p, Args&amp;&amp;... args) { ::new(reinterpret_cast&lt;void*&gt;(p)) U(std::forward&lt;Args&gt;(args)...); } void destroy(pointer p) { p-&gt;~T(); } }; template &lt;typename T, Alignment Align&gt; class AlignedAllocator&lt;const T, Align&gt; { public: typedef T value_type; typedef const T* pointer; typedef const T* const_pointer; typedef const T&amp; reference; typedef const T&amp; const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::true_type propagate_on_container_move_assignment; template &lt;class U&gt; struct rebind { typedef AlignedAllocator&lt;U, Align&gt; other; }; public: AlignedAllocator() noexcept {} template &lt;class U&gt; AlignedAllocator(const AlignedAllocator&lt;U, Align&gt;&amp;) noexcept {} size_type max_size() const noexcept { return (size_type(~0) - size_type(Align)) / sizeof(T); } const_pointer address(const_reference x) const noexcept { return std::addressof(x); } pointer allocate(size_type n, typename AlignedAllocator&lt;void, Align&gt;::const_pointer = 0) { const size_type alignment = static_cast&lt;size_type&gt;( Align ); void* ptr = detail::allocate_aligned_memory(alignment , n * sizeof(T)); if (ptr == nullptr) { throw std::bad_alloc(); } return reinterpret_cast&lt;pointer&gt;(ptr); } void deallocate(pointer p, size_type) noexcept { return detail::deallocate_aligned_memory(p); } template &lt;class U, class ...Args&gt; void construct(U* p, Args&amp;&amp;... args) { ::new(reinterpret_cast&lt;void*&gt;(p)) U(std::forward&lt;Args&gt;(args)...); } void destroy(pointer p) { p-&gt;~T(); } }; template &lt;typename T, Alignment TAlign, typename U, Alignment UAlign&gt; inline bool operator== (const AlignedAllocator&lt;T,TAlign&gt;&amp;, const AlignedAllocator&lt;U, UAlign&gt;&amp;) noexcept { return TAlign == UAlign; } template &lt;typename T, Alignment TAlign, typename U, Alignment UAlign&gt; inline bool operator!= (const AlignedAllocator&lt;T,TAlign&gt;&amp;, const AlignedAllocator&lt;U, UAlign&gt;&amp;) noexcept { return TAlign != UAlign; } </code></pre> <p>The implementation for the actual allocate calls is posix only but you can extent that easily.</p> <pre><code>void* detail::allocate_aligned_memory(size_t align, size_t size) { assert(align &gt;= sizeof(void*)); assert(nail::is_power_of_two(align)); if (size == 0) { return nullptr; } void* ptr = nullptr; int rc = posix_memalign(&amp;ptr, align, size); if (rc != 0) { return nullptr; } return ptr; } void detail::deallocate_aligned_memory(void *ptr) noexcept { return free(ptr); } </code></pre> <p>Needs C++11, btw.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload