Bug 975246 - Part1 - Implement operator->* in nsRefPtr. r=nfroyd, r=gerald
authorJames Cheng <jacheng@mozilla.com>
Wed, 29 Jul 2015 19:47:00 +0200
changeset 287093 c9d25e716d31e97d801451d8eeedaac3b7664664
parent 287092 17766cdd3de44947323f987e93286e7fb3ce6bab
child 287094 c016da5a123d5f7246901196a085f079d96ac06e
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd, gerald
bugs975246
milestone42.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 975246 - Part1 - Implement operator->* in nsRefPtr. r=nfroyd, r=gerald
mfbt/nsRefPtr.h
--- a/mfbt/nsRefPtr.h
+++ b/mfbt/nsRefPtr.h
@@ -246,29 +246,41 @@ public:
   T*
   operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
   {
     MOZ_ASSERT(mRawPtr != 0,
                "You can't dereference a NULL nsRefPtr with operator->().");
     return get();
   }
 
-  // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
-  // causes internal compiler errors for some MSVC versions.  (It's not
-  // clear to me whether it should be needed.)
-#ifndef _MSC_VER
-  template <class U, class V>
-  U&
-  operator->*(U V::* aMember)
+  template <typename R, typename... Args>
+  class Proxy
+  {
+    typedef R (T::*member_function)(Args...);
+    T* mRawPtr;
+    member_function mFunction;
+  public:
+    Proxy(T* aRawPtr, member_function aFunction)
+      : mRawPtr(aRawPtr),
+        mFunction(aFunction)
+    {
+    }
+    R operator()(Args... aArgs)
+    {
+      return ((*mRawPtr).*mFunction)(mozilla::Forward<Args>(aArgs)...);
+    }
+  };
+
+  template <typename R, typename... Args>
+  Proxy<R, Args...> operator->*(R (T::*aFptr)(Args...)) const
   {
     MOZ_ASSERT(mRawPtr != 0,
                "You can't dereference a NULL nsRefPtr with operator->*().");
-    return get()->*aMember;
+    return Proxy<R, Args...>(get(), aFptr);
   }
-#endif
 
   nsRefPtr<T>*
   get_address()
   // This is not intended to be used by clients.  See |address_of|
   // below.
   {
     return this;
   }