| // Copyright 2019 The PDFium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CORE_FXCRT_FX_MEMORY_WRAPPERS_H_ |
| #define CORE_FXCRT_FX_MEMORY_WRAPPERS_H_ |
| |
| #include <limits> |
| #include <type_traits> |
| #include <utility> |
| |
| #include "core/fxcrt/fx_memory.h" |
| |
| // Used with std::unique_ptr to FX_Free raw memory. |
| struct FxFreeDeleter { |
| inline void operator()(void* ptr) const { FX_Free(ptr); } |
| }; |
| |
| // Escape hatch mechanism to allow non_arithmetic types into data partition. |
| template <typename T> |
| struct IsFXDataPartitionException : std::false_type {}; |
| |
| // Use with caution. No further checks are made to see if `T` is appropriate |
| // for the Data Partition (e.g. no pointers, strings, vtables, etc.). This |
| // declaration must occur in the top-level namespace. |
| #define FX_DATA_PARTITION_EXCEPTION(T) \ |
| template <> \ |
| struct IsFXDataPartitionException<T> : std::true_type {} |
| |
| // Allocators for mapping STL containers onto Partition Alloc. |
| // Otherwise, replacing e.g. the FX_AllocUninit/FX_Free pairs with STL may |
| // undo some of the nice segregation that we get from PartitionAlloc. |
| template <class T, void* F(size_t, size_t)> |
| struct FxPartitionAllocAllocator { |
| public: |
| #if !defined(COMPILER_MSVC) || defined(NDEBUG) |
| static_assert(std::is_arithmetic<T>::value || std::is_enum<T>::value || |
| IsFXDataPartitionException<T>::value, |
| "Only numeric types allowed in this partition"); |
| #endif |
| |
| 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 = FxPartitionAllocAllocator<U, F>; |
| }; |
| |
| FxPartitionAllocAllocator() noexcept = default; |
| FxPartitionAllocAllocator(const FxPartitionAllocAllocator& other) noexcept = |
| default; |
| ~FxPartitionAllocAllocator() = default; |
| |
| template <typename U> |
| FxPartitionAllocAllocator( |
| const FxPartitionAllocAllocator<U, F>& other) noexcept {} |
| |
| 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 static_cast<pointer>(F(n, sizeof(value_type))); |
| } |
| void deallocate(pointer p, size_type n) { FX_Free(p); } |
| size_type max_size() const noexcept { |
| return std::numeric_limits<size_type>::max() / sizeof(value_type); |
| } |
| |
| template <class U, class... Args> |
| void construct(U* p, Args&&... args) { |
| new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); |
| } |
| |
| template <class U> |
| void destroy(U* p) { |
| p->~U(); |
| } |
| |
| // There's no state, so they are all the same, |
| bool operator==(const FxPartitionAllocAllocator& that) { return true; } |
| bool operator!=(const FxPartitionAllocAllocator& that) { return false; } |
| }; |
| |
| // Used to put backing store for std::vector<> and such into the |
| // general partition, ensuring they contain data only. |
| template <typename T, |
| typename = std::enable_if_t<std::is_arithmetic<T>::value || |
| std::is_enum<T>::value || |
| IsFXDataPartitionException<T>::value>> |
| using FxAllocAllocator = |
| FxPartitionAllocAllocator<T, pdfium::internal::AllocOrDie>; |
| |
| // Used to put backing store for std::string<> and std::ostringstream<> |
| // into the string partition. |
| template <typename T> |
| using FxStringAllocator = |
| FxPartitionAllocAllocator<T, pdfium::internal::StringAllocOrDie>; |
| |
| #endif // CORE_FXCRT_FX_MEMORY_WRAPPERS_H_ |