Bug 1822331 [wpt PR 38990] - [@scope] Enable implicit :scope and relative selectors...
[gecko.git] / dom / ipc / MaybeDiscarded.h
blob32c0dde3b9483b2767602f3e99a999c773532416
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 mozilla_dom_MaybeDiscarded_h
8 #define mozilla_dom_MaybeDiscarded_h
10 #include "mozilla/RefPtr.h"
12 namespace mozilla::dom {
14 // Wrapper type for a WindowContext or BrowsingContext instance which may be
15 // discarded, and thus unavailable in the current process. This type is used to
16 // pass WindowContext and BrowsingContext instances over IPC, as they may be
17 // discarded in the receiving process.
19 // A MaybeDiscarded can generally be implicitly converted to from a
20 // BrowsingContext* or WindowContext*, but requires an explicit check of
21 // |IsDiscarded| and call to |get| to read from.
22 template <typename T>
23 class MaybeDiscarded {
24 public:
25 MaybeDiscarded() = default;
26 MaybeDiscarded(MaybeDiscarded<T>&&) = default;
27 MaybeDiscarded(const MaybeDiscarded<T>&) = default;
29 // Construct from raw pointers and |nullptr|.
30 MOZ_IMPLICIT MaybeDiscarded(T* aRawPtr)
31 : mId(aRawPtr ? aRawPtr->Id() : 0), mPtr(aRawPtr) {}
32 MOZ_IMPLICIT MaybeDiscarded(decltype(nullptr)) {}
34 // Construct from |RefPtr<I>|
35 template <typename I,
36 typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
37 MOZ_IMPLICIT MaybeDiscarded(RefPtr<I>&& aPtr)
38 : mId(aPtr ? aPtr->Id() : 0), mPtr(std::move(aPtr)) {}
39 template <typename I,
40 typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
41 MOZ_IMPLICIT MaybeDiscarded(const RefPtr<I>& aPtr)
42 : mId(aPtr ? aPtr->Id() : 0), mPtr(aPtr) {}
44 // Basic assignment operators.
45 MaybeDiscarded<T>& operator=(const MaybeDiscarded<T>&) = default;
46 MaybeDiscarded<T>& operator=(MaybeDiscarded<T>&&) = default;
47 MaybeDiscarded<T>& operator=(decltype(nullptr)) {
48 mId = 0;
49 mPtr = nullptr;
50 return *this;
52 MaybeDiscarded<T>& operator=(T* aRawPtr) {
53 mId = aRawPtr ? aRawPtr->Id() : 0;
54 mPtr = aRawPtr;
55 return *this;
57 template <typename I>
58 MaybeDiscarded<T>& operator=(const RefPtr<I>& aRhs) {
59 mId = aRhs ? aRhs->Id() : 0;
60 mPtr = aRhs;
61 return *this;
63 template <typename I>
64 MaybeDiscarded<T>& operator=(RefPtr<I>&& aRhs) {
65 mId = aRhs ? aRhs->Id() : 0;
66 mPtr = std::move(aRhs);
67 return *this;
70 // Validate that the value is neither discarded nor null.
71 bool IsNullOrDiscarded() const { return !mPtr || mPtr->IsDiscarded(); }
72 bool IsDiscarded() const { return IsNullOrDiscarded() && !IsNull(); }
73 bool IsNull() const { return mId == 0; }
75 explicit operator bool() const { return !IsNullOrDiscarded(); }
77 // Extract the wrapped |T|. Must not be called on a discarded |T|.
78 T* get() const {
79 MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
80 return mPtr.get();
82 already_AddRefed<T> forget() {
83 MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
84 return mPtr.forget();
87 T* operator->() const {
88 MOZ_ASSERT(!IsNull());
89 return get();
92 // Like "get", but gets the "Canonical" version of the type. This method may
93 // only be called in the parent process.
94 auto get_canonical() const -> decltype(get()->Canonical()) {
95 if (get()) {
96 return get()->Canonical();
97 } else {
98 return nullptr;
102 // The ID for the context wrapped by this MaybeDiscarded. This ID comes from a
103 // remote process, and should generally only be used for logging. A
104 // BrowsingContext with this ID may not exist in the current process.
105 uint64_t ContextId() const { return mId; }
107 // Tries to get the wrapped value, disregarding discarded status.
108 // This may return |nullptr| for a non-null |MaybeDiscarded|, in the case that
109 // the target is no longer available in this process.
110 T* GetMaybeDiscarded() const { return mPtr.get(); }
112 // Clear the value to a discarded state with the given ID.
113 void SetDiscarded(uint64_t aId) {
114 mId = aId;
115 mPtr = nullptr;
118 // Comparison operators required by IPDL
119 bool operator==(const MaybeDiscarded<T>& aRhs) const {
120 return mId == aRhs.mId && mPtr == aRhs.mPtr;
122 bool operator!=(const MaybeDiscarded<T>& aRhs) const {
123 return !operator==(aRhs);
126 private:
127 uint64_t mId = 0;
128 RefPtr<T> mPtr;
131 } // namespace mozilla::dom
133 #endif // mozilla_dom_MaybeDiscarded_h