Bug 819523 part 2. Allow Nullable<> of various array types to work sanely. r=jlebar
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 18 Dec 2012 20:16:05 -0500
changeset 125577 51e3f82d820b
parent 125576 6ed3f784cdd3
child 125578 2c74293986cf
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs819523
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 819523 part 2. Allow Nullable<> of various array types to work sanely. r=jlebar
dom/bindings/BindingUtils.h
dom/bindings/Nullable.h
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1365,16 +1365,20 @@ public:
   const T& Value() const {
     return mImpl.ref();
   }
 
   T& Value() {
     return mImpl.ref();
   }
 
+  // If we ever decide to add conversion operators for optional arrays
+  // like the ones Nullable has, we'll need to ensure that Maybe<> has
+  // the boolean before the actual data.
+
 private:
   // Forbid copy-construction and assignment
   Optional(const Optional& other) MOZ_DELETE;
   const Optional &operator=(const Optional &other) MOZ_DELETE;
   
   Maybe<T> mImpl;
 };
 
--- a/dom/bindings/Nullable.h
+++ b/dom/bindings/Nullable.h
@@ -4,35 +4,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Nullable_h
 #define mozilla_dom_Nullable_h
 
 #include "mozilla/Assertions.h"
 
+template<typename E, class Allocator> class nsTArray;
+template<typename E> class InfallibleTArray;
+template<typename E> class FallibleTArray;
+
 namespace mozilla {
 namespace dom {
 
 // Support for nullable types
 template <typename T>
 struct Nullable
 {
 private:
+  // mIsNull MUST COME FIRST because otherwise the casting in our array
+  // conversion operators would shift where it is found in the struct.
+  bool mIsNull;
   T mValue;
-  bool mIsNull;
 
 public:
   Nullable()
     : mIsNull(true)
   {}
 
-  Nullable(T aValue)
-    : mValue(aValue)
-    , mIsNull(false)
+  explicit Nullable(T aValue)
+    : mIsNull(false)
+    , mValue(aValue)
   {}
 
   void SetValue(T aValue) {
     mValue = aValue;
     mIsNull = false;
   }
 
   // For cases when |T| is some type with nontrivial copy behavior, we may want
@@ -55,14 +61,38 @@ public:
   T& Value() {
     MOZ_ASSERT(!mIsNull);
     return mValue;
   }
 
   bool IsNull() const {
     return mIsNull;
   }
+
+  // Make it possible to use a const Nullable of an array type with other
+  // array types.
+  template<typename U, typename Allocator>
+  operator const Nullable< nsTArray<U, Allocator> >&() const {
+    // Make sure that T is ok to reinterpret to nsTArray<U, Allocator>
+    const nsTArray<U, Allocator>& arr = mValue;
+    (void)arr;
+    return *reinterpret_cast<const Nullable< nsTArray<U, Allocator> >*>(this);
+  }
+  template<typename U>
+  operator const Nullable< InfallibleTArray<U> >&() const {
+    // Make sure that T is ok to reinterpret to InfallibleTArray<U>
+    const InfallibleTArray<U>& arr = mValue;
+    (void)arr;
+    return *reinterpret_cast<const Nullable< InfallibleTArray<U> >*>(this);
+  }
+  template<typename U>
+  operator const Nullable< FallibleTArray<U> >&() const {
+    // Make sure that T is ok to reinterpret to FallibleTArray<U>
+    const FallibleTArray<U>& arr = mValue;
+    (void)arr;
+    return *reinterpret_cast<const Nullable< FallibleTArray<U> >*>(this);
+  }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_Nullable_h */