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.
23 class MaybeDiscarded
{
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>|
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
)) {}
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)) {
52 MaybeDiscarded
<T
>& operator=(T
* aRawPtr
) {
53 mId
= aRawPtr
? aRawPtr
->Id() : 0;
58 MaybeDiscarded
<T
>& operator=(const RefPtr
<I
>& aRhs
) {
59 mId
= aRhs
? aRhs
->Id() : 0;
64 MaybeDiscarded
<T
>& operator=(RefPtr
<I
>&& aRhs
) {
65 mId
= aRhs
? aRhs
->Id() : 0;
66 mPtr
= std::move(aRhs
);
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|.
79 MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
82 already_AddRefed
<T
> forget() {
83 MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
87 T
* operator->() const {
88 MOZ_ASSERT(!IsNull());
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()) {
96 return get()->Canonical();
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
) {
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
);
131 } // namespace mozilla::dom
133 #endif // mozilla_dom_MaybeDiscarded_h