blob: 25337d075d77b53ad7893b21c966a3d88bc8b2ef [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
7#include <cstddef>
8#include <limits>
9#include <type_traits>
10#include <utility>
11
12#include <stdlib.h>
13
14template <typename T, size_t Alignment>
15class AlignedAllocator;
16
17template <size_t Alignment>
18class AlignedAllocator<void, Alignment> {
19 public:
20 typedef void* pointer;
21 typedef const void* const_pointer;
22 typedef void value_type;
23
24 template <class U>
25 struct rebind {
26 typedef AlignedAllocator<U, Alignment> other;
27 };
28};
29
30template <typename T, size_t Alignment>
31class AlignedAllocator {
32 public:
33 typedef T value_type;
34 typedef T* pointer;
35 typedef const T* const_pointer;
36 typedef T& reference;
37 typedef const T& const_reference;
38 typedef size_t size_type;
39 typedef ptrdiff_t difference_type;
40
41#if __cplusplus >= 201402L
42 typedef std::true_type propagate_on_container_move_assignment;
43#endif
44
45 template <class U>
46 struct rebind {
47 typedef AlignedAllocator<U, Alignment> other;
48 };
49
50 public:
51 inline AlignedAllocator() noexcept {}
52
53 template <class U>
54 inline AlignedAllocator(
55 const AlignedAllocator<U, Alignment>& other) noexcept {}
56
57 inline size_type max_size() const noexcept {
58 return (std::numeric_limits<size_type>::max() - size_type(Alignment)) /
59 sizeof(T);
60 }
61
62 inline pointer address(reference x) const noexcept {
63 return std::addressof(x);
64 }
65
66 inline const_pointer address(const_reference x) const noexcept {
67 return std::addressof(x);
68 }
69
70 inline pointer allocate(
71 size_type n,
72 typename AlignedAllocator<void, Alignment>::const_pointer hint = 0) {
73#if defined(__ANDROID__)
74 void* memory = memalign(Alignment, n * sizeof(T));
75 if (memory == 0) {
76#if !defined(__GNUC__) || defined(__EXCEPTIONS)
77 throw std::bad_alloc();
78#endif
79 }
Yasuhiro Matsumoto462be052020-02-29 13:41:14 +090080#elif defined(_WIN32)
81 void* memory = nullptr;
82 memory = _aligned_malloc(n * sizeof(T), Alignment);
83 if (memory == 0) {
Yasuhiro Matsumotodac1a0e2020-02-29 14:31:49 +090084#if !defined(__GNUC__) && !defined(_MSC_VER) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
Yasuhiro Matsumoto462be052020-02-29 13:41:14 +090085 throw std::bad_alloc();
86#endif
87 }
XNNPACK Teamb455b122019-09-27 18:10:33 -070088#else
89 void* memory = nullptr;
90 if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) {
91#if !defined(__GNUC__) || defined(__EXCEPTIONS)
92 throw std::bad_alloc();
93#endif
94 }
95#endif
96 return static_cast<pointer>(memory);
97 }
98
99 inline void deallocate(pointer p, size_type n) noexcept {
100 free(static_cast<void*>(p));
101 }
102
103 template <class U, class... Args>
104 inline void construct(U* p, Args&&... args) {
105 ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
106 }
107
108 template <class U>
109 inline void destroy(U* p) {
110 p->~U();
111 }
112};