2 * Copyright (c) 2005, Eric Crahen
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef __ZTCOUNTEDPTR_H__
24 #define __ZTCOUNTEDPTR_H__
29 #include "zthread/AtomicCount.h"
32 # pragma warning(push)
33 # pragma warning(disable:4786) // warning: long template symbol name
34 # pragma warning(push)
35 # pragma warning(disable:4284) // warning: odd return type for operator->
43 * @author Eric Crahen <http://www.code-foo.com/>
44 * @date <2003-07-29T06:43:48-0400>
48 template <typename T
, typename CountT
= AtomicCount
>
51 #if !defined(__MWERKS__)
52 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
53 template <typename U
, typename V
> friend class CountedPtr
;
62 CountedPtr() : _count(0), _instance(0) { }
64 #if !defined(__MWERKS__)
65 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
67 explicit CountedPtr(T
* raw
) : _count(new CountT()), _instance(raw
) {
75 explicit CountedPtr(U
* raw
) : _count(new CountT()), _instance(raw
) {
79 #if !defined(__MWERKS__)
80 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
82 CountedPtr(const CountedPtr
& ptr
) : _count(ptr
._count
), _instance(ptr
._instance
) {
92 template <typename U
, typename V
>
93 CountedPtr(const CountedPtr
<U
, V
>& ptr
) : _count(ptr
._count
), _instance(ptr
._instance
) {
102 if(_count
&& --(*_count
) == 0) {
114 #if !defined(__MWERKS__)
115 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
117 const CountedPtr
& operator=(const CountedPtr
& ptr
) {
119 typedef CountedPtr
<T
, CountT
> ThisT
;
121 ThisT(ptr
).swap(*this);
129 template <typename U
, typename V
>
130 const CountedPtr
& operator=(const CountedPtr
<U
, V
>& ptr
) {
132 typedef CountedPtr
<T
, CountT
> ThisT
;
134 ThisT(ptr
).swap(*this);
141 typedef CountedPtr
<T
, CountT
> ThisT
;
146 #if !defined(__MWERKS__)
147 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
149 void swap(CountedPtr
& ptr
) {
151 std::swap(_count
, ptr
._count
);
152 std::swap(_instance
, ptr
._instance
);
159 template <typename U
, typename V
>
160 void swap(CountedPtr
<U
, V
>& ptr
) {
162 std::swap(_count
, ptr
._count
);
163 std::swap(_instance
, ptr
._instance
);
167 // Convience operators
169 #if !defined(__MWERKS__)
170 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
172 bool less(const CountedPtr
& ptr
) const {
173 return _instance
< ptr
._instance
;
179 template <typename U
, typename V
>
180 bool less(const CountedPtr
<U
, V
>& ptr
) const {
181 return _instance
< ptr
._instance
;
185 #if !defined(__MWERKS__)
186 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
188 bool equal(const CountedPtr
& ptr
) const {
189 return _count
== ptr
._count
;
195 template <typename U
, typename V
>
196 bool equal(const CountedPtr
<U
, V
>& ptr
) const {
197 return _count
== ptr
._count
;
201 friend inline bool operator==(const CountedPtr
& lhs
, const CountedPtr
& rhs
) {
202 return lhs
.equal(rhs
);
205 friend inline bool operator<(const CountedPtr
& lhs
, const CountedPtr
& rhs
) {
206 return lhs
.less(rhs
);
211 assert(_instance
!= 0);
216 assert(_instance
!= 0);
220 const T
* operator->() const {
221 assert(_instance
!= 0);
225 bool operator!() const {
226 return _instance
== 0;
229 operator bool() const {
230 return _instance
!= 0;
235 template<typename U
, typename V
, typename X
, typename Y
>
236 inline bool operator<(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<X
, Y
> const &rhs
) {
237 return lhs
.less(rhs
);
240 template<typename U
, typename V
, typename X
, typename Y
>
241 inline bool operator==(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<X
, Y
> const &rhs
) {
242 return lhs
.equal(rhs
.get
);
245 template<typename U
, typename V
, typename X
, typename Y
>
246 inline bool operator!=(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<X
, Y
> const &rhs
) {
247 return !(lhs
.equal(rhs
.get
));
250 template<typename U
, typename V
, typename X
, typename Y
>
251 inline void swap(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<X
, Y
> const &rhs
) {
255 #if !defined(__MWERKS__)
256 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
258 template<typename U
, typename V
>
259 inline bool operator<(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<U
, V
> const &rhs
) {
260 return lhs
.less(rhs
);
263 template<typename U
, typename V
>
264 inline bool operator==(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<U
, V
> const &rhs
) {
265 return lhs
.equal(rhs
.get
);
268 template<typename U
, typename V
>
269 inline bool operator!=(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<U
, V
> const &rhs
) {
270 return !(lhs
.equal(rhs
.get
));
273 template<typename U
, typename V
>
274 inline void swap(CountedPtr
<U
, V
> const &lhs
, CountedPtr
<U
, V
> const &rhs
) {
281 } // namespace ZThread
284 # pragma warning(pop)
285 # pragma warning(pop)
289 #endif // __ZTCOUNTEDPTR_H__