xref: /aosp_15_r20/external/pdfium/core/fxcrt/fx_memory_wrappers.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CORE_FXCRT_FX_MEMORY_WRAPPERS_H_
6 #define CORE_FXCRT_FX_MEMORY_WRAPPERS_H_
7 
8 #include <limits>
9 #include <type_traits>
10 #include <utility>
11 
12 #include "core/fxcrt/fx_memory.h"
13 
14 // Used with std::unique_ptr to FX_Free raw memory.
15 struct FxFreeDeleter {
operatorFxFreeDeleter16   inline void operator()(void* ptr) const { FX_Free(ptr); }
17 };
18 
19 // Escape hatch mechanism to allow non_arithmetic types into data partition.
20 template <typename T>
21 struct IsFXDataPartitionException : std::false_type {};
22 
23 // Use with caution. No further checks are made to see if `T` is appropriate
24 // for the Data Partition (e.g. no pointers, strings, vtables, etc.). This
25 // declaration must occur in the top-level namespace.
26 #define FX_DATA_PARTITION_EXCEPTION(T) \
27   template <>                          \
28   struct IsFXDataPartitionException<T> : std::true_type {}
29 
30 // Allocators for mapping STL containers onto Partition Alloc.
31 // Otherwise, replacing e.g. the FX_AllocUninit/FX_Free pairs with STL may
32 // undo some of the nice segregation that we get from PartitionAlloc.
33 template <class T, void* Alloc(size_t, size_t), void Free(void*)>
34 struct FxPartitionAllocAllocator {
35  public:
36 #if !defined(COMPILER_MSVC) || defined(NDEBUG)
37   static_assert(std::is_arithmetic<T>::value || std::is_enum<T>::value ||
38                     IsFXDataPartitionException<T>::value,
39                 "Only numeric types allowed in this partition");
40 #endif
41 
42   using value_type = T;
43   using pointer = T*;
44   using const_pointer = const T*;
45   using reference = T&;
46   using const_reference = const T&;
47   using size_type = size_t;
48   using difference_type = ptrdiff_t;
49 
50   template <class U>
51   struct rebind {
52     using other = FxPartitionAllocAllocator<U, Alloc, Free>;
53   };
54 
55   FxPartitionAllocAllocator() noexcept = default;
56   FxPartitionAllocAllocator(const FxPartitionAllocAllocator& other) noexcept =
57       default;
58   ~FxPartitionAllocAllocator() = default;
59 
60   template <typename U>
FxPartitionAllocAllocatorFxPartitionAllocAllocator61   FxPartitionAllocAllocator(
62       const FxPartitionAllocAllocator<U, Alloc, Free>& other) noexcept {}
63 
addressFxPartitionAllocAllocator64   pointer address(reference x) const noexcept { return &x; }
addressFxPartitionAllocAllocator65   const_pointer address(const_reference x) const noexcept { return &x; }
66   pointer allocate(size_type n, const void* hint = 0) {
67     return static_cast<pointer>(Alloc(n, sizeof(value_type)));
68   }
deallocateFxPartitionAllocAllocator69   void deallocate(pointer p, size_type n) { Free(p); }
max_sizeFxPartitionAllocAllocator70   size_type max_size() const noexcept {
71     return std::numeric_limits<size_type>::max() / sizeof(value_type);
72   }
73 
74   template <class U, class... Args>
constructFxPartitionAllocAllocator75   void construct(U* p, Args&&... args) {
76     new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
77   }
78 
79   template <class U>
destroyFxPartitionAllocAllocator80   void destroy(U* p) {
81     p->~U();
82   }
83 
84   // There's no state, so they are all the same,
85   bool operator==(const FxPartitionAllocAllocator& that) { return true; }
86   bool operator!=(const FxPartitionAllocAllocator& that) { return false; }
87 };
88 
89 // Used to put backing store for std::vector<> and such into the
90 // general partition, ensuring they contain data only.
91 template <typename T,
92           typename = std::enable_if_t<std::is_arithmetic<T>::value ||
93                                       std::is_enum<T>::value ||
94                                       IsFXDataPartitionException<T>::value>>
95 using FxAllocAllocator = FxPartitionAllocAllocator<T,
96                                                    pdfium::internal::AllocOrDie,
97                                                    pdfium::internal::Dealloc>;
98 
99 // Used to put backing store for std::string<> and std::ostringstream<>
100 // into the string partition.
101 template <typename T>
102 using FxStringAllocator =
103     FxPartitionAllocAllocator<T,
104                               pdfium::internal::StringAllocOrDie,
105                               pdfium::internal::StringDealloc>;
106 
107 #endif  // CORE_FXCRT_FX_MEMORY_WRAPPERS_H_
108