%PDF- %PDF-
| Direktori : /usr/include/xsimd/memory/ |
| Current File : //usr/include/xsimd/memory/xsimd_aligned_stack_buffer.hpp |
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
* Martin Renou *
* Copyright (c) QuantStack *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/
#ifndef XSIMD_ALIGNED_STACK_BUFFER_HPP
#define XSIMD_ALIGNED_STACK_BUFFER_HPP
#include <type_traits>
#include "xsimd_aligned_allocator.hpp"
namespace xsimd
{
template <class T, size_t Align>
class aligned_stack_buffer
{
public:
using allocator = aligned_allocator<T, Align>;
using value_type = typename allocator::value_type;
using pointer = typename allocator::pointer;
using const_pointer = typename allocator::const_pointer;
using reference = typename allocator::reference;
using const_reference = typename allocator::const_reference;
using size_type = typename allocator::size_type;
static constexpr alignment = allocator::alignment;
explicit aligned_stack_buffer(size_type n);
~aligned_stack_buffer();
aligned_stack_buffer(const aligned_stack_buffer&) = delete;
aligned_stack_buffer& operator=(const aligned_stack_buffer&) = delete;
aligned_stack_buffer(aligned_stack_buffer&&) = delete;
aligned_stack_buffer& operator=(aligned_stack_buffer&&) = delete;
size_type size() const noexcept;
reference operator[](size_type);
const_reference operator[](size_type) const;
operator pointer() noexcept;
private:
pointer m_ptr;
size_type m_size;
bool m_heap_allocation;
};
/***************************************
* aligned_stack_buffer implementation *
***************************************/
namespace detail
{
inline void* aligned_alloc_stack(size_t size, size_t alignment)
{
return reinterpret_cast<void*>(
reinterpret_cast<size_t>(XSIMD_ALLOCA(size + alignment)) &
~(size_t(alignment - 1))) +
alignment;
}
}
template <class T, size_t A>
inline aligned_stack_buffer<T, A>::aligned_stack_buffer(size_type n)
: m_size(n)
{
#ifdef XSIMD_ALLOCA
if (sizeof(T) * n <= XSIMD_STACK_ALLOCATION_LIMIT)
{
m_ptr = reinterpret_cast<pointer>(
(reinterpret_cast<size_t>(XSIMD_ALLOCA(n + A)) &
~(size_t(A - 1))) +
A);
m_heap_allocation = false;
}
else
{
m_ptr = reinterpret_cast<pointer>(aligned_malloc(n, A));
m_heap_allocation = true;
}
#else
m_ptr = reinterpret_cast<pointer>(aligned_malloc(n, A));
m_heap_allocation = true;
#endif
}
template <class T, size_t A>
inline aligned_stack_buffer<T, A>::~aligned_stack_buffer()
{
if (!std::is_trivially_destructible<T>::value && m_ptr != 0)
{
for (auto p = m_ptr; p < m_ptr + m_size; ++p)
{
p->~T();
}
}
if (m_heap_allocation)
{
aligned_free(m_ptr);
}
}
template <class T, size_t A>
inline auto aligned_stack_buffer<T, A>::size() const noexcept -> size_type
{
return m_size;
}
template <class T, size_t A>
inline auto
aligned_stack_buffer<T, A>::operator[](size_type i) -> reference
{
return m_ptr[i];
}
template <class T, size_t A>
inline auto
aligned_stack_buffer<T, A>::operator[](size_type i) const -> const_reference
{
return m_ptr[i];
}
template <class T, size_t A>
inline aligned_stack_buffer<T, A>::operator pointer() noexcept
{
return m_ptr;
}
}
#endif