1 // Copyright 2023 The Chromium 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 PARTITION_ALLOC_POINTERS_RAW_PTR_NOOP_IMPL_H_ 6 #define PARTITION_ALLOC_POINTERS_RAW_PTR_NOOP_IMPL_H_ 7 8 #include <type_traits> 9 10 #include "partition_alloc/partition_alloc_base/compiler_specific.h" 11 #include "partition_alloc/partition_alloc_forward.h" 12 13 namespace base::internal { 14 15 struct RawPtrNoOpImpl { 16 static constexpr bool kMustZeroOnConstruct = false; 17 static constexpr bool kMustZeroOnMove = false; 18 static constexpr bool kMustZeroOnDestruct = false; 19 20 // Wraps a pointer. 21 template <typename T> WrapRawPtrRawPtrNoOpImpl22 PA_ALWAYS_INLINE static constexpr T* WrapRawPtr(T* ptr) { 23 return ptr; 24 } 25 26 // Notifies the allocator when a wrapped pointer is being removed or 27 // replaced. 28 template <typename T> ReleaseWrappedPtrRawPtrNoOpImpl29 PA_ALWAYS_INLINE static constexpr void ReleaseWrappedPtr(T*) {} 30 31 // Unwraps the pointer, while asserting that memory hasn't been freed. The 32 // function is allowed to crash on nullptr. 33 template <typename T> SafelyUnwrapPtrForDereferenceRawPtrNoOpImpl34 PA_ALWAYS_INLINE static constexpr T* SafelyUnwrapPtrForDereference( 35 T* wrapped_ptr) { 36 return wrapped_ptr; 37 } 38 39 // Unwraps the pointer, while asserting that memory hasn't been freed. The 40 // function must handle nullptr gracefully. 41 template <typename T> SafelyUnwrapPtrForExtractionRawPtrNoOpImpl42 PA_ALWAYS_INLINE static constexpr T* SafelyUnwrapPtrForExtraction( 43 T* wrapped_ptr) { 44 return wrapped_ptr; 45 } 46 47 // Unwraps the pointer, without making an assertion on whether memory was 48 // freed or not. 49 template <typename T> UnsafelyUnwrapPtrForComparisonRawPtrNoOpImpl50 PA_ALWAYS_INLINE static constexpr T* UnsafelyUnwrapPtrForComparison( 51 T* wrapped_ptr) { 52 return wrapped_ptr; 53 } 54 55 // Upcasts the wrapped pointer. 56 template <typename To, typename From> UpcastRawPtrNoOpImpl57 PA_ALWAYS_INLINE static constexpr To* Upcast(From* wrapped_ptr) { 58 static_assert(std::is_convertible_v<From*, To*>, 59 "From must be convertible to To."); 60 // Note, this cast may change the address if upcasting to base that lies 61 // in the middle of the derived object. 62 return wrapped_ptr; 63 } 64 65 // Advance the wrapped pointer by `delta_elems`. 66 template < 67 typename T, 68 typename Z, 69 typename = 70 std::enable_if_t<partition_alloc::internal::is_offset_type<Z>, void>> 71 PA_ALWAYS_INLINE static constexpr T* AdvanceRawPtrNoOpImpl72 Advance(T* wrapped_ptr, Z delta_elems, bool /*is_in_pointer_modification*/) { 73 return wrapped_ptr + delta_elems; 74 } 75 76 // Retreat the wrapped pointer by `delta_elems`. 77 template < 78 typename T, 79 typename Z, 80 typename = 81 std::enable_if_t<partition_alloc::internal::is_offset_type<Z>, void>> 82 PA_ALWAYS_INLINE static constexpr T* RetreatRawPtrNoOpImpl83 Retreat(T* wrapped_ptr, Z delta_elems, bool /*is_in_pointer_modification*/) { 84 return wrapped_ptr - delta_elems; 85 } 86 87 template <typename T> GetDeltaElemsRawPtrNoOpImpl88 PA_ALWAYS_INLINE static constexpr ptrdiff_t GetDeltaElems(T* wrapped_ptr1, 89 T* wrapped_ptr2) { 90 return wrapped_ptr1 - wrapped_ptr2; 91 } 92 93 // Returns a copy of a wrapped pointer, without making an assertion on 94 // whether memory was freed or not. 95 template <typename T> DuplicateRawPtrNoOpImpl96 PA_ALWAYS_INLINE static constexpr T* Duplicate(T* wrapped_ptr) { 97 return wrapped_ptr; 98 } 99 100 // `WrapRawPtrForDuplication` and `UnsafelyUnwrapPtrForDuplication` are used 101 // to create a new raw_ptr<T> from another raw_ptr<T> of a different flavor. 102 template <typename T> WrapRawPtrForDuplicationRawPtrNoOpImpl103 PA_ALWAYS_INLINE static constexpr T* WrapRawPtrForDuplication(T* ptr) { 104 return ptr; 105 } 106 107 template <typename T> UnsafelyUnwrapPtrForDuplicationRawPtrNoOpImpl108 PA_ALWAYS_INLINE static constexpr T* UnsafelyUnwrapPtrForDuplication( 109 T* wrapped_ptr) { 110 return wrapped_ptr; 111 } 112 113 template <typename T> TraceRawPtrNoOpImpl114 static constexpr void Trace([[maybe_unused]] uint64_t owner_id, 115 [[maybe_unused]] T* wrapped_ptr) {} UntraceRawPtrNoOpImpl116 static constexpr void Untrace([[maybe_unused]] uint64_t owner_id) {} 117 118 // This is for accounting only, used by unit tests. IncrementSwapCountForTestRawPtrNoOpImpl119 PA_ALWAYS_INLINE static constexpr void IncrementSwapCountForTest() {} IncrementLessCountForTestRawPtrNoOpImpl120 PA_ALWAYS_INLINE static constexpr void IncrementLessCountForTest() {} 121 }; 122 123 } // namespace base::internal 124 125 #endif // PARTITION_ALLOC_POINTERS_RAW_PTR_NOOP_IMPL_H_ 126