|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ |
|
2 /* vim: set ts=2 sw=2 et tw=79: */ |
|
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 |
|
14 namespace mozilla { |
|
15 namespace dom { |
|
16 |
|
17 // Support for nullable types |
|
18 template <typename T> |
|
19 struct Nullable |
|
20 { |
|
21 private: |
|
22 // mIsNull MUST COME FIRST because otherwise the casting in our array |
|
23 // conversion operators would shift where it is found in the struct. |
|
24 bool mIsNull; |
|
25 T mValue; |
|
26 |
|
27 public: |
|
28 Nullable() |
|
29 : mIsNull(true) |
|
30 {} |
|
31 |
|
32 explicit Nullable(T aValue) |
|
33 : mIsNull(false) |
|
34 , mValue(aValue) |
|
35 {} |
|
36 |
|
37 explicit Nullable(Nullable<T>&& aOther) |
|
38 : mIsNull(aOther.mIsNull) |
|
39 , mValue(mozilla::Move(aOther.mValue)) |
|
40 {} |
|
41 |
|
42 Nullable(const Nullable<T>& aOther) |
|
43 : mIsNull(aOther.mIsNull) |
|
44 , mValue(aOther.mValue) |
|
45 {} |
|
46 |
|
47 void operator=(const Nullable<T>& aOther) |
|
48 { |
|
49 mIsNull = aOther.mIsNull; |
|
50 mValue = aOther.mValue; |
|
51 } |
|
52 |
|
53 void SetValue(T aValue) { |
|
54 mValue = aValue; |
|
55 mIsNull = false; |
|
56 } |
|
57 |
|
58 // For cases when |T| is some type with nontrivial copy behavior, we may want |
|
59 // to get a reference to our internal copy of T and work with it directly |
|
60 // instead of relying on the copying version of SetValue(). |
|
61 T& SetValue() { |
|
62 mIsNull = false; |
|
63 return mValue; |
|
64 } |
|
65 |
|
66 void SetNull() { |
|
67 mIsNull = true; |
|
68 } |
|
69 |
|
70 const T& Value() const { |
|
71 MOZ_ASSERT(!mIsNull); |
|
72 return mValue; |
|
73 } |
|
74 |
|
75 T& Value() { |
|
76 MOZ_ASSERT(!mIsNull); |
|
77 return mValue; |
|
78 } |
|
79 |
|
80 bool IsNull() const { |
|
81 return mIsNull; |
|
82 } |
|
83 |
|
84 bool Equals(const Nullable<T>& aOtherNullable) const |
|
85 { |
|
86 return (mIsNull && aOtherNullable.mIsNull) || |
|
87 (!mIsNull && !aOtherNullable.mIsNull && |
|
88 mValue == aOtherNullable.mValue); |
|
89 } |
|
90 |
|
91 bool operator==(const Nullable<T>& aOtherNullable) const |
|
92 { |
|
93 return Equals(aOtherNullable); |
|
94 } |
|
95 |
|
96 bool operator!=(const Nullable<T>& aOtherNullable) const |
|
97 { |
|
98 return !Equals(aOtherNullable); |
|
99 } |
|
100 |
|
101 // Make it possible to use a const Nullable of an array type with other |
|
102 // array types. |
|
103 template<typename U> |
|
104 operator const Nullable< nsTArray<U> >&() const { |
|
105 // Make sure that T is ok to reinterpret to nsTArray<U> |
|
106 const nsTArray<U>& arr = mValue; |
|
107 (void)arr; |
|
108 return *reinterpret_cast<const Nullable< nsTArray<U> >*>(this); |
|
109 } |
|
110 template<typename U> |
|
111 operator const Nullable< FallibleTArray<U> >&() const { |
|
112 // Make sure that T is ok to reinterpret to FallibleTArray<U> |
|
113 const FallibleTArray<U>& arr = mValue; |
|
114 (void)arr; |
|
115 return *reinterpret_cast<const Nullable< FallibleTArray<U> >*>(this); |
|
116 } |
|
117 }; |
|
118 |
|
119 } // namespace dom |
|
120 } // namespace mozilla |
|
121 |
|
122 #endif /* mozilla_dom_Nullable_h */ |