]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/RefCount.h
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / base / RefCount.h
CommitLineData
1077c1b8 1/*
5b74111a 2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
1077c1b8 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
1077c1b8 7 */
8
bbc27441
AJ
9/* DEBUG: section -- Refcount allocator */
10
605f2c3e
AJ
11#ifndef SQUID_REFCOUNT_H_
12#define SQUID_REFCOUNT_H_
1077c1b8 13
8bf217bd
AJ
14// reference counting requires the Lock API on base classes
15#include "base/Lock.h"
16
7c36d157 17#include <iostream>
18
8bf217bd
AJ
19/**
20 * Template for Reference Counting pointers.
21 *
2763a37c 22 * Objects of type 'C' must inherit from 'RefCountable' in base/Lock.h
8bf217bd
AJ
23 * which provides the locking interface used by reference counting.
24 */
1077c1b8 25template <class C>
43ae1d95 26class RefCount
27{
28
1077c1b8 29public:
43ae1d95 30 RefCount () : p_ (NULL) {}
31
32 RefCount (C const *p) : p_(p) { reference (*this); }
33
c5dd4956 34 ~RefCount() {
43ae1d95 35 dereference();
1077c1b8 36 }
43ae1d95 37
c5dd4956 38 RefCount (const RefCount &p) : p_(p.p_) {
43ae1d95 39 reference (p);
1077c1b8 40 }
43ae1d95 41
47349075
FC
42 RefCount (RefCount &&p) : p_(std::move(p.p_)) {
43 p.p_=NULL;
44 }
45
c5dd4956 46 RefCount& operator = (const RefCount& p) {
43ae1d95 47 // DO NOT CHANGE THE ORDER HERE!!!
48 // This preserves semantics on self assignment
49 C const *newP_ = p.p_;
50 reference(p);
db812f89 51 dereference(newP_);
43ae1d95 52 return *this;
1077c1b8 53 }
43ae1d95 54
47349075 55 RefCount& operator = (RefCount&& p) {
5a0d1f98 56 if (this != &p) {
0e63f973 57 dereference(p.p_);
5a0d1f98
FC
58 p.p_ = NULL;
59 }
29d97824 60 return *this;
47349075
FC
61 }
62
95426d2e
AR
63 explicit operator bool() const { return p_; }
64
c5dd4956 65 bool operator !() const { return !p_; }
be702f78 66
b0d53123 67 C * operator-> () const {return const_cast<C *>(p_); }
43ae1d95 68
801cfc26
CT
69 C & operator * () const {
70 assert(p_);
71 return *const_cast<C *>(p_);
72 }
43ae1d95 73
801cfc26 74 C * getRaw() const { return const_cast<C *>(p_); }
43ae1d95 75
c5dd4956 76 bool operator == (const RefCount& p) const {
43ae1d95 77 return p.p_ == p_;
1077c1b8 78 }
43ae1d95 79
c5dd4956 80 bool operator != (const RefCount &p) const {
0655fa4d 81 return p.p_ != p_;
82 }
83
1077c1b8 84private:
c5dd4956 85 void dereference(C const *newP = NULL) {
db812f89 86 /* Setting p_ first is important:
00d77d6b 87 * we may be freed ourselves as a result of
88 * delete p_;
89 */
faffe22c 90 C const (*tempP_) (p_);
00d77d6b 91 p_ = newP;
92
8bf217bd 93 if (tempP_ && tempP_->unlock() == 0)
00d77d6b 94 delete tempP_;
1077c1b8 95 }
43ae1d95 96
c5dd4956 97 void reference (const RefCount& p) {
43ae1d95 98 if (p.p_)
8bf217bd 99 p.p_->lock();
1077c1b8 100 }
43ae1d95 101
102 C const *p_;
1077c1b8 103
104};
105
7c36d157 106template <class C>
107inline std::ostream &operator <<(std::ostream &os, const RefCount<C> &p)
108{
109 if (p != NULL)
8bf217bd 110 return os << p.getRaw() << '*' << p->LockCount();
7c36d157 111 else
112 return os << "NULL";
113}
114
605f2c3e 115#endif /* SQUID_REFCOUNT_H_ */
f53969cc 116