32 #ifndef VSMC_UTILITY_ALIGNED_MEMORY_HPP 33 #define VSMC_UTILITY_ALIGNED_MEMORY_HPP 39 #elif defined(VSMC_MSVC) 44 #include <tbb/scalable_allocator.h> 49 #ifndef VSMC_ALIGNMENT 50 #define VSMC_ALIGNMENT 32 55 #ifndef VSMC_ALIGNMENT_MIN 56 #define VSMC_ALIGNMENT_MIN 16 59 #if VSMC_ALIGNMENT < VSMC_ALIGNMENT_MIN 61 #define VSMC_ALIGNMENT VSMC_ALIGNMENT_MIN 66 #ifndef VSMC_ALIGNED_MEMORY_TYPE 67 #if VSMC_USE_TBB_MALLOC 68 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemoryTBB 69 #elif VSMC_HAS_POSIX || defined(VSMC_MSVC) 70 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySYS 72 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySTD 77 #ifndef VSMC_CONSTRUCT_SCALAR 78 #define VSMC_CONSTRUCT_SCALAR 0 90 #define VSMC_DEFINE_NEW_DELETE(Class) \ 92 static void *operator new(std::size_t n) \ 94 void *ptr = ::vsmc::AlignedMemory::aligned_malloc( \ 95 n, ::vsmc::AlignmentTrait<Class>::value); \ 97 throw std::bad_alloc(); \ 102 static void *operator new[](std::size_t n) \ 104 void *ptr = ::vsmc::AlignedMemory::aligned_malloc( \ 105 n, ::vsmc::AlignmentTrait<Class>::value); \ 106 if (ptr == nullptr) \ 107 throw std::bad_alloc(); \ 112 static void *operator new(std::size_t, void *ptr) { return ptr; } \ 114 static void *operator new[](std::size_t, void *ptr) { return ptr; } \ 116 static void operator delete(void *ptr) \ 118 ::vsmc::AlignedMemory::aligned_free(ptr); \ 121 static void operator delete[](void *ptr) \ 123 ::vsmc::AlignedMemory::aligned_free(ptr); \ 126 static void operator delete(void *, void *) {} \ 128 static void operator delete[](void *, void *) {} 136 template <typename T, bool = std::is_scalar<T>::value>
140 static constexpr std::size_t
value =
144 template <
typename T>
148 static constexpr std::size_t
160 template <
typename T>
162 internal::AlignmentTraitImpl<T>::value>
177 std::size_t bytes = (n > 0 ? n : 1) + alignment +
sizeof(
void *);
181 void *orig_ptr = std::malloc(bytes);
182 if (orig_ptr ==
nullptr)
185 uintptr_t address =
reinterpret_cast<uintptr_t
>(orig_ptr);
186 uintptr_t offset = alignment - (address +
sizeof(
void *)) % alignment;
188 reinterpret_cast<void *
>(address + offset +
sizeof(
void *));
189 void **orig =
reinterpret_cast<void **
>(address + offset);
197 if (ptr !=
nullptr) {
198 std::free(*reinterpret_cast<void **>(
199 reinterpret_cast<uintptr_t>(ptr) -
sizeof(
void *)));
218 if (posix_memalign(&ptr, alignment, n > 0 ? n : 1) != 0)
230 #elif defined(VSMC_MSVC) 235 static void *aligned_malloc(std::size_t n, std::size_t alignment) noexcept
237 return _aligned_malloc(n > 0 ? n : 1, alignment);
240 static void aligned_free(
void *ptr) noexcept
247 #endif // VSMC_HAS_POSIX 259 return scalable_aligned_malloc(n > 0 ? n : 1, alignment);
265 scalable_aligned_free(ptr);
269 #endif // VSMC_HAS_TBB 290 template <typename T, std::size_t Alignment = AlignmentTrait<T>::value,
294 static_assert(Alignment != 0 && (Alignment & (Alignment - 1)) == 0,
295 "**Allocator** USED WITH Alignment OTHER THAN A POWER OF TWO " 298 static_assert(Alignment >=
sizeof(
void *),
299 "**Allocator** USED WITH Alignment LESS THAN sizeof(void *)");
307 using reference =
typename std::add_lvalue_reference<T>::type;
311 template <
typename U>
330 template <
typename U>
332 :
std::allocator<T>(static_cast<
std::allocator<U>>(other))
336 template <
typename U>
338 :
std::allocator<T>(
std::move(static_cast<
std::allocator<U>>(other)))
344 n = std::max(n, static_cast<size_type>(1));
347 throw std::bad_alloc();
350 static_cast<pointer>(Memory::aligned_malloc(bytes, Alignment));
352 throw std::bad_alloc();
360 Memory::aligned_free(ptr);
363 template <
typename U>
366 construct_dispatch(ptr,
368 !std::is_scalar<U>::value)>());
371 template <
typename U,
typename Arg,
typename... Args>
374 std::allocator<T>::construct(
375 ptr, std::forward<Arg>(arg), std::forward<Args>(args)...);
379 template <
typename U>
380 void construct_dispatch(U *ptr, std::true_type)
382 std::allocator<T>::construct(ptr);
385 template <
typename U>
386 void construct_dispatch(U *, std::false_type)
393 template <std::
size_t Alignment,
typename Memory>
396 using value_type = void;
397 using pointer =
void *;
398 using const_pointer =
const void *;
408 template <std::
size_t Alignment,
typename Memory>
411 using value_type =
const void;
412 using pointer =
const void *;
413 using const_pointer =
const void *;
423 template <
typename T1,
typename T2, std::
size_t Alignment,
typename Memory>
432 template <
typename T1,
typename T2, std::
size_t Alignment,
typename Memory>
442 template <
typename Alloc>
444 :
public AlignmentTrait<typename std::allocator_traits<Alloc>::value_type>
448 template <
typename T, std::
size_t Alignment,
typename Memory>
450 :
public std::integral_constant<std::size_t, Alignment>
458 template <
typename T,
typename Alloc = Allocator<T>>
463 template <
typename T, std::size_t N,
465 class alignas(Alignment)
Array :
public std::array<T, N>
467 static_assert(Alignment != 0 && (Alignment & (Alignment - 1)) == 0,
468 "**Array** USED WITH Alignment OTHER THAN A POWER OF TWO " 471 static_assert(Alignment >=
sizeof(
void *),
472 "**Array** USED WITH Alignment LESS THAN sizeof(void *)");
477 #endif // VSMC_UTILITY_ALIGNED_MEMORY_HPP std::vector< T, Alloc > Vector
std::vector with Allocator as default allocator
Aligned memory using std::malloc and std::free
#define VSMC_ALIGNMENT_MIN
The minimum alignment for any type.
Aligned memory using Intel TBB scalable_aligned_malloc and scalable_aligned_free. ...
Allocator(const Allocator< U, Alignment, Memory > &other)
static void aligned_free(void *ptr) noexcept
static void * aligned_malloc(std::size_t n, std::size_t alignment) noexcept
Alignment of a given type.
static constexpr std::size_t value
#define VSMC_ALIGNMENT
The default alignment for scalar type.
bool operator!=(const SingleParticle< T > &sp1, const SingleParticle< T > &sp2)
std::ptrdiff_t difference_type
typename std::add_lvalue_reference< T >::type reference
Aligned memory using native system aligned memory allocation.
static void * aligned_malloc(std::size_t n, std::size_t alignment) noexcept
void deallocate(pointer ptr, size_type=0) noexcept
#define VSMC_CONSTRUCT_SCALAR
Allocator::construct default behavior for scalar type.
std::true_type is_always_equal
bool operator==(const SingleParticle< T > &sp1, const SingleParticle< T > &sp2)
Allocator(Allocator< U, Alignment, Memory > &&other)
void constrct(U *ptr, Arg &&arg, Args &&...args)
static void * aligned_malloc(std::size_t n, std::size_t alignment) noexcept
#define VSMC_ALIGNED_MEMORY_TYPE
Default AlignedMemory type.
std::array with proper alignment
static void aligned_free(void *ptr) noexcept
static void aligned_free(void *ptr) noexcept
pointer allocate(size_type n, const void *=nullptr)
typename std::add_lvalue_reference< const T >::type const_reference