8 * Created by Christian Brunschen on 07/05/2008.
9 * Copyright 2008 Google UK. All rights reserved.
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
24 //#define DEBUG_COUNTING
34 /* base class for reference-counted objects */
39 Counted() : count_(0) {
41 cout << "instantiating " << typeid(*this).name() << " " << this <<
42 " @ " << count_ << "\n";
45 virtual ~Counted() { }
46 virtual Counted *retain() {
48 cout << "retaining " << typeid(*this).name() << " " << this <<
53 cout << "->" << count_ << "\n";
57 virtual void release() {
59 cout << "releasing " << typeid(*this).name() << " " << this <<
62 if (count_ == 0 || count_ == 54321) {
64 cout << "\nOverreleasing already-deleted object " << this << "!!!\n";
70 cout << "->" << count_ << "\n";
74 cout << "deleting " << typeid(*this).name() << " " << this << "\n";
81 /* return the current count for denugging purposes or similar */
82 int count() const { return count_; }
85 /* counting reference to reference-counted objects */
86 template<typename T> class Ref {
90 explicit Ref(T *o = 0) : object_(0) {
92 cout << "instantiating Ref " << this << " from pointer\n";
97 explicit Ref(const T &o) : object_(0) {
99 cout << "instantiating Ref " << this << " from reference\n";
101 reset(const_cast<T *>(&o));
104 Ref(const Ref &other) : object_(0) {
105 #ifdef DEBUG_COUNTING
106 cout << "instantiating Ref " << this << " from Ref " << &other << "\n";
108 reset(other.object_);
112 Ref(const Ref<Y> &other) : object_(0) {
113 #ifdef DEBUG_COUNTING
114 cout << "instantiating Ref " << this << " from reference\n";
116 reset(other.object_);
121 #ifdef DEBUG_COUNTING
122 cout << "destroying Ref " << this << " with " <<
123 (object_ ? typeid(*object_).name() : "NULL") << " " << object_ << "\n";
131 #ifdef DEBUG_COUNTING
132 cout << "resetting Ref " << this << " from " <<
133 (object_ ? typeid(*object_).name() : "NULL") << " " << object_ <<
134 " to " << (o ? typeid(*o).name() : "NULL") << " " << o << "\n";
136 if (o) { o->retain(); }
137 if (object_) { object_->release(); }
140 Ref& operator=(const Ref &other) {
141 reset(other.object_);
145 Ref& operator=(const Ref<Y> &other) {
146 reset(other.object_);
149 Ref& operator=(T* o) {
154 Ref& operator=(Y* o) {
159 T& operator*() { return *object_; }
160 T* operator->() { return object_; }
161 operator T*() { return object_; }
163 bool operator==(const int x) { return x == 0 ? object_ == 0 : false; }
164 bool operator==(const Ref &other) const {
165 return object_ == other.object_ || *object_ == *(other.object_);
168 bool operator==(const Ref<Y> &other) const {
169 return object_ == other.object_ || *object_ == *(other.object_);
172 bool operator!=(const int x) { return x == 0 ? object_ != 0 : true; }
175 friend ostream& operator<<(ostream &out, Ref<Y>& ref);
179 #endif // __COUNTED_H__