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