Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Neptune / Source / Core / NptReferences.h
blobc8e1f5ad42587317d215f20f8be2596736f15ced
1 /*****************************************************************
3 | Neptune - References
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
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 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "NptConstants.h"
39 #include "NptThreads.h"
41 /*----------------------------------------------------------------------
42 | NPT_Reference
43 +---------------------------------------------------------------------*/
44 template <typename T>
45 class NPT_Reference
47 public:
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) :
51 m_Object(object),
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();
75 ~NPT_Reference() {
76 Release();
79 // overloaded operators
80 NPT_Reference<T>& operator=(const NPT_Reference<T>& ref) {
81 if (this != &ref) {
82 Release();
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();
92 return *this;
94 NPT_Reference<T>& operator=(T* object) {
95 Release();
96 m_Object = object;
97 m_Counter = object?new NPT_Cardinal(1):NULL;
98 m_Mutex = (object && m_ThreadSafe)?new NPT_Mutex():NULL;
99 return *this;
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);
116 // methods
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.
138 void Detach() {
139 Release(true);
142 private:
143 // methods
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) {
149 delete m_Counter;
150 if (!detach_only) delete m_Object;
151 last_reference = true;
154 m_Counter = NULL;
155 m_Object = NULL;
157 if (m_Mutex) {
158 NPT_Mutex* mutex = m_Mutex;
159 m_Mutex = NULL;
160 mutex->Unlock();
161 if (last_reference) delete mutex;
166 // members
167 T* m_Object;
168 NPT_Cardinal* m_Counter;
169 NPT_Mutex* m_Mutex;
170 bool m_ThreadSafe;
173 #endif // _NPT_REFERENCES_H_