// Copyright (c) Facebook, Inc. and its affiliates. // All rights reserved. // // This source code is licensed under the BSD-style license found in the // LICENSE file in the root directory of this source tree. #include #include #include #include #include #include #if defined(__ANDROID__) || defined(_WIN32) || defined(__CYGWIN__) #include #endif template class AlignedAllocator; template class AlignedAllocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef AlignedAllocator other; }; }; template class AlignedAllocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; #if __cplusplus >= 201402L typedef std::true_type propagate_on_container_move_assignment; #endif template struct rebind { typedef AlignedAllocator other; }; public: inline AlignedAllocator() noexcept {} template inline AlignedAllocator( const AlignedAllocator& other) noexcept {} inline size_type max_size() const noexcept { return (std::numeric_limits::max() - size_type(Alignment)) / sizeof(T); } inline pointer address(reference x) const noexcept { return std::addressof(x); } inline const_pointer address(const_reference x) const noexcept { return std::addressof(x); } inline pointer allocate( size_type n, typename AlignedAllocator::const_pointer hint = 0) { #if defined(_WIN32) void* memory = nullptr; memory = _aligned_malloc(n * sizeof(T), Alignment); if (memory == 0) { #if !defined(__GNUC__) && !defined(_MSC_VER) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) throw std::bad_alloc(); #endif } #elif defined(__ANDROID__) || defined(__CYGWIN__) void* memory = memalign(Alignment, n * sizeof(T)); if (memory == 0) { #if !defined(__GNUC__) || defined(__EXCEPTIONS) throw std::bad_alloc(); #endif } #else void* memory = nullptr; if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) { #if !defined(__GNUC__) || defined(__EXCEPTIONS) throw std::bad_alloc(); #endif } #endif return static_cast(memory); } inline void deallocate(pointer p, size_type n) noexcept { #if defined(_WIN32) _aligned_free(static_cast(p)); #else free(static_cast(p)); #endif } template inline void construct(U* p, Args&&... args) { ::new (static_cast(p)) U(std::forward(args)...); } template inline void destroy(U* p) { p->~U(); } };