1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FXCRT_SHARED_COPY_ON_WRITE_H_ 8 #define CORE_FXCRT_SHARED_COPY_ON_WRITE_H_ 9 10 #include "core/fxcrt/fx_system.h" 11 #include "core/fxcrt/retain_ptr.h" 12 13 namespace fxcrt { 14 15 // A shared pointer to an object with Copy on Write semantics that makes it 16 // appear as if all instances were independent. |ObjClass| must implement the 17 // requirements of |Retainable| from retain_ptr.h, and must also provide a 18 // Clone() method. Often this will just call MakeRetain<>(*this) but will need 19 // to be virtual if |ObjClass| is subclassed. 20 template <class ObjClass> 21 class SharedCopyOnWrite { 22 public: SharedCopyOnWrite()23 SharedCopyOnWrite() {} SharedCopyOnWrite(const SharedCopyOnWrite & other)24 SharedCopyOnWrite(const SharedCopyOnWrite& other) 25 : m_pObject(other.m_pObject) {} ~SharedCopyOnWrite()26 ~SharedCopyOnWrite() {} 27 28 template <typename... Args> Emplace(Args...params)29 ObjClass* Emplace(Args... params) { 30 m_pObject = pdfium::MakeRetain<ObjClass>(params...); 31 return m_pObject.Get(); 32 } 33 34 SharedCopyOnWrite& operator=(const SharedCopyOnWrite& that) { 35 if (*this != that) 36 m_pObject = that.m_pObject; 37 return *this; 38 } 39 SetNull()40 void SetNull() { m_pObject.Reset(); } GetObject()41 const ObjClass* GetObject() const { return m_pObject.Get(); } 42 43 template <typename... Args> GetPrivateCopy(Args...params)44 ObjClass* GetPrivateCopy(Args... params) { 45 if (!m_pObject) 46 return Emplace(params...); 47 if (!m_pObject->HasOneRef()) 48 m_pObject = m_pObject->Clone(); 49 return m_pObject.Get(); 50 } 51 52 bool operator==(const SharedCopyOnWrite& that) const { 53 return m_pObject == that.m_pObject; 54 } 55 bool operator!=(const SharedCopyOnWrite& that) const { 56 return !(*this == that); 57 } 58 explicit operator bool() const { return !!m_pObject; } 59 60 private: 61 RetainPtr<ObjClass> m_pObject; 62 }; 63 64 } // namespace fxcrt 65 66 using fxcrt::SharedCopyOnWrite; 67 68 #endif // CORE_FXCRT_SHARED_COPY_ON_WRITE_H_ 69