Bug 1753131 - Dispatch devicechange events even without an actively capturing MediaSt...
[gecko.git] / js / src / vm / SharedMem.h
blobdcb74da84671e63a76e5639f6842052b62f4a925
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/. */
7 #ifndef vm_SharedMem_h
8 #define vm_SharedMem_h
10 #include "mozilla/Assertions.h"
12 #include <type_traits>
14 template <typename T>
15 class SharedMem {
16 static_assert(std::is_pointer_v<T>, "SharedMem encapsulates pointer types");
18 enum Sharedness { IsUnshared, IsShared };
20 T ptr_;
21 #ifdef DEBUG
22 Sharedness sharedness_;
23 #endif
25 SharedMem(T ptr, Sharedness sharedness)
26 : ptr_(ptr)
27 #ifdef DEBUG
29 sharedness_(sharedness)
30 #endif
34 public:
35 // Create a SharedMem<T> that is an unshared nullptr.
36 SharedMem()
37 : ptr_(nullptr)
38 #ifdef DEBUG
40 sharedness_(IsUnshared)
41 #endif
45 // Create a SharedMem<T> that's shared/unshared in the same way as
46 // "forSharedness".
47 SharedMem(T ptr, const SharedMem& forSharedness)
48 : ptr_(ptr)
49 #ifdef DEBUG
51 sharedness_(forSharedness.sharedness_)
52 #endif
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) {
67 ptr_ = that.ptr_;
68 #ifdef DEBUG
69 sharedness_ = that.sharedness_;
70 #endif
71 return *this;
74 // Reinterpret-cast the pointer to type U, preserving sharedness.
75 // Eg, "obj->dataPointerEither().cast<uint8_t*>()" yields a
76 // SharedMem<uint8_t*>.
77 template <typename U>
78 inline SharedMem<U> cast() const {
79 #ifdef DEBUG
80 MOZ_ASSERT(
81 asValue() %
82 sizeof(std::conditional_t<std::is_void_v<std::remove_pointer_t<U>>,
83 char, std::remove_pointer_t<U>>) ==
84 0);
85 if (sharedness_ == IsUnshared) {
86 return SharedMem<U>::unshared(unwrap());
88 #endif
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++() {
99 ptr_++;
100 return *this;
103 SharedMem operator++(int) {
104 SharedMem<T> result(*this);
105 ptr_++;
106 return result;
109 SharedMem operator--() {
110 ptr_--;
111 return *this;
114 SharedMem operator--(int) {
115 SharedMem<T> result(*this);
116 ptr_--;
117 return result;
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
123 // places.
124 SharedMem addBytes(size_t nbytes) {
125 MOZ_ASSERT(
126 nbytes %
127 sizeof(std::conditional_t<std::is_void_v<std::remove_pointer_t<T>>,
128 char, std::remove_pointer_t<T>>) ==
130 return SharedMem(
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);
138 return ptr_;
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