Index: Source/bindings/core/v8/Optional.h |
diff --git a/Source/bindings/core/v8/Optional.h b/Source/bindings/core/v8/Optional.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dda76797ee86803f87a5826ae1e158dd031dabf2 |
--- /dev/null |
+++ b/Source/bindings/core/v8/Optional.h |
@@ -0,0 +1,228 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef Optional_h |
+#define Optional_h |
+ |
+#include "bindings/core/v8/Dictionary.h" |
+#include "bindings/core/v8/ScriptValue.h" |
+#include "bindings/core/v8/V8StringResource.h" |
+#include "wtf/Assertions.h" |
+ |
+namespace blink { |
+ |
+template <typename T> |
+inline T defaultValue() |
+{ |
+ return T(); |
+} |
+ |
+template <> |
+inline float defaultValue() |
+{ |
+ return std::numeric_limits<float>::quiet_NaN(); |
+} |
+ |
+template <> |
+inline double defaultValue() |
+{ |
+ return std::numeric_limits<double>::quiet_NaN(); |
+} |
+ |
+template <typename T> |
+class Optional { |
+public: |
+ template <typename U> |
+ explicit Optional(const U& value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) { } |
+ |
+ Optional(const Optional& other) |
+ : m_value(other.m_value) |
+ , m_isMissing(other.m_isMissing) { } |
+ |
+ template <typename U> |
+ Optional(const Optional<U>& other) |
+ : m_value(other.get()) |
+ , m_isMissing(other.isMissing()) { } |
+ |
+ T get() const { return m_isMissing ? defaultValue<T>() : m_value; } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator T() const |
+ { |
+ return get(); |
+ } |
+ |
+private: |
+ T m_value; |
+ bool m_isMissing; |
+}; |
+ |
+// Partial specialization that adds conversion from T* to PassRefPtr<T>. |
+template <typename T> |
+class Optional<T*> { |
+public: |
+ template <typename U> |
+ explicit Optional(U* value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ T* get() const { return m_isMissing ? nullptr : m_value; } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator T*() const |
+ { |
+ return get(); |
+ } |
+ operator PassRefPtr<T>() const |
+ { |
+ return PassRefPtr<T>(get()); |
+ } |
+ |
+private: |
+ T* m_value; |
+ bool m_isMissing; |
+}; |
+ |
+// Partial specialization that adds conversion from RefPtr<T> to PassRefPtr<T> and T*. |
+template <typename T> |
+class Optional<RefPtr<T> > { |
+public: |
+ explicit Optional(T* value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ template <typename U> |
+ explicit Optional(const RefPtr<U>& value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ PassRefPtr<T> get() const { return m_isMissing ? nullptr : m_value; } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator PassRefPtr<T>() const |
+ { |
+ return get(); |
+ } |
+ operator T*() const |
+ { |
+ return m_isMissing ? nullptr : m_value.get(); |
+ } |
+ |
+private: |
+ RefPtr<T> m_value; |
+ bool m_isMissing; |
+}; |
+ |
+// Partial specialization that adds conversion from OwnPtr<T> to PassOwnPtr<T>. |
+// FIXME: This specialization is odd in that it actually holds on to a non-const |
+// reference to the original value, and mutates it. It would be great to avoid |
+// that, e.g. by not passing OwnPtr<> argument from the bindings layer. |
+template <typename T> |
+class Optional<OwnPtr<T> > { |
+public: |
+ explicit Optional(OwnPtr<T>& value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ PassOwnPtr<T> get() { return m_isMissing ? PassOwnPtr<T>() : m_value.release(); } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator PassOwnPtr<T>() |
+ { |
+ return get(); |
+ } |
+ |
+private: |
+ OwnPtr<T>& m_value; |
+ bool m_isMissing; |
+}; |
+ |
+// Partial specialization that adds conversion from Member<T> to T*. |
+template <typename T> |
+class Optional<Member<T> > { |
+ STACK_ALLOCATED(); |
+public: |
+ explicit Optional(T* value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ T* get() { return m_isMissing ? nullptr : m_value.get(); } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator T*() |
+ { |
+ return get(); |
+ } |
+ |
+private: |
+ Member<T> m_value; |
+ bool m_isMissing; |
+}; |
+ |
+// Partial specialization that adds conversion from V8StringResource<Mode> to String and AtomicString. |
+template <V8StringResourceMode Mode> |
+class Optional<V8StringResource<Mode> > { |
+public: |
+ explicit Optional(const V8StringResource<Mode>& value, bool isMissing = false) |
+ : m_value(value) |
+ , m_isMissing(isMissing) |
+ { |
+ } |
+ |
+ String get() const { return m_isMissing ? String() : m_value; } |
+ bool isMissing() const { return m_isMissing; } |
+ |
+ operator String() const |
+ { |
+ return get(); |
+ } |
+ operator AtomicString() const |
+ { |
+ return m_isMissing ? AtomicString() : m_value; |
+ } |
+ |
+private: |
+ const V8StringResource<Mode>& m_value; |
+ bool m_isMissing; |
+}; |
+ |
+template <typename T> |
+Optional<T> makeOptionalMissing() |
+{ |
+ return Optional<T>(defaultValue<T>(), true); |
+} |
+ |
+template <typename T> |
+Optional<T> makeOptional(T value, bool isMissing = false) |
+{ |
+ return Optional<T>(value, isMissing); |
+} |
+ |
+template <typename T> |
+Optional<RefPtr<T> > makeOptional(const RefPtr<T>& value, bool isMissing = false) |
+{ |
+ return Optional<RefPtr<T> >(value, isMissing); |
+} |
+ |
+template <typename T> |
+Optional<OwnPtr<T> > makeOptional(OwnPtr<T>& value, bool isMissing = false) |
+{ |
+ return Optional<OwnPtr<T> >(value, isMissing); |
+} |
+ |
+} // namespace blink |
+ |
+#endif // Optional_h |