From 0b95042db2e6dab5876abd12ce485fff0a8e08fe Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 21 Sep 2017 15:49:49 -0400 Subject: Rename CFX_RetainPtr to RetainPtr This CL renames CFX_RetainPtr to RetainPtr and places in the fxcrt namespace. Bug: pdfium:898 Change-Id: I8798a9f79cb0840d3f037e8d04937cedd742914e Reviewed-on: https://pdfium-review.googlesource.com/14616 Reviewed-by: Tom Sepez Commit-Queue: dsinclair --- core/fxcrt/retain_ptr.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 core/fxcrt/retain_ptr.h (limited to 'core/fxcrt/retain_ptr.h') diff --git a/core/fxcrt/retain_ptr.h b/core/fxcrt/retain_ptr.h new file mode 100644 index 0000000000..481bfbba56 --- /dev/null +++ b/core/fxcrt/retain_ptr.h @@ -0,0 +1,130 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CORE_FXCRT_RETAIN_PTR_H_ +#define CORE_FXCRT_RETAIN_PTR_H_ + +#include +#include +#include + +#include "core/fxcrt/fx_system.h" + +namespace fxcrt { + +// Used with std::unique_ptr to Release() objects that can't be deleted. +template +struct ReleaseDeleter { + inline void operator()(T* ptr) const { ptr->Release(); } +}; + +// Analogous to base's scoped_refptr. +template +class RetainPtr { + public: + explicit RetainPtr(T* pObj) : m_pObj(pObj) { + if (m_pObj) + m_pObj->Retain(); + } + + RetainPtr() {} + RetainPtr(const RetainPtr& that) : RetainPtr(that.Get()) {} + RetainPtr(RetainPtr&& that) noexcept { Swap(that); } + + // Deliberately implicit to allow returning nullptrs. + // NOLINTNEXTLINE(runtime/explicit) + RetainPtr(std::nullptr_t ptr) {} + + template + RetainPtr(const RetainPtr& that) : RetainPtr(that.Get()) {} + + template + RetainPtr As() const { + return RetainPtr(static_cast(Get())); + } + + void Reset(T* obj = nullptr) { + if (obj) + obj->Retain(); + m_pObj.reset(obj); + } + + T* Get() const { return m_pObj.get(); } + void Swap(RetainPtr& that) { m_pObj.swap(that.m_pObj); } + + // Useful for passing notion of object ownership across a C API. + T* Leak() { return m_pObj.release(); } + void Unleak(T* ptr) { m_pObj.reset(ptr); } + + RetainPtr& operator=(const RetainPtr& that) { + if (*this != that) + Reset(that.Get()); + return *this; + } + + RetainPtr& operator=(RetainPtr&& that) { + m_pObj.reset(that.Leak()); + return *this; + } + + bool operator==(const RetainPtr& that) const { return Get() == that.Get(); } + bool operator!=(const RetainPtr& that) const { return !(*this == that); } + + bool operator<(const RetainPtr& that) const { + return std::less()(Get(), that.Get()); + } + + explicit operator bool() const { return !!m_pObj; } + T& operator*() const { return *m_pObj.get(); } + T* operator->() const { return m_pObj.get(); } + + private: + std::unique_ptr> m_pObj; +}; + +// Trivial implementation - internal ref count with virtual destructor. +class Retainable { + public: + bool HasOneRef() const { return m_nRefCount == 1; } + + protected: + virtual ~Retainable() {} + + private: + template + friend struct ReleaseDeleter; + + template + friend class RetainPtr; + + void Retain() { ++m_nRefCount; } + void Release() { + ASSERT(m_nRefCount > 0); + if (--m_nRefCount == 0) + delete this; + } + + intptr_t m_nRefCount = 0; +}; + +} // namespace fxcrt + +using fxcrt::ReleaseDeleter; +using fxcrt::RetainPtr; +using fxcrt::Retainable; + +namespace pdfium { + +// Helper to make a RetainPtr along the lines of std::make_unique<>(), +// or pdfium::MakeUnique<>(). Arguments are forwarded to T's constructor. +// Classes managed by RetainPtr should have protected (or private) +// constructors, and should friend this function. +template +RetainPtr MakeRetain(Args&&... args) { + return RetainPtr(new T(std::forward(args)...)); +} + +} // namespace pdfium + +#endif // CORE_FXCRT_RETAIN_PTR_H_ -- cgit v1.2.3