1 /*****************************************************************
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
32 #ifndef _NPT_REFERENCES_H_
33 #define _NPT_REFERENCES_H_
35 /*----------------------------------------------------------------------
37 +---------------------------------------------------------------------*/
38 #include "NptConstants.h"
39 #include "NptThreads.h"
41 /*----------------------------------------------------------------------
43 +---------------------------------------------------------------------*/
48 // constructors and destructor
49 NPT_Reference() : m_Object(NULL
), m_Counter(NULL
), m_Mutex(NULL
), m_ThreadSafe(true) {}
50 explicit NPT_Reference(T
* object
, bool thread_safe
= true) :
52 m_Counter(object
?new NPT_Cardinal(1):NULL
),
53 m_Mutex((object
&& thread_safe
)?new NPT_Mutex():NULL
),
54 m_ThreadSafe(thread_safe
) {}
56 NPT_Reference(const NPT_Reference
<T
>& ref
) :
57 m_Object(ref
.m_Object
), m_Counter(ref
.m_Counter
), m_Mutex(ref
.m_Mutex
), m_ThreadSafe(ref
.m_ThreadSafe
) {
58 if (m_Mutex
) m_Mutex
->Lock();
59 if (m_Counter
) ++(*m_Counter
);
60 if (m_Mutex
) m_Mutex
->Unlock();
63 // this methods should be private, but this causes a problem on some
64 // compilers, because we need this function in order to implement
65 // the cast operator operator NPT_Reference<U>() below, which would
66 // have to be marked as a friend, and friend declarations with the
67 // same class name confuses some compilers
68 NPT_Reference(T
* object
, NPT_Cardinal
* counter
, NPT_Mutex
* mutex
, bool thread_safe
) :
69 m_Object(object
), m_Counter(counter
), m_Mutex(mutex
), m_ThreadSafe(thread_safe
) {
70 if (m_Mutex
) m_Mutex
->Lock();
71 if (m_Counter
) ++(*m_Counter
);
72 if (m_Mutex
) m_Mutex
->Unlock();
79 // overloaded operators
80 NPT_Reference
<T
>& operator=(const NPT_Reference
<T
>& ref
) {
83 m_Object
= ref
.m_Object
;
84 m_Counter
= ref
.m_Counter
;
85 m_Mutex
= ref
.m_Mutex
;
86 m_ThreadSafe
= ref
.m_ThreadSafe
;
88 if (m_Mutex
) m_Mutex
->Lock();
89 if (m_Counter
) ++(*m_Counter
);
90 if (m_Mutex
) m_Mutex
->Unlock();
94 NPT_Reference
<T
>& operator=(T
* object
) {
97 m_Counter
= object
?new NPT_Cardinal(1):NULL
;
98 m_Mutex
= (object
&& m_ThreadSafe
)?new NPT_Mutex():NULL
;
101 T
& operator*() const { return *m_Object
; }
102 T
* operator->() const { return m_Object
; }
104 bool operator==(const NPT_Reference
<T
>& ref
) const {
105 return m_Object
== ref
.m_Object
;
107 bool operator!=(const NPT_Reference
<T
>& ref
) const {
108 return m_Object
!= ref
.m_Object
;
111 // overloaded cast operators
112 template <typename U
> operator NPT_Reference
<U
>() {
113 return NPT_Reference
<U
>(m_Object
, m_Counter
, m_Mutex
, m_ThreadSafe
);
118 * Returns the naked pointer value.
120 T
* AsPointer() const { return m_Object
; }
123 * Returns the reference counter value.
125 NPT_Cardinal
GetCounter() const { return *m_Counter
; }
128 * Returns whether this references a NULL object.
130 bool IsNull() const { return m_Object
== NULL
; }
133 * Detach the reference from the shared object.
134 * The reference count is decremented, but the object is not deleted if the
135 * reference count becomes 0.
136 * After the method returns, this reference does not point to any shared object.
144 void Release(bool detach_only
= false) {
145 bool last_reference
= false;
146 if (m_Mutex
) m_Mutex
->Lock();
148 if (m_Counter
&& --(*m_Counter
) == 0) {
150 if (!detach_only
) delete m_Object
;
151 last_reference
= true;
158 NPT_Mutex
* mutex
= m_Mutex
;
161 if (last_reference
) delete mutex
;
168 NPT_Cardinal
* m_Counter
;
173 #endif // _NPT_REFERENCES_H_