blob: ee12481052cb8305d53fcab26f72482616ab42f4 [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 }
80#else
81 void* memory = nullptr;
82 if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) {
83#if !defined(__GNUC__) || defined(__EXCEPTIONS)
84 throw std::bad_alloc();
85#endif
86 }
87#endif
88 return static_cast<pointer>(memory);
89 }
90
91 inline void deallocate(pointer p, size_type n) noexcept {
92 free(static_cast<void*>(p));
93 }
94
95 template <class U, class... Args>
96 inline void construct(U* p, Args&&... args) {
97 ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
98 }
99
100 template <class U>
101 inline void destroy(U* p) {
102 p->~U();
103 }
104};