Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : #ifndef __BASE_DEPENDENCY_H__ 7 : #define __BASE_DEPENDENCY_H__ 8 : 9 : #include <boost/intrusive/list.hpp> 10 : #include <boost/iterator/iterator_facade.hpp> 11 : #include "base/util.h" 12 : 13 : template <typename NodeType, typename ObjectType> 14 : class DependencyList; 15 : 16 : template <typename NodeType, typename ObjectType> 17 : class DependencyRef { 18 : public: 19 11958 : explicit DependencyRef(NodeType *self) : self_(self), ptr_(NULL) { } 20 1224325 : DependencyRef(NodeType *self, ObjectType *ptr) 21 1224325 : : self_(self), ptr_(ptr) { 22 1224369 : if (ptr_ != NULL) { 23 838424 : ptr_->DependencyAdd(this); 24 : } 25 1224386 : } 26 : 27 1236858 : ~DependencyRef() { 28 1236858 : if (ptr_ != NULL) { 29 779958 : ptr_->DependencyRemove(this); 30 : } 31 1236858 : } 32 : 33 720955 : void reset(ObjectType *ptr) { 34 720955 : if (ptr_ != NULL) { 35 355412 : ptr_->DependencyRemove(this); 36 : } 37 720955 : ptr_ = ptr; 38 720955 : if (ptr_ != NULL) { 39 353332 : ptr_->DependencyAdd(this); 40 : } 41 720966 : } 42 : 43 210 : void clear() { 44 210 : if (ptr_ != NULL) { 45 210 : ptr_->DependencyRemove(this); 46 : } 47 210 : ptr_ = NULL; 48 210 : } 49 : 50 9546 : ObjectType *get() const { 51 9546 : return ptr_; 52 : } 53 : 54 597 : ObjectType *operator->() const { 55 597 : return ptr_; 56 : } 57 : 58 : private: 59 : friend class DependencyList<NodeType, ObjectType>; 60 : boost::intrusive::list_member_hook<> node_; 61 : NodeType *self_; 62 : ObjectType *ptr_; 63 : DISALLOW_COPY_AND_ASSIGN(DependencyRef); 64 : }; 65 : 66 : template <typename NodeType, typename ObjectType> 67 : class DependencyList { 68 : public: 69 : typedef boost::intrusive::member_hook< 70 : DependencyRef<NodeType, ObjectType>, 71 : boost::intrusive::list_member_hook<>, 72 : &DependencyRef<NodeType, ObjectType>::node_> MemberHook; 73 : typedef boost::intrusive::list< 74 : DependencyRef<NodeType, ObjectType>, MemberHook> List; 75 : 76 : template <typename ValueType, typename IteratorType> 77 : class IteratorBase : public boost::iterator_facade< 78 : IteratorBase<ValueType, IteratorType>, ValueType, 79 : boost::forward_traversal_tag> { 80 : public: 81 3253831 : explicit IteratorBase(const IteratorType &iter) : iter_(iter) { } 82 : private: 83 1133827 : void increment() { ++iter_; } 84 2193800 : bool equal(const IteratorBase &rhs) const { 85 4387600 : return iter_ == rhs.iter_; 86 : } 87 1133822 : ValueType &dereference() const { 88 2267644 : return *(iter_->self_); 89 : } 90 : friend class boost::iterator_core_access; 91 : IteratorType iter_; 92 : }; 93 : typedef IteratorBase<NodeType, typename List::iterator> iterator; 94 : typedef IteratorBase<const NodeType, 95 : typename List::const_iterator> const_iterator; 96 1106177 : DependencyList() { } 97 1106433 : ~DependencyList() { clear(); } 98 : 99 1218561 : void Add(DependencyRef<NodeType, ObjectType> *node) { 100 1218561 : list_.push_back(*node); 101 1218393 : } 102 : 103 1218828 : void Remove(DependencyRef<NodeType, ObjectType> *node) { 104 2437654 : list_.erase(list_.iterator_to(*node)); 105 1218819 : } 106 : 107 1106433 : void clear() { 108 1106507 : while (!list_.empty()) { 109 74 : DependencyRef<NodeType, ObjectType> *node = &list_.front(); 110 74 : node->clear(); 111 : } 112 1106433 : } 113 : 114 : const List &list() const { return list_; } 115 : 116 1060025 : iterator begin() { return iterator(list_.begin()); } 117 2193790 : iterator end() { return iterator(list_.end()); } 118 6 : const_iterator begin() const { 119 6 : return const_iterator(list_.begin()); 120 : } 121 10 : const_iterator end() const { 122 10 : return const_iterator(list_.end()); 123 : } 124 : 125 3452098 : bool empty() const { return list_.empty(); } 126 : 127 : private: 128 : List list_; 129 : DISALLOW_COPY_AND_ASSIGN(DependencyList); 130 : }; 131 : 132 : #define DEPENDENCY_LIST(NodeType, ObjectType, _Member) \ 133 : friend class DependencyRef<NodeType, ObjectType>; \ 134 : void DependencyAdd(DependencyRef<NodeType, ObjectType> *node) { \ 135 : _Member.Add(node); \ 136 : } \ 137 : void DependencyRemove(DependencyRef<NodeType, ObjectType> *node) { \ 138 : _Member.Remove(node); \ 139 : } \ 140 : DependencyList<NodeType, ObjectType> _Member 141 : 142 : #endif