Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef __BASE_DEPENDENCY_H__ 6 : #define __BASE_DEPENDENCY_H__ 7 : 8 : #include <boost/intrusive/list.hpp> 9 : #include <boost/iterator/iterator_facade.hpp> 10 : #include "base/util.h" 11 : 12 : template <typename NodeType, typename ObjectType> 13 : class DependencyList; 14 : 15 : template <typename NodeType, typename ObjectType> 16 : class DependencyRef { 17 : public: 18 5992 : explicit DependencyRef(NodeType *self) : self_(self), ptr_(NULL) { } 19 1216389 : DependencyRef(NodeType *self, ObjectType *ptr) 20 1216389 : : self_(self), ptr_(ptr) { 21 1216474 : if (ptr_ != NULL) { 22 832987 : ptr_->DependencyAdd(this); 23 : } 24 1216492 : } 25 : 26 1222989 : ~DependencyRef() { 27 1222989 : if (ptr_ != NULL) { 28 779460 : ptr_->DependencyRemove(this); 29 : } 30 1222989 : } 31 : 32 714986 : void reset(ObjectType *ptr) { 33 714986 : if (ptr_ != NULL) { 34 353253 : ptr_->DependencyRemove(this); 35 : } 36 714986 : ptr_ = ptr; 37 714986 : if (ptr_ != NULL) { 38 351741 : ptr_->DependencyAdd(this); 39 : } 40 714994 : } 41 : 42 93 : void clear() { 43 93 : if (ptr_ != NULL) { 44 93 : ptr_->DependencyRemove(this); 45 : } 46 93 : ptr_ = NULL; 47 93 : } 48 : 49 2760 : ObjectType *get() const { 50 2760 : return ptr_; 51 : } 52 : 53 6 : ObjectType *operator->() const { 54 6 : return ptr_; 55 : } 56 : 57 : private: 58 : friend class DependencyList<NodeType, ObjectType>; 59 : boost::intrusive::list_member_hook<> node_; 60 : NodeType *self_; 61 : ObjectType *ptr_; 62 : DISALLOW_COPY_AND_ASSIGN(DependencyRef); 63 : }; 64 : 65 : template <typename NodeType, typename ObjectType> 66 : class DependencyList { 67 : public: 68 : typedef boost::intrusive::member_hook< 69 : DependencyRef<NodeType, ObjectType>, 70 : boost::intrusive::list_member_hook<>, 71 : &DependencyRef<NodeType, ObjectType>::node_> MemberHook; 72 : typedef boost::intrusive::list< 73 : DependencyRef<NodeType, ObjectType>, MemberHook> List; 74 : 75 : template <typename ValueType, typename IteratorType> 76 : class IteratorBase : public boost::iterator_facade< 77 : IteratorBase<ValueType, IteratorType>, ValueType, 78 : boost::forward_traversal_tag> { 79 : public: 80 3193765 : explicit IteratorBase(const IteratorType &iter) : iter_(iter) { } 81 : private: 82 1125237 : void increment() { ++iter_; } 83 2159462 : bool equal(const IteratorBase &rhs) const { 84 4318924 : return iter_ == rhs.iter_; 85 : } 86 1125232 : ValueType &dereference() const { 87 2250464 : return *(iter_->self_); 88 : } 89 : friend class boost::iterator_core_access; 90 : IteratorType iter_; 91 : }; 92 : typedef IteratorBase<NodeType, typename List::iterator> iterator; 93 : typedef IteratorBase<const NodeType, 94 : typename List::const_iterator> const_iterator; 95 1040823 : DependencyList() { } 96 1041120 : ~DependencyList() { clear(); } 97 : 98 1209629 : void Add(DependencyRef<NodeType, ObjectType> *node) { 99 1209629 : list_.push_back(*node); 100 1209491 : } 101 : 102 1209996 : void Remove(DependencyRef<NodeType, ObjectType> *node) { 103 2419989 : list_.erase(list_.iterator_to(*node)); 104 1209992 : } 105 : 106 1041120 : void clear() { 107 1041122 : while (!list_.empty()) { 108 2 : DependencyRef<NodeType, ObjectType> *node = &list_.front(); 109 2 : node->clear(); 110 : } 111 1041120 : } 112 : 113 : const List &list() const { return list_; } 114 : 115 1034297 : iterator begin() { return iterator(list_.begin()); } 116 2159452 : iterator end() { return iterator(list_.end()); } 117 6 : const_iterator begin() const { 118 6 : return const_iterator(list_.begin()); 119 : } 120 10 : const_iterator end() const { 121 10 : return const_iterator(list_.end()); 122 : } 123 : 124 3447596 : bool empty() const { return list_.empty(); } 125 : 126 : private: 127 : List list_; 128 : DISALLOW_COPY_AND_ASSIGN(DependencyList); 129 : }; 130 : 131 : #define DEPENDENCY_LIST(NodeType, ObjectType, _Member) \ 132 : friend class DependencyRef<NodeType, ObjectType>; \ 133 : void DependencyAdd(DependencyRef<NodeType, ObjectType> *node) { \ 134 : _Member.Add(node); \ 135 : } \ 136 : void DependencyRemove(DependencyRef<NodeType, ObjectType> *node) { \ 137 : _Member.Remove(node); \ 138 : } \ 139 : DependencyList<NodeType, ObjectType> _Member 140 : 141 : #endif