| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_ |
| #define THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <type_traits> |
| |
| #include "build/build_config.h" |
| #include "third_party/base/base_export.h" |
| #include "third_party/base/bits.h" |
| #include "third_party/base/check.h" |
| |
| #if defined(COMPILER_MSVC) |
| #include <malloc.h> |
| #else |
| #include <stdlib.h> |
| #endif |
| |
| // A runtime sized aligned allocation can be created: |
| // |
| // float* my_array = static_cast<float*>(AlignedAlloc(size, alignment)); |
| // |
| // // ... later, to release the memory: |
| // AlignedFree(my_array); |
| // |
| // Or using unique_ptr: |
| // |
| // std::unique_ptr<float, AlignedFreeDeleter> my_array( |
| // static_cast<float*>(AlignedAlloc(size, alignment))); |
| |
| namespace pdfium { |
| namespace base { |
| |
| // This can be replaced with std::aligned_alloc when we have C++17. |
| // Caveat: std::aligned_alloc requires the size parameter be an integral |
| // multiple of alignment. |
| BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment); |
| |
| inline void AlignedFree(void* ptr) { |
| #if defined(COMPILER_MSVC) |
| _aligned_free(ptr); |
| #else |
| free(ptr); |
| #endif |
| } |
| |
| // Deleter for use with unique_ptr. E.g., use as |
| // std::unique_ptr<Foo, base::AlignedFreeDeleter> foo; |
| struct AlignedFreeDeleter { |
| inline void operator()(void* ptr) const { |
| AlignedFree(ptr); |
| } |
| }; |
| |
| #ifdef __has_builtin |
| #define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned)) |
| #else |
| #define SUPPORTS_BUILTIN_IS_ALIGNED 0 |
| #endif |
| |
| inline bool IsAligned(uintptr_t val, size_t alignment) { |
| // If the compiler supports builtin alignment checks prefer them. |
| #if SUPPORTS_BUILTIN_IS_ALIGNED |
| return __builtin_is_aligned(val, alignment); |
| #else |
| DCHECK(bits::IsPowerOfTwo(alignment)); |
| return (val & (alignment - 1)) == 0; |
| #endif |
| } |
| |
| #undef SUPPORTS_BUILTIN_IS_ALIGNED |
| |
| inline bool IsAligned(void* val, size_t alignment) { |
| return IsAligned(reinterpret_cast<uintptr_t>(val), alignment); |
| } |
| |
| } // namespace base |
| } // namespace pdfium |
| |
| #endif // THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_ |