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