// Copyright 2015 The Crashpad Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_ #define CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_ #include #include #include #include #include #include namespace crashpad { //! \brief Allocates memory with the specified alignment constraint. //! //! This function wraps `posix_memalign()` or `_aligned_malloc()`. Memory //! allocated by this function must be released by AlignFree(). void* AlignedAllocate(size_t alignment, size_t size); //! \brief Frees memory allocated by AlignedAllocate(). //! //! This function wraps `free()` or `_aligned_free()`. void AlignedFree(void* pointer); //! \brief A standard allocator that aligns its allocations as requested, //! suitable for use as an allocator in standard containers. //! //! This is similar to `std::allocator`, with the addition of an alignment //! guarantee. \a Alignment must be a power of 2. If \a Alignment is not //! specified, the default alignment for type \a T is used. template struct AlignedAllocator { public: using value_type = T; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using size_type = size_t; using difference_type = ptrdiff_t; template struct rebind { using other = AlignedAllocator; }; AlignedAllocator() noexcept {} AlignedAllocator(const AlignedAllocator& other) noexcept {} template AlignedAllocator(const AlignedAllocator& other) noexcept {} ~AlignedAllocator() {} pointer address(reference x) const noexcept { return &x; } const_pointer address(const_reference x) const noexcept { return &x; } pointer allocate(size_type n, const void* hint = 0) { return reinterpret_cast( AlignedAllocate(Alignment, sizeof(value_type) * n)); } void deallocate(pointer p, size_type n) { AlignedFree(p); } size_type max_size() const noexcept { return std::numeric_limits::max() / sizeof(value_type); } template void construct(U* p, Args&&... args) { new (reinterpret_cast(p)) U(std::forward(args)...); } template void destroy(U* p) { p->~U(); } }; template bool operator==(const AlignedAllocator& lhs, const AlignedAllocator& rhs) noexcept { return true; } template bool operator!=(const AlignedAllocator& lhs, const AlignedAllocator& rhs) noexcept { return false; } //! \brief A `std::vector` using AlignedAllocator. //! //! This is similar to `std::vector`, with the addition of an alignment //! guarantee. \a Alignment must be a power of 2. If \a Alignment is not //! specified, the default alignment for type \a T is used. template using AlignedVector = std::vector>; } // namespace crashpad #endif // CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_