Line data Source code
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/. */
6 :
7 : #ifndef mozilla_dom_Nullable_h
8 : #define mozilla_dom_Nullable_h
9 :
10 : #include "mozilla/Assertions.h"
11 : #include "nsTArrayForwardDeclare.h"
12 : #include "mozilla/Move.h"
13 : #include "mozilla/Maybe.h"
14 :
15 : #include <ostream>
16 :
17 : class nsCycleCollectionTraversalCallback;
18 :
19 : namespace mozilla {
20 : namespace dom {
21 :
22 : // Support for nullable types
23 : template <typename T>
24 999 : struct Nullable
25 : {
26 : private:
27 : Maybe<T> mValue;
28 :
29 : public:
30 1002 : Nullable()
31 1002 : : mValue()
32 1002 : {}
33 :
34 0 : MOZ_IMPLICIT Nullable(const decltype(nullptr)&)
35 0 : : mValue()
36 0 : {}
37 :
38 0 : explicit Nullable(const T& aValue)
39 0 : : mValue()
40 : {
41 0 : mValue.emplace(aValue);
42 0 : }
43 :
44 3 : MOZ_IMPLICIT Nullable(T&& aValue)
45 3 : : mValue()
46 : {
47 3 : mValue.emplace(mozilla::Move(aValue));
48 3 : }
49 :
50 0 : Nullable(Nullable<T>&& aOther)
51 0 : : mValue(mozilla::Move(aOther.mValue))
52 0 : {}
53 :
54 4 : Nullable(const Nullable<T>& aOther)
55 4 : : mValue(aOther.mValue)
56 4 : {}
57 :
58 422 : void operator=(const Nullable<T>& aOther)
59 : {
60 422 : mValue = aOther.mValue;
61 422 : }
62 :
63 160 : void SetValue(const T& aArgs)
64 : {
65 160 : mValue.reset();
66 160 : mValue.emplace(aArgs);
67 160 : }
68 :
69 210 : void SetValue(T&& aArgs)
70 : {
71 210 : mValue.reset();
72 210 : mValue.emplace(mozilla::Move(aArgs));
73 210 : }
74 :
75 : // For cases when |T| is some type with nontrivial copy behavior, we may want
76 : // to get a reference to our internal copy of T and work with it directly
77 : // instead of relying on the copying version of SetValue().
78 5 : T& SetValue() {
79 5 : if (mValue.isNothing()) {
80 5 : mValue.emplace();
81 : }
82 5 : return mValue.ref();
83 : }
84 :
85 195 : void SetNull() {
86 195 : mValue.reset();
87 195 : }
88 :
89 286 : const T& Value() const {
90 286 : return mValue.ref();
91 : }
92 :
93 152 : T& Value() {
94 152 : return mValue.ref();
95 : }
96 :
97 1265 : bool IsNull() const {
98 1265 : return mValue.isNothing();
99 : }
100 :
101 32 : bool Equals(const Nullable<T>& aOtherNullable) const
102 : {
103 32 : return mValue == aOtherNullable.mValue;
104 : }
105 :
106 0 : bool operator==(const Nullable<T>& aOtherNullable) const
107 : {
108 0 : return Equals(aOtherNullable);
109 : }
110 :
111 32 : bool operator!=(const Nullable<T>& aOtherNullable) const
112 : {
113 32 : return !Equals(aOtherNullable);
114 : }
115 :
116 : friend std::ostream& operator<<(std::ostream& aStream,
117 : const Nullable& aNullable) {
118 : return aStream << aNullable.mValue;
119 : }
120 : };
121 :
122 :
123 : template<typename T>
124 : void
125 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
126 : Nullable<T>& aNullable,
127 : const char* aName,
128 : uint32_t aFlags = 0)
129 : {
130 0 : if (!aNullable.IsNull()) {
131 0 : ImplCycleCollectionTraverse(aCallback, aNullable.Value(), aName, aFlags);
132 : }
133 0 : }
134 :
135 : template<typename T>
136 : void
137 0 : ImplCycleCollectionUnlink(Nullable<T>& aNullable)
138 : {
139 0 : if (!aNullable.IsNull()) {
140 0 : ImplCycleCollectionUnlink(aNullable.Value());
141 : }
142 0 : }
143 :
144 : } // namespace dom
145 : } // namespace mozilla
146 :
147 : #endif /* mozilla_dom_Nullable_h */
|