crashpad/util/stdlib/aligned_allocator.h
Mark Mentovai 8c35d92ae4 Use the C++11-standardized alignof instead of ALIGNOF
Use the standard alignas instead of ALIGNAS in cases where this is
possible too. It’s not currently possible where ALIGNAS may be mixed
with other attributes, although the not-landed
https://codereview.chromium.org/2670873002/ suggests that where ALIGNAS
is mixed with __attribute__((packed)), it’s viable to write “struct
alignas(4) S { /* … */ } __attribute__((packed));”.

This includes an update of mini_chromium to
723e840a2f100a525f7feaad2e93df31d701780a, picking up:

723e840a2f10 Remove ALIGNOF

This tracks upstream https://codereview.chromium.org/2932053002/.

Change-Id: I7ddaf829020ef3be0512f803cecbb7c543294f07
Reviewed-on: https://chromium-review.googlesource.com/533356
Reviewed-by: Scott Graham <scottmg@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2017-06-13 18:33:35 +00:00

141 lines
4.2 KiB
C++

// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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 <stddef.h>
#include <limits>
#include <memory>
#include <new>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "build/build_config.h"
#include "util/stdlib/cxx.h"
#if defined(COMPILER_MSVC) && _MSC_VER < 1900
#define CRASHPAD_NOEXCEPT _NOEXCEPT
#else
#define CRASHPAD_NOEXCEPT noexcept
#endif
namespace crashpad {
namespace internal {
//! \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);
} // namespace internal
//! \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<T>`, 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 <class T, size_t Alignment = alignof(T)>
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 <class U>
struct rebind {
using other = AlignedAllocator<U, Alignment>;
};
AlignedAllocator() CRASHPAD_NOEXCEPT {}
AlignedAllocator(const AlignedAllocator& other) CRASHPAD_NOEXCEPT {}
template <typename U>
AlignedAllocator(const AlignedAllocator<U, Alignment>& other)
CRASHPAD_NOEXCEPT {}
~AlignedAllocator() {}
pointer address(reference x) const CRASHPAD_NOEXCEPT { return &x; }
const_pointer address(const_reference x) const CRASHPAD_NOEXCEPT {
return &x;
}
pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0) {
return reinterpret_cast<pointer>(
internal::AlignedAllocate(Alignment, sizeof(value_type) * n));
}
void deallocate(pointer p, size_type n) { internal::AlignedFree(p); }
size_type max_size() const CRASHPAD_NOEXCEPT {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
#if CXX_LIBRARY_VERSION < 2011
void construct(pointer p, const T& val) {
new (reinterpret_cast<void*>(p)) T(val);
}
#else
template <class U, class... Args>
void construct(U* p, Args&&... args) {
new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
}
#endif
template <class U>
void destroy(U* p) {
p->~U();
}
};
template <class T1, class T2, size_t Alignment>
bool operator==(const AlignedAllocator<T1, Alignment>& lhs,
const AlignedAllocator<T2, Alignment>& rhs) CRASHPAD_NOEXCEPT {
return true;
}
template <class T1, class T2, size_t Alignment>
bool operator!=(const AlignedAllocator<T1, Alignment>& lhs,
const AlignedAllocator<T2, Alignment>& rhs) CRASHPAD_NOEXCEPT {
return false;
}
//! \brief A `std::vector` using AlignedAllocator.
//!
//! This is similar to `std::vector<T>`, 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 <typename T, size_t Alignment = alignof(T)>
using AlignedVector = std::vector<T, AlignedAllocator<T, Alignment>>;
} // namespace crashpad
#undef CRASHPAD_NOEXCEPT
#endif // CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_