Bug 1119199 - Rewrite Maybe::emplace with variadic template. r=waldo
authorXidorn Quan <quanxunzhen@gmail.com>
Tue, 13 Jan 2015 10:48:10 +1100
changeset 223420 ea1a96f3a4c0
parent 223419 32e93a36551d
child 223421 aa2eb48a20d9
push id53905
push userxquan@mozilla.com
push dateMon, 12 Jan 2015 23:48:49 +0000
treeherdermozilla-inbound@428abebd41a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1119199
milestone38.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 1119199 - Rewrite Maybe::emplace with variadic template. r=waldo
mfbt/Maybe.h
--- a/mfbt/Maybe.h
+++ b/mfbt/Maybe.h
@@ -322,93 +322,53 @@ public:
   const T& operator*() const
   {
     MOZ_ASSERT(mIsSome);
     return ref();
   }
 
   /* If |isSome()|, runs the provided function or functor on the contents of
    * this Maybe. */
-  template<typename F>
-  void apply(F&& aFunc)
+  template<typename F, typename... Args>
+  void apply(F&& aFunc, Args&&... aArgs)
   {
     if (isSome()) {
-      aFunc(ref());
+      aFunc(ref(), Forward<Args>(aArgs)...);
     }
   }
 
-  template<typename F>
-  void apply(F&& aFunc) const
+  template<typename F, typename... Args>
+  void apply(F&& aFunc, Args&&... aArgs) const
   {
     if (isSome()) {
-      aFunc(ref());
-    }
-  }
-
-  /* Variant of |apply()| that takes an additional argument for the function. */
-  template<typename F, typename A>
-  void apply(F&& aFunc, A&& aArg)
-  {
-    if (isSome()) {
-      aFunc(ref(), Forward<A>(aArg));
-    }
-  }
-
-  template<typename F, typename A>
-  void apply(F&& aFunc, A&& aArg) const
-  {
-    if (isSome()) {
-      aFunc(ref(), Forward<A>(aArg));
+      aFunc(ref(), Forward<Args>(aArgs)...);
     }
   }
 
   /*
    * If |isSome()|, runs the provided function and returns the result wrapped
    * in a Maybe. If |isNothing()|, returns an empty Maybe value.
    */
-  template<typename R>
-  Maybe<R> map(R(*aFunc)(T&))
+  template<typename R, typename... FArgs, typename... Args>
+  Maybe<R> map(R (*aFunc)(T&, FArgs...), Args&&... aArgs)
   {
     if (isSome()) {
       Maybe<R> val;
-      val.emplace(aFunc(ref()));
+      val.emplace(aFunc(ref(), Forward<Args>(aArgs)...));
       return val;
     }
     return Maybe<R>();
   }
 
-  template<typename R>
-  Maybe<R> map(R(*aFunc)(const T&)) const
+  template<typename R, typename... FArgs, typename... Args>
+  Maybe<R> map(R (*aFunc)(const T&, FArgs...), Args&&... aArgs) const
   {
     if (isSome()) {
       Maybe<R> val;
-      val.emplace(aFunc(ref()));
-      return val;
-    }
-    return Maybe<R>();
-  }
-
-  /* Variant of |map()| that takes an additional argument for the function. */
-  template<typename R, typename FA, typename A>
-  Maybe<R> map(R(*aFunc)(T&, FA), A&& aArg)
-  {
-    if (isSome()) {
-      Maybe<R> val;
-      val.emplace(aFunc(ref(), Forward<A>(aArg)));
-      return val;
-    }
-    return Maybe<R>();
-  }
-
-  template<typename R, typename FA, typename A>
-  Maybe<R> map(R(*aFunc)(const T&, FA), A&& aArg) const
-  {
-    if (isSome()) {
-      Maybe<R> val;
-      val.emplace(aFunc(ref(), Forward<A>(aArg)));
+      val.emplace(aFunc(ref(), Forward<Args>(aArgs)...));
       return val;
     }
     return Maybe<R>();
   }
 
   /* If |isSome()|, empties this Maybe and destroys its contents. */
   void reset()
   {
@@ -416,125 +376,22 @@ public:
       ref().~T();
       mIsSome = false;
     }
   }
 
   /*
    * Constructs a T value in-place in this empty Maybe<T>'s storage. The
    * arguments to |emplace()| are the parameters to T's constructor.
-   *
-   * WARNING: You can't pass a literal nullptr to these methods without
-   * hitting GCC 4.4-only (and hence B2G-only) compile errors.
    */
-  void emplace()
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T();
-    mIsSome = true;
-  }
-
-  template<typename T1>
-  void emplace(T1&& t1)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2>
-  void emplace(T1&& t1, T2&& t2)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3>
-  void emplace(T1&& t1, T2&& t2, T3&& t3)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5)
+  template<typename... Args>
+  void emplace(Args&&... aArgs)
   {
     MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5,
-           typename T6>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5, T6&& t6)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5), Forward<T6>(t6));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5,
-           typename T6, typename T7>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5, T6&& t6,
-               T7&& t7)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5), Forward<T6>(t6),
-                              Forward<T7>(t7));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5,
-           typename T6, typename T7, typename T8>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5, T6&& t6,
-               T7&& t7, T8&& t8)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5), Forward<T6>(t6),
-                              Forward<T7>(t7), Forward<T8>(t8));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5,
-           typename T6, typename T7, typename T8, typename T9>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5, T6&& t6,
-               T7&& t7, T8&& t8, T9&& t9)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5), Forward<T6>(t6),
-                              Forward<T7>(t7), Forward<T8>(t8), Forward<T9>(t9));
-    mIsSome = true;
-  }
-
-  template<typename T1, typename T2, typename T3, typename T4, typename T5,
-           typename T6, typename T7, typename T8, typename T9, typename T10>
-  void emplace(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5, T6&& t6,
-               T7&& t7, T8&& t8, T9&& t9, T10&& t10)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (mStorage.addr()) T(Forward<T1>(t1), Forward<T2>(t2), Forward<T3>(t3),
-                              Forward<T4>(t4), Forward<T5>(t5), Forward<T6>(t6),
-                              Forward<T7>(t7), Forward<T8>(t8), Forward<T9>(t9),
-                              Forward<T1>(t10));
+    ::new (mStorage.addr()) T(Forward<Args>(aArgs)...);
     mIsSome = true;
   }
 };
 
 /*
  * Some() creates a Maybe<T> value containing the provided T value. If T has a
  * move constructor, it's used to make this as efficient as possible.
  *