Bug 1885602 - Part 5: Implement navigating to the SUMO help topic from the menu heade...
[gecko.git] / dom / bindings / Nullable.h
blob2ab2a4e0f072679b733da45bd29a5d5f9f171b8b
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_Nullable_h
8 #define mozilla_dom_Nullable_h
10 #include <ostream>
11 #include <utility>
13 #include "mozilla/Assertions.h"
14 #include "mozilla/Maybe.h"
15 #include "nsTArrayForwardDeclare.h"
17 class nsCycleCollectionTraversalCallback;
19 namespace mozilla::dom {
21 // Support for nullable types
22 template <typename T>
23 struct Nullable {
24 private:
25 Maybe<T> mValue;
27 public:
28 Nullable() : mValue() {}
30 MOZ_IMPLICIT Nullable(const decltype(nullptr)&) : mValue() {}
32 explicit Nullable(const T& aValue) : mValue() { mValue.emplace(aValue); }
34 MOZ_IMPLICIT Nullable(T&& aValue) : mValue() {
35 mValue.emplace(std::move(aValue));
38 Nullable(Nullable<T>&& aOther) : mValue(std::move(aOther.mValue)) {}
40 Nullable(const Nullable<T>& aOther) : mValue(aOther.mValue) {}
42 void operator=(const Nullable<T>& aOther) { mValue = aOther.mValue; }
44 void SetValue(const T& aArgs) {
45 mValue.reset();
46 mValue.emplace(aArgs);
49 void SetValue(T&& aArgs) {
50 mValue.reset();
51 mValue.emplace(std::move(aArgs));
54 // For cases when |T| is some type with nontrivial copy behavior, we may want
55 // to get a reference to our internal copy of T and work with it directly
56 // instead of relying on the copying version of SetValue().
57 T& SetValue() {
58 if (mValue.isNothing()) {
59 mValue.emplace();
61 return mValue.ref();
64 void SetNull() { mValue.reset(); }
66 const T& Value() const { return mValue.ref(); }
68 T& Value() { return mValue.ref(); }
70 bool IsNull() const { return mValue.isNothing(); }
72 bool Equals(const Nullable<T>& aOtherNullable) const {
73 return mValue == aOtherNullable.mValue;
76 bool operator==(const Nullable<T>& aOtherNullable) const {
77 return Equals(aOtherNullable);
80 bool operator!=(const Nullable<T>& aOtherNullable) const {
81 return !Equals(aOtherNullable);
84 friend std::ostream& operator<<(std::ostream& aStream,
85 const Nullable& aNullable) {
86 return aStream << aNullable.mValue;
90 template <typename T>
91 void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
92 Nullable<T>& aNullable, const char* aName,
93 uint32_t aFlags = 0) {
94 if (!aNullable.IsNull()) {
95 ImplCycleCollectionTraverse(aCallback, aNullable.Value(), aName, aFlags);
99 template <typename T>
100 void ImplCycleCollectionUnlink(Nullable<T>& aNullable) {
101 if (!aNullable.IsNull()) {
102 ImplCycleCollectionUnlink(aNullable.Value());
106 } // namespace mozilla::dom
108 #endif /* mozilla_dom_Nullable_h */