OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
intrusive_ptr_back_ref.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
6 #define SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
7 
8 #include <boost/intrusive_ptr.hpp>
9 
10 // IntrusivePtrRef Class is an extension to boost::intrusive_ptr
11 // to provide additional functionality of making back reference
12 // pointer available with callbacks intrusive_ptr_add_back_ref
13 // and intrusive_ptr_del_back_ref, using which application using
14 // IntrusivePtrRef can keep track of pointers who holds references
15 // to the object
16 
17 // referrer, pair of base pointer and member pointer
18 typedef std::pair<void*, void*> IntrusiveReferrer;
19 
20 template <class D>
21 class IntrusivePtrRef : public boost::intrusive_ptr<D> {
22 public:
23  IntrusivePtrRef() : boost::intrusive_ptr<D>(), referrer_(NULL) {
24  }
25 
26  IntrusivePtrRef(D *data) : boost::intrusive_ptr<D>(data), referrer_(NULL) {
27  if (data) {
29  }
30  }
31 
32  IntrusivePtrRef(D *data, void *referrer) : boost::intrusive_ptr<D>(data),
33  referrer_(referrer) {
34  if (data) {
35  intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this), data);
36  }
37  }
38 
39  IntrusivePtrRef(IntrusivePtrRef const &rhs, void *referrer)
40  : boost::intrusive_ptr<D>(rhs), referrer_(referrer) {
41  if (this->get()) {
43  this->get());
44  }
45  }
46 
47  virtual ~IntrusivePtrRef() {
48  if (this->get()) {
50  }
51  }
52 
54  IntrusivePtrRef(rhs, this).swap(*this);
55  return *this;
56  }
57 
59  IntrusivePtrRef(rhs, this).swap(*this);
60  return *this;
61  }
62 
63  void reset() {
64  IntrusivePtrRef(NULL, this).swap(*this);
65  }
66 
67  void reset(D *rhs) {
68  IntrusivePtrRef(rhs, this).swap(*this);
69  }
70 
71  void swap(IntrusivePtrRef &rhs) {
72  // Trigger Base class swap to swap values
73  boost::intrusive_ptr<D>::swap(rhs);
74 
75  // swap the referrer for this and rhs
76  D *tmp = this->get();
77  if (tmp) {
78  // change referrer for new value of IntrusivePtrRef
81  }
82  tmp = rhs.get();
83  if (tmp) {
84  // change referrer for new value of rhs
87  }
88  }
89 
90 private:
91  void *referrer_;
92 };
93 
94 #endif // SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
std::pair< void *, void * > IntrusiveReferrer
void intrusive_ptr_del_back_ref(const IntrusiveReferrer ref, const Interface *p)
IntrusivePtrRef(D *data, void *referrer)
IntrusivePtrRef & operator=(IntrusivePtrRef const &rhs)
void swap(IntrusivePtrRef &rhs)
IntrusivePtrRef & operator=(D *rhs)
IntrusivePtrRef(IntrusivePtrRef const &rhs, void *referrer)
void intrusive_ptr_add_back_ref(const IntrusiveReferrer ref, const Interface *p)