28
28
#include < memory_resource>
29
29
#include < utility>
30
30
31
- #if defined(_MSC_VER)
32
- #define ALIGNED_ALLOC (size, alignment ) _aligned_malloc(size, alignment)
33
- #define ALIGNED_FREE (ptr ) _aligned_free(ptr)
34
- #else
35
- #define ALIGNED_ALLOC (size, alignment ) aligned_alloc(alignment, size)
36
- #define ALIGNED_FREE (ptr ) free(ptr)
37
- #endif
38
-
39
31
#if defined T_AVX512
40
32
#define ALIGNMENT 64
41
33
#elif defined T_AVX2
42
34
#define ALIGNMENT 32
43
35
#elif defined T_AVX
44
36
#define ALIGNMENT 16
45
37
#else
46
- #define ALIGNMENT 8
38
+ #define ALIGNMENT 16
47
39
#endif
48
40
41
+ inline uint64_t findNextClosestMultiple (uint64_t number) {
42
+ if constexpr (ALIGNMENT == 0 ) {
43
+ return 0 ;
44
+ }
45
+
46
+ uint64_t remainder = number % ALIGNMENT;
47
+ if (remainder == 0 ) {
48
+ return number;
49
+ }
50
+
51
+ uint64_t nextMultiple = number + (ALIGNMENT - remainder );
52
+ return nextMultiple;
53
+ }
54
+
49
55
namespace JsonifierInternal {
50
56
51
- template <typename ValueType> class AlignedAllocator {
57
+ template <typename ValueType> class AlignedAllocator : public std ::pmr::polymorphic_allocator<ValueType> {
52
58
public:
53
59
using value_type = ValueType;
54
60
using pointer = value_type*;
55
61
using size_type = uint64_t ;
62
+ using allocator = std::pmr::polymorphic_allocator<ValueType>;
56
63
57
- inline pointer allocate (size_type n) const {
64
+ inline pointer allocate (size_type n) {
58
65
if (n == 0 ) {
59
66
return nullptr ;
60
67
}
61
- return static_cast <pointer>( ALIGNED_ALLOC ( n * sizeof (ValueType ), ALIGNMENT));
68
+ return static_cast <ValueType*>( allocator::allocate_bytes ( findNextClosestMultiple ( n * sizeof (value_type) ), ALIGNMENT));
62
69
}
63
70
64
- inline void deallocate (pointer p , size_type) const {
65
- if (p ) {
66
- ALIGNED_FREE (p );
71
+ inline void deallocate (pointer ptr , size_type n) {
72
+ if (ptr ) {
73
+ allocator::deallocate_bytes (ptr, findNextClosestMultiple (n * sizeof (value_type)), ALIGNMENT );
67
74
}
68
75
}
69
76
70
- template <typename ... Args> inline void construct (pointer p, Args&&... args) const {
77
+ template <typename ... Args> inline void construct (pointer p, Args&&... args) {
71
78
new (p) value_type (std::forward<Args>(args)...);
72
79
}
73
80
74
- inline void destroy (pointer p) const {
81
+ inline void destroy (pointer p) {
75
82
p->~value_type ();
76
83
}
77
84
};
@@ -81,24 +88,24 @@ namespace JsonifierInternal {
81
88
using value_type = ValueType;
82
89
using pointer = value_type*;
83
90
using size_type = uint64_t ;
84
- using allocator = const AlignedAllocator<value_type>;
85
- using allocator_traits = const std::allocator_traits<allocator>;
91
+ using allocator = AlignedAllocator<value_type>;
92
+ using allocator_traits = std::allocator_traits<allocator>;
86
93
87
94
inline AllocWrapper (){};
88
95
89
- inline pointer allocate (size_type count) const {
96
+ inline pointer allocate (size_type count) {
90
97
return allocator_traits::allocate (*this , count);
91
98
}
92
99
93
- inline void deallocate (pointer ptr, size_type count) const {
100
+ inline void deallocate (pointer ptr, size_type count) {
94
101
allocator_traits::deallocate (*this , ptr, count);
95
102
}
96
103
97
- template <typename ... Args> inline void construct (pointer ptr, Args&&... args) const {
104
+ template <typename ... Args> inline void construct (pointer ptr, Args&&... args) {
98
105
allocator_traits::construct (*this , ptr, std::forward<Args>(args)...);
99
106
}
100
107
101
- inline void destroy (pointer ptr) const {
108
+ inline void destroy (pointer ptr) {
102
109
allocator_traits::destroy (*this , ptr);
103
110
}
104
111
0 commit comments