forked from google/XNNPACK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAlignedAllocator.h
121 lines (102 loc) · 2.9 KB
/
AlignedAllocator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright (c) Facebook, Inc. and its affiliates.
// All rights reserved.
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
#include <cstddef>
#include <limits>
#include <type_traits>
#include <utility>
#include <stdlib.h>
#if defined(__ANDROID__) || defined(_WIN32) || defined(__CYGWIN__)
#include <malloc.h>
#endif
template <typename T, size_t Alignment>
class AlignedAllocator;
template <size_t Alignment>
class AlignedAllocator<void, Alignment> {
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class U>
struct rebind {
typedef AlignedAllocator<U, Alignment> other;
};
};
template <typename T, size_t Alignment>
class AlignedAllocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus >= 201402L
typedef std::true_type propagate_on_container_move_assignment;
#endif
template <class U>
struct rebind {
typedef AlignedAllocator<U, Alignment> other;
};
public:
inline AlignedAllocator() noexcept {}
template <class U>
inline AlignedAllocator(
const AlignedAllocator<U, Alignment>& other) noexcept {}
inline size_type max_size() const noexcept {
return (std::numeric_limits<size_type>::max() - size_type(Alignment)) /
sizeof(T);
}
inline pointer address(reference x) const noexcept {
return std::addressof(x);
}
inline const_pointer address(const_reference x) const noexcept {
return std::addressof(x);
}
inline pointer allocate(
size_type n,
typename AlignedAllocator<void, Alignment>::const_pointer hint = 0) {
#if defined(_WIN32)
void* memory = nullptr;
memory = _aligned_malloc(n * sizeof(T), Alignment);
if (memory == 0) {
#if !defined(__GNUC__) && !defined(_MSC_VER) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
throw std::bad_alloc();
#endif
}
#elif defined(__ANDROID__) || defined(__CYGWIN__)
void* memory = memalign(Alignment, n * sizeof(T));
if (memory == 0) {
#if !defined(__GNUC__) || defined(__EXCEPTIONS)
throw std::bad_alloc();
#endif
}
#else
void* memory = nullptr;
if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) {
#if !defined(__GNUC__) || defined(__EXCEPTIONS)
throw std::bad_alloc();
#endif
}
#endif
return static_cast<pointer>(memory);
}
inline void deallocate(pointer p, size_type n) noexcept {
#if defined(_WIN32)
_aligned_free(static_cast<void*>(p));
#else
free(static_cast<void*>(p));
#endif
}
template <class U, class... Args>
inline void construct(U* p, Args&&... args) {
::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
}
template <class U>
inline void destroy(U* p) {
p->~U();
}
};