Add pdfium::MakeRetain<>() helper function.

Part of the work to get rid of |new|s.  Stripped from a forthcoming CL.

Review-Url: https://codereview.chromium.org/2536973003
diff --git a/core/fxcrt/cfx_retain_ptr.h b/core/fxcrt/cfx_retain_ptr.h
index 883494e..8c7bf28 100644
--- a/core/fxcrt/cfx_retain_ptr.h
+++ b/core/fxcrt/cfx_retain_ptr.h
@@ -6,6 +6,7 @@
 #define CORE_FXCRT_CFX_RETAIN_PTR_H_
 
 #include <memory>
+#include <utility>
 
 #include "core/fxcrt/fx_memory.h"
 
@@ -17,10 +18,13 @@
       m_pObj->Retain();
   }
 
-  CFX_RetainPtr() : CFX_RetainPtr(nullptr) {}
+  CFX_RetainPtr() {}
   CFX_RetainPtr(const CFX_RetainPtr& that) : CFX_RetainPtr(that.Get()) {}
   CFX_RetainPtr(CFX_RetainPtr&& that) { Swap(that); }
 
+  // Deliberately implicit to allow returning nullptrs.
+  CFX_RetainPtr(std::nullptr_t ptr) {}
+
   template <class U>
   CFX_RetainPtr(const CFX_RetainPtr<U>& that) : CFX_RetainPtr(that.Get()) {}
 
@@ -53,4 +57,30 @@
   std::unique_ptr<T, ReleaseDeleter<T>> m_pObj;
 };
 
+// Trivial implementation - internal ref count with virtual destructor.
+class CFX_Retainable {
+ public:
+  void Retain() { ++m_nRefCount; }
+  void Release() {
+    if (--m_nRefCount == 0)
+      delete this;
+  }
+  bool HasOneRef() const { return m_nRefCount == 1; }
+
+ protected:
+  virtual ~CFX_Retainable() {}
+  intptr_t m_nRefCount = 0;
+};
+
+namespace pdfium {
+
+// Helper to make a CFX_RetainPtr along the lines of std::make_unique<>(),
+// or pdfium::MakeUnique<>(). Arguments are forwarded to T's constructor.
+template <typename T, typename... Args>
+CFX_RetainPtr<T> MakeRetain(Args&&... args) {
+  return CFX_RetainPtr<T>(new T(std::forward<Args>(args)...));
+}
+
+}  // namespace pdfium
+
 #endif  // CORE_FXCRT_CFX_RETAIN_PTR_H_
diff --git a/core/fxcrt/cfx_retain_ptr_unittest.cpp b/core/fxcrt/cfx_retain_ptr_unittest.cpp
index aa92e57..692beb8 100644
--- a/core/fxcrt/cfx_retain_ptr_unittest.cpp
+++ b/core/fxcrt/cfx_retain_ptr_unittest.cpp
@@ -213,3 +213,13 @@
   EXPECT_FALSE(null_bool);
   EXPECT_TRUE(obj1_bool);
 }
+
+TEST(fxcrt, RetainPtrMakeRetained) {
+  auto ptr = pdfium::MakeRetain<CFX_Retainable>();
+  EXPECT_TRUE(ptr->HasOneRef());
+  {
+    CFX_RetainPtr<CFX_Retainable> other = ptr;
+    EXPECT_FALSE(ptr->HasOneRef());
+  }
+  EXPECT_TRUE(ptr->HasOneRef());
+}