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 5668 : explicit DependencyRef(NodeType *self) : self_(self), ptr_(NULL) { } 19 1220532 : DependencyRef(NodeType *self, ObjectType *ptr) 20 1220532 : : self_(self), ptr_(ptr) { 21 1220562 : if (ptr_ != NULL) { 22 835876 : ptr_->DependencyAdd(this); 23 : } 24 1220609 : } 25 : 26 1226903 : ~DependencyRef() { 27 1226903 : if (ptr_ != NULL) { 28 779536 : ptr_->DependencyRemove(this); 29 : } 30 1226903 : } 31 : 32 15886 : void reset(ObjectType *ptr) { 33 15886 : if (ptr_ != NULL) { 34 6143 : ptr_->DependencyRemove(this); 35 : } 36 15886 : ptr_ = ptr; 37 15886 : if (ptr_ != NULL) { 38 9703 : ptr_->DependencyAdd(this); 39 : } 40 15886 : } 41 : 42 85 : void clear() { 43 85 : if (ptr_ != NULL) { 44 85 : ptr_->DependencyRemove(this); 45 : } 46 85 : ptr_ = NULL; 47 85 : } 48 : 49 2010 : ObjectType *get() const { 50 2010 : return ptr_; 51 : } 52 : 53 2 : ObjectType *operator->() const { 54 2 : 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 3197102 : explicit IteratorBase(const IteratorType &iter) : iter_(iter) { } 81 : private: 82 1129388 : void increment() { ++iter_; } 83 2163216 : bool equal(const IteratorBase &rhs) const { 84 4326432 : return iter_ == rhs.iter_; 85 : } 86 1129383 : ValueType &dereference() const { 87 2258766 : 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 1038354 : DependencyList() { } 96 1038655 : ~DependencyList() { clear(); } 97 : 98 1213959 : void Add(DependencyRef<NodeType, ObjectType> *node) { 99 1213959 : list_.push_back(*node); 100 1213812 : } 101 : 102 1214301 : void Remove(DependencyRef<NodeType, ObjectType> *node) { 103 2428598 : list_.erase(list_.iterator_to(*node)); 104 1214297 : } 105 : 106 1038655 : void clear() { 107 1038657 : while (!list_.empty()) { 108 2 : DependencyRef<NodeType, ObjectType> *node = &list_.front(); 109 2 : node->clear(); 110 : } 111 1038655 : } 112 : 113 : const List &list() const { return list_; } 114 : 115 1033880 : iterator begin() { return iterator(list_.begin()); } 116 2163206 : 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 3447193 : 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