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