Bug 1114701: Replace function pointers with function references, r=keeler
authorBrian Smith <brian@briansmith.org>
Tue, 23 Dec 2014 12:43:25 -0800
changeset 221119 09f9ef6716874a136849fa41c72e3aeb43a88ca6
parent 221118 d8d78db85c5dd9b59edf9fd8a889b200d411482e
child 221120 2f90deb1be159e0559d8b6e97fac20775065e4a8
push id53287
push userbrian@briansmith.org
push dateTue, 23 Dec 2014 22:21:02 +0000
treeherdermozilla-inbound@2f90deb1be15 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1114701
milestone37.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 1114701: Replace function pointers with function references, r=keeler
security/pkix/include/pkix/ScopedPtr.h
security/pkix/include/pkix/bind.h
security/pkix/lib/pkixcert.cpp
--- a/security/pkix/include/pkix/ScopedPtr.h
+++ b/security/pkix/include/pkix/ScopedPtr.h
@@ -26,17 +26,17 @@
 #define mozilla_pkix__ScopedPtr_h
 
 #include "pkix/nullptr.h"
 
 namespace mozilla { namespace pkix {
 
 // Similar to boost::scoped_ptr and std::unique_ptr. Does not support copying
 // or assignment.
-template <typename T, void (*Destroyer)(T*)>
+template <typename T, void (&Destroyer)(T*)>
 class ScopedPtr
 {
 public:
   explicit ScopedPtr(T* value = nullptr) : mValue(value) { }
   ~ScopedPtr()
   {
     if (mValue) {
       Destroyer(mValue);
@@ -68,38 +68,38 @@ public:
 
 protected:
   T* mValue;
 
   ScopedPtr(const ScopedPtr&) /* = delete */;
   void operator=(const ScopedPtr&) /* = delete */;
 };
 
-template <typename T, void(*Destroyer)(T*)>
+template <typename T, void(&Destroyer)(T*)>
 inline bool
 operator==(T* a, const ScopedPtr<T, Destroyer>& b)
 {
   return a == b.get();
 }
 
-template <typename T, void(*Destroyer)(T*)>
+template <typename T, void(&Destroyer)(T*)>
 inline bool
 operator==(const ScopedPtr<T, Destroyer>& a, T* b)
 {
   return a.get() == b;
 }
 
-template <typename T, void(*Destroyer)(T*)>
+template <typename T, void(&Destroyer)(T*)>
 inline bool
 operator!=(T* a, const ScopedPtr<T, Destroyer>& b)
 {
   return a != b.get();
 }
 
-template <typename T, void(*Destroyer)(T*)>
+template <typename T, void(&Destroyer)(T*)>
 inline bool
 operator!=(const ScopedPtr<T, Destroyer>& a, T* b)
 {
   return a.get() != b;
 }
 
 } } // namespace mozilla::pkix
 
--- a/security/pkix/include/pkix/bind.h
+++ b/security/pkix/include/pkix/bind.h
@@ -69,152 +69,161 @@ template <typename V>       V&  ref(V& v
 template <typename V> const V& cref(const V& v) { return v; }
 
 namespace internal {
 
 template <typename R, typename P1, typename B1>
 class Bind1
 {
 public:
-  typedef R (*F)(P1 &, B1 &);
-  Bind1(F f, B1 & b1) : f(f), b1(b1) { }
-  R operator()(P1 & p1) const { return f(p1, b1); }
+  typedef R (&F)(P1&, B1&);
+  Bind1(F f, B1& b1) : f(f), b1(b1) { }
+  R operator()(P1& p1) const { return f(p1, b1); }
 private:
-  const F f;
+  F f;
   B1& b1;
   void operator=(const Bind1&) /*= delete*/;
 };
 
 template <typename R, typename P1, typename B1, typename B2>
 class Bind2
 {
 public:
-  typedef R (*F)(P1&, B1&, B2&);
+  typedef R (&F)(P1&, B1&, B2&);
   Bind2(F f, B1& b1, B2& b2) : f(f), b1(b1), b2(b2) { }
   R operator()(P1& p1) const { return f(p1, b1, b2); }
 private:
-  const F f;
+  F f;
   B1& b1;
   B2& b2;
   void operator=(const Bind2&) /*= delete*/;
 };
 
 template <typename R, typename P1, typename B1, typename B2, typename B3>
 class Bind3
 {
 public:
-  typedef R (*F)(P1&, B1, B2, B3&);
+  typedef R (&F)(P1&, B1, B2, B3&);
   Bind3(F f, B1& b1, B2& b2, B3& b3)
     : f(f), b1(b1), b2(b2), b3(b3) { }
   R operator()(P1& p1) const { return f(p1, b1, b2, b3); }
 private:
-  const F f;
+  F f;
   B1& b1;
   B2& b2;
   B3& b3;
   void operator=(const Bind3&) /*= delete*/;
 };
 
 template <typename R, typename P1, typename B1, typename B2, typename B3,
           typename B4>
 class Bind4
 {
 public:
-  typedef R (*F)(P1&, B1, B2, B3&, B4&);
+  typedef R (&F)(P1&, B1, B2, B3&, B4&);
   Bind4(F f, B1& b1, B2& b2, B3& b3, B4& b4)
     : f(f), b1(b1), b2(b2), b3(b3), b4(b4) { }
   R operator()(P1& p1) const { return f(p1, b1, b2, b3, b4); }
 private:
-  const F f;
+  F f;
   B1& b1;
   B2& b2;
   B3& b3;
   B4& b4;
   void operator=(const Bind4&) /*= delete*/;
 };
 
 template <typename R, typename C1, typename P1, typename P2, typename P3,
           typename P4>
 class BindToMemberFunction4
 {
 public:
+  // XXX: C++ doesn't have reference-to-member function, only
+  // pointer-to-member function, so we can't enforce the non-nullness of f
+  // using the type system.
   typedef R (C1::*F)(P1&, P2&, P3, P4&);
-  BindToMemberFunction4(F f, C1* that) : f(f), that(that) { }
-  R operator()(P1& p1, P2& p2, P3 p3, P4& p4) const { return (that->*f)(p1, p2, p3, p4); }
+  BindToMemberFunction4(F f, C1& that) : f(f), that(that) { }
+  R operator()(P1& p1, P2& p2, P3 p3, P4& p4) const
+  {
+    return (that.*f)(p1, p2, p3, p4);
+  }
 private:
   const F f;
-  C1* const that;
+  C1& that;
   void operator=(const BindToMemberFunction4&) /*= delete*/;
 };
 
 template <typename R, typename P1, typename B1, typename B2, typename B3,
           typename B4, typename B5>
 class Bind5
 {
 public:
-  typedef R (*F)(P1&, B1, B2, B3, B4, B5);
+  typedef R (&F)(P1&, B1, B2, B3, B4, B5);
   Bind5(F f, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5)
     : f(f), b1(b1), b2(b2), b3(b3), b4(b4), b5(b5) { }
   R operator()(P1& p1) const { return f(p1, b1, b2, b3, b4, b5); }
 private:
-  const F f;
+  F f;
   B1 b1;
   B2 b2;
   B3 b3;
   B4 b4;
   B5 b5;
   void operator=(const Bind5&) /*= delete*/;
 };
 
 } // namespace internal
 
 template <typename R, typename P1, typename B1>
 inline internal::Bind1<R, P1, B1>
-bind(R (*f)(P1&, B1&), Placeholder1&, B1& b1)
+bind(R (&f)(P1&, B1&), Placeholder1&, B1& b1)
 {
   return internal::Bind1<R, P1, B1>(f, b1);
 }
 
 template <typename R, typename P1, typename B1, typename B2>
 inline internal::Bind2<R, P1, B1, B2>
-bind(R (*f)(P1&, B1&, B2&), Placeholder1&, B1& b1, B2& b2)
+bind(R (&f)(P1&, B1&, B2&), Placeholder1&, B1& b1, B2& b2)
 {
   return internal::Bind2<R, P1, B1, B2>(f, b1, b2);
 }
 
 template <typename R, typename P1, typename B1, typename B2, typename B3>
 inline internal::Bind3<R, P1, const B1, const B2, B3>
-bind(R (*f)(P1&, B1, B2, B3&), Placeholder1&, const B1& b1, const B2& b2,
+bind(R (&f)(P1&, B1, B2, B3&), Placeholder1&, const B1& b1, const B2& b2,
      B3& b3)
 {
   return internal::Bind3<R, P1, const B1, const B2, B3>(f, b1, b2, b3);
 }
 
 template <typename R, typename P1, typename B1, typename B2, typename B3,
           typename B4>
 inline internal::Bind4<R, P1, const B1, const B2, B3, B4>
-bind(R (*f)(P1&, B1, B2, B3&, B4&), Placeholder1&, const B1& b1, const B2& b2,
+bind(R (&f)(P1&, B1, B2, B3&, B4&), Placeholder1&, const B1& b1, const B2& b2,
      B3& b3, B4& b4)
 {
   return internal::Bind4<R, P1, const B1, const B2, B3, B4>(f, b1, b2, b3, b4);
 }
 
+// XXX: C++ doesn't have reference-to-member function, only
+// pointer-to-member function, so we can't enforce the non-nullness of f
+// using the type system.
 template <typename R, typename C1, typename P1, typename P2, typename P3,
           typename P4>
 inline internal::BindToMemberFunction4<R, C1, P1, P2, P3, P4>
-bind(R (C1::*f)(P1&, P2&, P3, P4&), C1* that, Placeholder1&, Placeholder2&,
-     Placeholder3, Placeholder4&)
+bind(R (C1::*f)(P1&, P2&, P3, P4&), C1& that, Placeholder1&,
+     Placeholder2&, Placeholder3, Placeholder4&)
 {
   return internal::BindToMemberFunction4<R, C1, P1, P2, P3, P4>(f, that);
 }
 
 template <typename R, typename P1, typename B1, typename B2, typename B3,
           typename B4, typename B5>
 inline internal::Bind5<R, P1, B1, B2, B3, B4, B5&>
-bind(R (*f)(P1&, B1, B2, B3, B4, B5&), Placeholder1&, B1 b1, B2 b2, B3 b3,
+bind(R (&f)(P1&, B1, B2, B3, B4, B5&), Placeholder1&, B1 b1, B2 b2, B3 b3,
      B4 b4, B5& b5)
 {
   return internal::Bind5<R, P1, B1, B2, B3, B4, B5&>(f, b1, b2, b3, b4, b5);
 }
 
 #endif
 
 } } // namespace mozilla::pkix
--- a/security/pkix/lib/pkixcert.cpp
+++ b/security/pkix/lib/pkixcert.cpp
@@ -136,17 +136,17 @@ BackCert::Init()
   if (tbsCertificate.Peek(CSC | 2)) {
     rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 2);
     if (rv != Success) {
       return rv;
     }
   }
 
   rv = der::OptionalExtensions(tbsCertificate, CSC | 3,
-                               bind(&BackCert::RememberExtension, this, _1,
+                               bind(&BackCert::RememberExtension, *this, _1,
                                     _2, _3, _4));
   if (rv != Success) {
     return rv;
   }
 
   // The Netscape Certificate Type extension is an obsolete
   // Netscape-proprietary mechanism that we ignore in favor of the standard
   // extensions. However, some CAs have issued certificates with the Netscape