1 /*
2 Copyright (C) 2009 Facundo Domínguez
3
4 This file is part of Spacejunk.
5
6 Spacejunk is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Foobar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * This file defines counted references and
22 * */
23
24 #ifndef REFERENCE_H
25 #define REFERENCE_H
26 #include <stdlib.h>
27
28 template <class PointedType>
del(PointedType * p)29 inline void del(PointedType*p) {
30 delete p;
31 }
32 template <class PointedType>
delarray(PointedType * p)33 inline void delarray(PointedType*p) {
34 delete [] p;
35 }
36
37 /** Reference-counted smart pointer implementation. */
38 template <class PointedType,void FreeRoutine(PointedType*) = del<PointedType> >
39 class Ref {
40 protected:
41 PointedType * p;
42 int * refCounter;
43 public:
Ref()44 Ref(): p(NULL), refCounter(NULL) {};
Ref(PointedType * p)45 explicit Ref(PointedType * p) : p(p), refCounter() {
46 refCounter=p?new int(1):NULL;
47 };
Ref(const Ref<PointedType,FreeRoutine> & r)48 Ref(const Ref<PointedType,FreeRoutine> & r) : p(r.p), refCounter(r.refCounter) {
49 if (refCounter) ++*refCounter;
50 };
51
clear()52 void clear() {
53 if (p && !--*refCounter) {
54 FreeRoutine(p);
55 delete refCounter;
56 }
57 };
58
59 Ref<PointedType,FreeRoutine> & operator=(const Ref<PointedType,FreeRoutine> & r) {
60 if (this!=&r) {
61 clear();
62 refCounter=r.refCounter;
63 if (refCounter) ++*refCounter;
64 p=r.p;
65 }
66 return *this;
67 };
68
~Ref()69 virtual ~Ref() {
70 clear();
71 };
72
73 PointedType * operator ->() const {
74 return p;
75 }
76 PointedType & operator *() const {
77 return *p;
78 }
79 bool operator == (const Ref<PointedType,FreeRoutine> & r) const {
80 return p==r.p;
81 }
82 bool operator != (const Ref<PointedType,FreeRoutine> & r) const {
83 return *this!=r;
84 }
85 bool operator < (const Ref<PointedType,FreeRoutine> & r) const {
86 return p<r.p;
87 }
88 };
89
90 template <class PointedType>
clone(PointedType * p)91 inline PointedType* clone(PointedType*p) {
92 return p?new PointedType(*p):NULL;
93 }
94
95 /** Deep copy smart pointer implementation. */
96 template <class PointedType,
97 PointedType* CloneRoutine(PointedType*)=clone<PointedType>,
98 void FreeRoutine(PointedType*) = del<PointedType> >
99 class OwnRef {
100 protected:
101 PointedType * p;
102 public:
OwnRef()103 OwnRef(): p(NULL) {};
OwnRef(PointedType * p)104 OwnRef(PointedType * p) : p(p) {};
OwnRef(const OwnRef<PointedType,CloneRoutine,FreeRoutine> & r)105 OwnRef(const OwnRef<PointedType,CloneRoutine,FreeRoutine> & r) {
106 p=CloneRoutine(r.p);
107 };
108
109 OwnRef<PointedType,CloneRoutine,FreeRoutine> & operator=(const OwnRef<PointedType,CloneRoutine,FreeRoutine> & r) {
110 if (this!=&r) {
111 if (p) FreeRoutine(p);
112 p=CloneRoutine(r.p);
113 }
114 return *this;
115 };
116
117 OwnRef<PointedType,CloneRoutine,FreeRoutine> & operator=(PointedType * p) {
118 if (this->p!=p) {
119 if (this->p) FreeRoutine(this->p);
120 this->p=CloneRoutine(p);
121 }
122 return *this;
123 };
124
~OwnRef()125 virtual ~OwnRef() {
126 if (p) FreeRoutine(p);/*cout<<rc<<"\n";*/
127 };
128
129 PointedType * operator ->() const {
130 return p;
131 }
132 PointedType & operator *() const {
133 return *p;
134 }
135 };
136
137 #endif // REFERENCE_H
138