blob: a5e26b2e23215a3554734a62905c4e9e5ab5d634 [file] [log] [blame]
XNNPACK Teamb455b122019-09-27 18:10:33 -07001// Copyright (c) Facebook, Inc. and its affiliates.
2// All rights reserved.
3//
4// This source code is licensed under the BSD-style license found in the
5// LICENSE file in the root directory of this source tree.
6
Zhi An Ngd90af6f2022-01-10 14:36:26 -08007#pragma once
8
XNNPACK Teamb455b122019-09-27 18:10:33 -07009#include <cstddef>
10#include <limits>
XNNPACK Teamdb2475b2020-12-30 12:02:14 -080011#include <memory>
XNNPACK Teamb455b122019-09-27 18:10:33 -070012#include <type_traits>
13#include <utility>
14
15#include <stdlib.h>
16
Marat Dukhan78583c72020-04-26 22:00:43 -070017#if defined(__ANDROID__) || defined(_WIN32) || defined(__CYGWIN__)
18 #include <malloc.h>
19#endif
20
21
XNNPACK Teamb455b122019-09-27 18:10:33 -070022template <typename T, size_t Alignment>
23class AlignedAllocator;
24
25template <size_t Alignment>
26class AlignedAllocator<void, Alignment> {
27 public:
28 typedef void* pointer;
29 typedef const void* const_pointer;
30 typedef void value_type;
31
32 template <class U>
33 struct rebind {
34 typedef AlignedAllocator<U, Alignment> other;
35 };
36};
37
38template <typename T, size_t Alignment>
39class AlignedAllocator {
40 public:
41 typedef T value_type;
42 typedef T* pointer;
43 typedef const T* const_pointer;
44 typedef T& reference;
45 typedef const T& const_reference;
46 typedef size_t size_type;
47 typedef ptrdiff_t difference_type;
48
49#if __cplusplus >= 201402L
50 typedef std::true_type propagate_on_container_move_assignment;
51#endif
52
53 template <class U>
54 struct rebind {
55 typedef AlignedAllocator<U, Alignment> other;
56 };
57
58 public:
59 inline AlignedAllocator() noexcept {}
60
61 template <class U>
62 inline AlignedAllocator(
63 const AlignedAllocator<U, Alignment>& other) noexcept {}
64
65 inline size_type max_size() const noexcept {
66 return (std::numeric_limits<size_type>::max() - size_type(Alignment)) /
67 sizeof(T);
68 }
69
70 inline pointer address(reference x) const noexcept {
71 return std::addressof(x);
72 }
73
74 inline const_pointer address(const_reference x) const noexcept {
75 return std::addressof(x);
76 }
77
78 inline pointer allocate(
79 size_type n,
80 typename AlignedAllocator<void, Alignment>::const_pointer hint = 0) {
Marat Dukhan78583c72020-04-26 22:00:43 -070081#if defined(_WIN32)
Yasuhiro Matsumoto462be052020-02-29 13:41:14 +090082 void* memory = nullptr;
83 memory = _aligned_malloc(n * sizeof(T), Alignment);
84 if (memory == 0) {
Yasuhiro Matsumotodac1a0e2020-02-29 14:31:49 +090085#if !defined(__GNUC__) && !defined(_MSC_VER) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
Yasuhiro Matsumoto462be052020-02-29 13:41:14 +090086 throw std::bad_alloc();
87#endif
88 }
Marat Dukhan78583c72020-04-26 22:00:43 -070089#elif defined(__ANDROID__) || defined(__CYGWIN__)
90 void* memory = memalign(Alignment, n * sizeof(T));
91 if (memory == 0) {
92#if !defined(__GNUC__) || defined(__EXCEPTIONS)
93 throw std::bad_alloc();
94#endif
95 }
XNNPACK Teamb455b122019-09-27 18:10:33 -070096#else
97 void* memory = nullptr;
98 if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) {
99#if !defined(__GNUC__) || defined(__EXCEPTIONS)
100 throw std::bad_alloc();
101#endif
102 }
103#endif
104 return static_cast<pointer>(memory);
105 }
106
107 inline void deallocate(pointer p, size_type n) noexcept {
Marat Dukhanc2cfb972020-04-13 10:17:06 -0700108#if defined(_WIN32)
109 _aligned_free(static_cast<void*>(p));
110#else
XNNPACK Teamb455b122019-09-27 18:10:33 -0700111 free(static_cast<void*>(p));
Marat Dukhanc2cfb972020-04-13 10:17:06 -0700112#endif
XNNPACK Teamb455b122019-09-27 18:10:33 -0700113 }
114
115 template <class U, class... Args>
116 inline void construct(U* p, Args&&... args) {
117 ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
118 }
119
120 template <class U>
121 inline void destroy(U* p) {
122 p->~U();
123 }
124};