-
Notifications
You must be signed in to change notification settings - Fork 9
/
Counted.h
63 lines (51 loc) · 1.41 KB
/
Counted.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef UTILS_COUNTED_H
#define UTILS_COUNTED_H
#include <boost/intrusive_ptr.hpp>
#include <cassert>
#include <stdexcept>
namespace utils {
// Enclosure into another namespace is needed to assure that
// intrusive_ptr* don't get automatically specialized for arbitrary
// classes.
namespace pt {
class Counted {
mutable size_t counter;
Counted(const Counted&);
Counted& operator=(const Counted&);
friend void intrusive_ptr_add_ref(Counted*);
friend void intrusive_ptr_release(Counted*);
protected:
void ref() { // Increment ref counter
counter++;
if (counter == 0) {
assert(false && "Ref counter overflow.");
throw(std::overflow_error("Ref counter overflow."));
}
}
bool unref() { // Decrement ref counter
if (counter <= 0) {
assert(false && "Ref counter underflow.");
throw(std::underflow_error("Ref counter underflow."));
}
return --counter == 0;
}
public:
Counted() : counter(0) {}
size_t count() const { return counter; }
virtual ~Counted() {}
};
inline void intrusive_ptr_add_ref(Counted* p) {
if (p) {
p->ref();
}
}
inline void intrusive_ptr_release(Counted* p) {
if (p) {
if (p->unref()) { // Zero active references left
delete p;
}
}
}
} // End of pt namespace
} // End of utils namespace
#endif // UTILS_COUNTED_H