1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "mozilla/Assertions.h"
12 #include <type_traits>
16 static_assert(std::is_pointer_v
<T
>, "SharedMem encapsulates pointer types");
18 enum Sharedness
{ IsUnshared
, IsShared
};
22 Sharedness sharedness_
;
25 SharedMem(T ptr
, Sharedness sharedness
)
29 sharedness_(sharedness
)
35 // Create a SharedMem<T> that is an unshared nullptr.
40 sharedness_(IsUnshared
)
45 // Create a SharedMem<T> that's shared/unshared in the same way as
47 SharedMem(T ptr
, const SharedMem
& forSharedness
)
51 sharedness_(forSharedness
.sharedness_
)
56 // Create a SharedMem<T> that's marked as shared.
57 static SharedMem
shared(void* p
) {
58 return SharedMem(static_cast<T
>(p
), IsShared
);
61 // Create a SharedMem<T> that's marked as unshared.
62 static SharedMem
unshared(void* p
) {
63 return SharedMem(static_cast<T
>(p
), IsUnshared
);
66 SharedMem
& operator=(const SharedMem
& that
) {
69 sharedness_
= that
.sharedness_
;
74 // Reinterpret-cast the pointer to type U, preserving sharedness.
75 // Eg, "obj->dataPointerEither().cast<uint8_t*>()" yields a
76 // SharedMem<uint8_t*>.
78 inline SharedMem
<U
> cast() const {
82 sizeof(std::conditional_t
<std::is_void_v
<std::remove_pointer_t
<U
>>,
83 char, std::remove_pointer_t
<U
>>) ==
85 if (sharedness_
== IsUnshared
) {
86 return SharedMem
<U
>::unshared(unwrap());
89 return SharedMem
<U
>::shared(unwrap());
92 explicit operator bool() { return ptr_
!= nullptr; }
94 SharedMem
operator+(size_t offset
) { return SharedMem(ptr_
+ offset
, *this); }
96 SharedMem
operator-(size_t offset
) { return SharedMem(ptr_
- offset
, *this); }
98 SharedMem
operator++() {
103 SharedMem
operator++(int) {
104 SharedMem
<T
> result(*this);
109 SharedMem
operator--() {
114 SharedMem
operator--(int) {
115 SharedMem
<T
> result(*this);
120 uintptr_t asValue() const { return reinterpret_cast<uintptr_t>(ptr_
); }
122 // Cast to char*, add nbytes, and cast back to T. Simplifies code in a few
124 SharedMem
addBytes(size_t nbytes
) {
127 sizeof(std::conditional_t
<std::is_void_v
<std::remove_pointer_t
<T
>>,
128 char, std::remove_pointer_t
<T
>>) ==
131 reinterpret_cast<T
>(reinterpret_cast<char*>(ptr_
) + nbytes
), *this);
134 T
unwrap() const { return ptr_
; }
136 T
unwrapUnshared() const {
137 MOZ_ASSERT(sharedness_
== IsUnshared
);
141 uintptr_t unwrapValue() const { return reinterpret_cast<uintptr_t>(ptr_
); }
144 template <typename T
>
145 inline bool operator>=(const SharedMem
<T
>& a
, const SharedMem
<T
>& b
) {
146 return a
.unwrap() >= b
.unwrap();
149 template <typename T
>
150 inline bool operator>=(const void* a
, const SharedMem
<T
>& b
) {
151 return a
>= b
.unwrap();
154 template <typename T
>
155 inline bool operator==(const void* a
, const SharedMem
<T
>& b
) {
156 return a
== b
.unwrap();
159 template <typename T
>
160 inline bool operator==(const SharedMem
<T
>& a
, decltype(nullptr) b
) {
161 return a
.unwrap() == b
;
164 template <typename T
>
165 inline bool operator==(const SharedMem
<T
>& a
, const SharedMem
<T
>& b
) {
166 return a
.unwrap() == b
.unwrap();
169 template <typename T
>
170 inline bool operator!=(const SharedMem
<T
>& a
, decltype(nullptr) b
) {
171 return a
.unwrap() != b
;
174 template <typename T
>
175 inline bool operator!=(const SharedMem
<T
>& a
, const SharedMem
<T
>& b
) {
176 return a
.unwrap() != b
.unwrap();
179 template <typename T
>
180 inline bool operator>(const SharedMem
<T
>& a
, const SharedMem
<T
>& b
) {
181 return a
.unwrap() > b
.unwrap();
184 template <typename T
>
185 inline bool operator>(const void* a
, const SharedMem
<T
>& b
) {
186 return a
> b
.unwrap();
189 template <typename T
>
190 inline bool operator<=(const SharedMem
<T
>& a
, const SharedMem
<T
>& b
) {
191 return a
.unwrap() <= b
.unwrap();
194 template <typename T
>
195 inline bool operator<=(const void* a
, const SharedMem
<T
>& b
) {
196 return a
<= b
.unwrap();
199 template <typename T
>
200 inline bool operator<(const void* a
, const SharedMem
<T
>& b
) {
201 return a
< b
.unwrap();
204 #endif // vm_SharedMem_h