Radium Engine  1.5.20
Loading...
Searching...
No Matches
AlignedAllocator.hpp
1#pragma once
2#include <Core/RaCore.hpp>
3
4#ifdef _WIN32
5# include <malloc.h>
6#elif !defined ARCH_ARM32 && !defined ARCH_ARM64 || defined _WIN32
7# include <mm_malloc.h>
8#endif
9#include <cstddef>
10#include <cstdint>
11#include <cstdlib>
12
13namespace Ra {
14namespace Core {
23template <typename T, std::size_t Alignment>
25{
26 public:
27 // The following will be the same for virtually all allocators.
28 using pointer = T*;
29 using const_pointer = const T*;
30 using reference = T&;
31 using const_reference = const T&;
32 using value_type = T;
33 using size_type = std::size_t;
34 using difference_type = ptrdiff_t;
35
36 T* address( T& r ) const { return &r; }
37
38 const T* address( const T& s ) const { return &s; }
39
40 std::size_t max_size() const {
41 // The following has been carefully written to be independent of
42 // the definition of size_t and to avoid signed/unsigned warnings.
43 return ( static_cast<std::size_t>( 0 ) - static_cast<std::size_t>( 1 ) ) / sizeof( T );
44 }
45
46 // The following must be the same for all allocators.
47 template <typename U>
48 struct rebind {
50 };
51
52 bool operator!=( const AlignedAllocator& other ) const { return !( *this == other ); }
53
54 void construct( T* const p, const T& t ) const {
55 void* const pv = static_cast<void*>( p );
56 new ( pv ) T( t );
57 }
58
59 void destroy( T* const p ) const { p->~T(); }
60
61 // Returns true if and only if storage allocated from *this
62 // can be deallocated from other, and vice versa.
63 // Always returns true for stateless allocators.
64 bool operator==( const AlignedAllocator& /*other*/ ) const { return true; }
65
66 // Default constructor, copy constructor, rebinding constructor, and destructor.
67 // Empty for stateless allocators.
69
71
72 template <typename U>
74
76
77 // The following will be different for each allocator.
78 T* allocate( const std::size_t n ) const {
79 // The return value of allocate(0) is unspecified.
80 // Mallocator returns NULL in order to avoid depending
81 // on malloc(0)'s implementation-defined behavior
82 // (the implementation can define malloc(0) to return NULL,
83 // in which case the bad_alloc check below would fire).
84 // All allocators can return NULL in this case.
85 if ( n == 0 ) { return NULL; }
86
87 // All allocators should contain an integer overflow check.
88 // The Standardization Committee recommends that std::length_error
89 // be thrown in the case of integer overflow.
90 CORE_ASSERT( n <= max_size(), "Integer overflow" );
91
92#if !defined ARCH_ARM32 && !defined ARCH_ARM64 || defined _WIN32
93 void* const pv = _mm_malloc( n * sizeof( T ), Alignment );
94#else
95 void* const pv = aligned_alloc( Alignment, n * sizeof( T ) );
96#endif
97
98 // Allocators should throw std::bad_alloc in the case of memory allocation failure.
99 CORE_ASSERT( pv != NULL, " Bad alloc" );
100 CORE_ASSERT( ( reinterpret_cast<std::size_t>( pv ) & ( Alignment - 1 ) ) == 0,
101 "Alignment constraint not satisfied" );
102
103 return static_cast<T*>( pv );
104 }
105
106 void deallocate( T* const p, const std::size_t /*n*/ ) const {
107#if !defined ARCH_ARM32 && !defined ARCH_ARM64 || defined _WIN32
108 _mm_free( p );
109#else
110 free( p );
111#endif
112 }
113
114 // The following will be the same for all allocators that ignore hints.
115 template <typename U>
116 T* allocate( const std::size_t n, const U* /* const hint */ ) const {
117 return allocate( n );
118 }
119
120 // Allocators are not required to be assignable, so
121 // all allocators should have a private unimplemented
122 // assignment operator. Note that this will trigger the
123 // off-by-default (enabled under /Wall) warning C4626
124 // "assignment operator could not be generated because a
125 // base class assignment operator is inaccessible" within
126 // the STL headers, but that warning is useless.
127 private:
128 AlignedAllocator& operator=( const AlignedAllocator& ) = delete;
129};
130
131} // namespace Core
132} // namespace Ra
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3