Bug 1732409 let fake:true getUserMedia() parameter override loopback prefs r=jib
[gecko.git] / dom / bindings / Nullable.h
blob3aebe830cb645b6dbd2d5e6bc7a116d20fc9efc4
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 {
20 namespace dom {
22 // Support for nullable types
23 template <typename T>
24 struct Nullable {
25 private:
26 Maybe<T> mValue;
28 public:
29 Nullable() : mValue() {}
31 MOZ_IMPLICIT Nullable(const decltype(nullptr)&) : mValue() {}
33 explicit Nullable(const T& aValue) : mValue() { mValue.emplace(aValue); }
35 MOZ_IMPLICIT Nullable(T&& aValue) : mValue() {
36 mValue.emplace(std::move(aValue));
39 Nullable(Nullable<T>&& aOther) : mValue(std::move(aOther.mValue)) {}
41 Nullable(const Nullable<T>& aOther) : mValue(aOther.mValue) {}
43 void operator=(const Nullable<T>& aOther) { mValue = aOther.mValue; }
45 void SetValue(const T& aArgs) {
46 mValue.reset();
47 mValue.emplace(aArgs);
50 void SetValue(T&& aArgs) {
51 mValue.reset();
52 mValue.emplace(std::move(aArgs));
55 // For cases when |T| is some type with nontrivial copy behavior, we may want
56 // to get a reference to our internal copy of T and work with it directly
57 // instead of relying on the copying version of SetValue().
58 T& SetValue() {
59 if (mValue.isNothing()) {
60 mValue.emplace();
62 return mValue.ref();
65 void SetNull() { mValue.reset(); }
67 const T& Value() const { return mValue.ref(); }
69 T& Value() { return mValue.ref(); }
71 bool IsNull() const { return mValue.isNothing(); }
73 bool Equals(const Nullable<T>& aOtherNullable) const {
74 return mValue == aOtherNullable.mValue;
77 bool operator==(const Nullable<T>& aOtherNullable) const {
78 return Equals(aOtherNullable);
81 bool operator!=(const Nullable<T>& aOtherNullable) const {
82 return !Equals(aOtherNullable);
85 friend std::ostream& operator<<(std::ostream& aStream,
86 const Nullable& aNullable) {
87 return aStream << aNullable.mValue;
91 template <typename T>
92 void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
93 Nullable<T>& aNullable, const char* aName,
94 uint32_t aFlags = 0) {
95 if (!aNullable.IsNull()) {
96 ImplCycleCollectionTraverse(aCallback, aNullable.Value(), aName, aFlags);
100 template <typename T>
101 void ImplCycleCollectionUnlink(Nullable<T>& aNullable) {
102 if (!aNullable.IsNull()) {
103 ImplCycleCollectionUnlink(aNullable.Value());
107 } // namespace dom
108 } // namespace mozilla
110 #endif /* mozilla_dom_Nullable_h */