1 // Copyright 2019 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 #ifndef CORE_FXCRT_RETAINED_TREE_NODE_H_ 6 #define CORE_FXCRT_RETAINED_TREE_NODE_H_ 7 8 #include "core/fxcrt/retain_ptr.h" 9 #include "core/fxcrt/tree_node.h" 10 #include "third_party/base/logging.h" 11 12 namespace fxcrt { 13 14 // For DOM/XML-ish trees, where references outside the tree are RetainPtr<T>, 15 // and the parent node also "retains" its children but doesn't always have 16 // a direct pointer to them. 17 template <typename T> 18 class RetainedTreeNode : public TreeNode<T> { 19 public: 20 template <typename U, typename... Args> 21 friend RetainPtr<U> pdfium::MakeRetain(Args&&... args); 22 AppendFirstChild(const RetainPtr<T> & child)23 void AppendFirstChild(const RetainPtr<T>& child) { 24 TreeNode<T>::AppendFirstChild(child.Get()); 25 } 26 AppendLastChild(const RetainPtr<T> & child)27 void AppendLastChild(const RetainPtr<T>& child) { 28 TreeNode<T>::AppendLastChild(child.Get()); 29 } 30 InsertBefore(const RetainPtr<T> & child,T * other)31 void InsertBefore(const RetainPtr<T>& child, T* other) { 32 TreeNode<T>::InsertBefore(child.Get(), other); 33 } 34 InsertAfter(const RetainPtr<T> & child,T * other)35 void InsertAfter(const RetainPtr<T>& child, T* other) { 36 TreeNode<T>::InsertAfter(child.Get(), other); 37 } 38 RemoveChild(const RetainPtr<T> & child)39 void RemoveChild(const RetainPtr<T>& child) { 40 TreeNode<T>::RemoveChild(child.Get()); 41 } 42 RemoveSelfIfParented()43 void RemoveSelfIfParented() { 44 if (T* parent = TreeNode<T>::GetParent()) { 45 parent->TreeNode<T>::RemoveChild( 46 pdfium::WrapRetain(static_cast<T*>(this)).Get()); 47 } 48 } 49 50 protected: 51 RetainedTreeNode() = default; ~RetainedTreeNode()52 ~RetainedTreeNode() override { 53 while (auto* pChild = TreeNode<T>::GetFirstChild()) 54 RemoveChild(pdfium::WrapRetain(pChild)); 55 } 56 57 private: 58 template <typename U> 59 friend struct ReleaseDeleter; 60 61 template <typename U> 62 friend class RetainPtr; 63 64 RetainedTreeNode(const RetainedTreeNode& that) = delete; 65 RetainedTreeNode& operator=(const RetainedTreeNode& that) = delete; 66 Retain()67 void Retain() { ++m_nRefCount; } Release()68 void Release() { 69 ASSERT(m_nRefCount > 0); 70 if (--m_nRefCount == 0 && !TreeNode<T>::GetParent()) 71 delete this; 72 } 73 74 intptr_t m_nRefCount = 0; 75 }; 76 77 } // namespace fxcrt 78 79 using fxcrt::RetainedTreeNode; 80 81 #endif // CORE_FXCRT_RETAINED_TREE_NODE_H_ 82