OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef Optional_h |
| 6 #define Optional_h |
| 7 |
| 8 #include "bindings/core/v8/Dictionary.h" |
| 9 #include "bindings/core/v8/ScriptValue.h" |
| 10 #include "bindings/core/v8/V8StringResource.h" |
| 11 #include "wtf/Assertions.h" |
| 12 |
| 13 namespace blink { |
| 14 |
| 15 template <typename T> |
| 16 inline T defaultValue() |
| 17 { |
| 18 return T(); |
| 19 } |
| 20 |
| 21 template <> |
| 22 inline float defaultValue() |
| 23 { |
| 24 return std::numeric_limits<float>::quiet_NaN(); |
| 25 } |
| 26 |
| 27 template <> |
| 28 inline double defaultValue() |
| 29 { |
| 30 return std::numeric_limits<double>::quiet_NaN(); |
| 31 } |
| 32 |
| 33 template <typename T> |
| 34 class Optional { |
| 35 public: |
| 36 template <typename U> |
| 37 explicit Optional(const U& value, bool isMissing = false) |
| 38 : m_value(value) |
| 39 , m_isMissing(isMissing) { } |
| 40 |
| 41 Optional(const Optional& other) |
| 42 : m_value(other.m_value) |
| 43 , m_isMissing(other.m_isMissing) { } |
| 44 |
| 45 template <typename U> |
| 46 Optional(const Optional<U>& other) |
| 47 : m_value(other.get()) |
| 48 , m_isMissing(other.isMissing()) { } |
| 49 |
| 50 T get() const { return m_isMissing ? defaultValue<T>() : m_value; } |
| 51 bool isMissing() const { return m_isMissing; } |
| 52 |
| 53 operator T() const |
| 54 { |
| 55 return get(); |
| 56 } |
| 57 |
| 58 private: |
| 59 T m_value; |
| 60 bool m_isMissing; |
| 61 }; |
| 62 |
| 63 // Partial specialization that adds conversion from T* to PassRefPtr<T>. |
| 64 template <typename T> |
| 65 class Optional<T*> { |
| 66 public: |
| 67 template <typename U> |
| 68 explicit Optional(U* value, bool isMissing = false) |
| 69 : m_value(value) |
| 70 , m_isMissing(isMissing) |
| 71 { |
| 72 } |
| 73 |
| 74 T* get() const { return m_isMissing ? nullptr : m_value; } |
| 75 bool isMissing() const { return m_isMissing; } |
| 76 |
| 77 operator T*() const |
| 78 { |
| 79 return get(); |
| 80 } |
| 81 operator PassRefPtr<T>() const |
| 82 { |
| 83 return PassRefPtr<T>(get()); |
| 84 } |
| 85 |
| 86 private: |
| 87 T* m_value; |
| 88 bool m_isMissing; |
| 89 }; |
| 90 |
| 91 // Partial specialization that adds conversion from RefPtr<T> to PassRefPtr<T> a
nd T*. |
| 92 template <typename T> |
| 93 class Optional<RefPtr<T> > { |
| 94 public: |
| 95 explicit Optional(T* value, bool isMissing = false) |
| 96 : m_value(value) |
| 97 , m_isMissing(isMissing) |
| 98 { |
| 99 } |
| 100 |
| 101 template <typename U> |
| 102 explicit Optional(const RefPtr<U>& value, bool isMissing = false) |
| 103 : m_value(value) |
| 104 , m_isMissing(isMissing) |
| 105 { |
| 106 } |
| 107 |
| 108 PassRefPtr<T> get() const { return m_isMissing ? nullptr : m_value; } |
| 109 bool isMissing() const { return m_isMissing; } |
| 110 |
| 111 operator PassRefPtr<T>() const |
| 112 { |
| 113 return get(); |
| 114 } |
| 115 operator T*() const |
| 116 { |
| 117 return m_isMissing ? nullptr : m_value.get(); |
| 118 } |
| 119 |
| 120 private: |
| 121 RefPtr<T> m_value; |
| 122 bool m_isMissing; |
| 123 }; |
| 124 |
| 125 // Partial specialization that adds conversion from OwnPtr<T> to PassOwnPtr<T>. |
| 126 // FIXME: This specialization is odd in that it actually holds on to a non-const |
| 127 // reference to the original value, and mutates it. It would be great to avoid |
| 128 // that, e.g. by not passing OwnPtr<> argument from the bindings layer. |
| 129 template <typename T> |
| 130 class Optional<OwnPtr<T> > { |
| 131 public: |
| 132 explicit Optional(OwnPtr<T>& value, bool isMissing = false) |
| 133 : m_value(value) |
| 134 , m_isMissing(isMissing) |
| 135 { |
| 136 } |
| 137 |
| 138 PassOwnPtr<T> get() { return m_isMissing ? PassOwnPtr<T>() : m_value.release
(); } |
| 139 bool isMissing() const { return m_isMissing; } |
| 140 |
| 141 operator PassOwnPtr<T>() |
| 142 { |
| 143 return get(); |
| 144 } |
| 145 |
| 146 private: |
| 147 OwnPtr<T>& m_value; |
| 148 bool m_isMissing; |
| 149 }; |
| 150 |
| 151 // Partial specialization that adds conversion from Member<T> to T*. |
| 152 template <typename T> |
| 153 class Optional<Member<T> > { |
| 154 STACK_ALLOCATED(); |
| 155 public: |
| 156 explicit Optional(T* value, bool isMissing = false) |
| 157 : m_value(value) |
| 158 , m_isMissing(isMissing) |
| 159 { |
| 160 } |
| 161 |
| 162 T* get() { return m_isMissing ? nullptr : m_value.get(); } |
| 163 bool isMissing() const { return m_isMissing; } |
| 164 |
| 165 operator T*() |
| 166 { |
| 167 return get(); |
| 168 } |
| 169 |
| 170 private: |
| 171 Member<T> m_value; |
| 172 bool m_isMissing; |
| 173 }; |
| 174 |
| 175 // Partial specialization that adds conversion from V8StringResource<Mode> to St
ring and AtomicString. |
| 176 template <V8StringResourceMode Mode> |
| 177 class Optional<V8StringResource<Mode> > { |
| 178 public: |
| 179 explicit Optional(const V8StringResource<Mode>& value, bool isMissing = fals
e) |
| 180 : m_value(value) |
| 181 , m_isMissing(isMissing) |
| 182 { |
| 183 } |
| 184 |
| 185 String get() const { return m_isMissing ? String() : m_value; } |
| 186 bool isMissing() const { return m_isMissing; } |
| 187 |
| 188 operator String() const |
| 189 { |
| 190 return get(); |
| 191 } |
| 192 operator AtomicString() const |
| 193 { |
| 194 return m_isMissing ? AtomicString() : m_value; |
| 195 } |
| 196 |
| 197 private: |
| 198 const V8StringResource<Mode>& m_value; |
| 199 bool m_isMissing; |
| 200 }; |
| 201 |
| 202 template <typename T> |
| 203 Optional<T> makeOptionalMissing() |
| 204 { |
| 205 return Optional<T>(defaultValue<T>(), true); |
| 206 } |
| 207 |
| 208 template <typename T> |
| 209 Optional<T> makeOptional(T value, bool isMissing = false) |
| 210 { |
| 211 return Optional<T>(value, isMissing); |
| 212 } |
| 213 |
| 214 template <typename T> |
| 215 Optional<RefPtr<T> > makeOptional(const RefPtr<T>& value, bool isMissing = false
) |
| 216 { |
| 217 return Optional<RefPtr<T> >(value, isMissing); |
| 218 } |
| 219 |
| 220 template <typename T> |
| 221 Optional<OwnPtr<T> > makeOptional(OwnPtr<T>& value, bool isMissing = false) |
| 222 { |
| 223 return Optional<OwnPtr<T> >(value, isMissing); |
| 224 } |
| 225 |
| 226 } // namespace blink |
| 227 |
| 228 #endif // Optional_h |
OLD | NEW |