LiteSQL 0.3.10
counted_ptr.hpp
1/*
2 * counted_ptr - simple reference counted pointer.
3 *
4 * The is a non-intrusive implementation that allocates an additional
5 * int and pointer for every counted object.
6 */
7
8#ifndef COUNTED_PTR_HPP
9#define COUNTED_PTR_HPP
10
11/* For ANSI-challenged compilers, you may want to #define
12 * NO_MEMBER_TEMPLATES or explicit */
13
14template <class X> class counted_ptr
15{
16public:
17 typedef X element_type;
18
19 explicit counted_ptr(X* p = 0) // allocate a new counter
20 : itsCounter(0) {if (p) itsCounter = new counter(p);}
21 ~counted_ptr()
22 {release();}
23 counted_ptr(const counted_ptr& r) throw()
24 {acquire(r.itsCounter);}
25 counted_ptr& operator=(const counted_ptr& r)
26 {
27 if (this != &r) {
28 release();
29 acquire(r.itsCounter);
30 }
31 return *this;
32 }
33
34#ifndef NO_MEMBER_TEMPLATES
35 template <class Y> friend class counted_ptr<Y>;
36 template <class Y> counted_ptr(const counted_ptr<Y>& r) throw()
37 {acquire(r.itsCounter);}
38 template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r)
39 {
40 if (this != &r) {
41 release();
42 acquire(r.itsCounter);
43 }
44 return *this;
45 }
46#endif // NO_MEMBER_TEMPLATES
47
48 X& operator*() const throw() {return *itsCounter->ptr;}
49 X* operator->() const throw() {return itsCounter->ptr;}
50 X* get() const throw() {return itsCounter ? itsCounter->ptr : 0;}
51 bool unique() const throw()
52 {return (itsCounter ? itsCounter->count == 1 : true);}
53
54private:
55
56 struct counter {
57 counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
58 X* ptr;
59 unsigned count;
60 }* itsCounter;
61
62 void acquire(counter* c) throw()
63 { // increment the count
64 itsCounter = c;
65 if (c) ++c->count;
66 }
67
68 void release()
69 { // decrement the count, delete if it is 0
70 if (itsCounter) {
71 if (--itsCounter->count == 0) {
72 delete itsCounter->ptr;
73 delete itsCounter;
74 }
75 itsCounter = 0;
76 }
77 }
78};
79
80#endif // COUNTED_PTR_HPP

SourceForge.net Logo