kodi
NptReferences.h
1 /*****************************************************************
2 |
3 | Neptune - References
4 |
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
7 |
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.
18 |
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.
29 |
30 ****************************************************************/
31 
32 #ifndef _NPT_REFERENCES_H_
33 #define _NPT_REFERENCES_H_
34 
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "NptConstants.h"
39 #include "NptThreads.h"
40 
41 /*----------------------------------------------------------------------
42 | NPT_Reference
43 +---------------------------------------------------------------------*/
44 template <typename T>
46 {
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) {}
55 
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();
61  }
62 
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();
73  }
74 
75  ~NPT_Reference() {
76  Release();
77  }
78 
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;
87 
88  if (m_Mutex) m_Mutex->Lock();
89  if (m_Counter) ++(*m_Counter);
90  if (m_Mutex) m_Mutex->Unlock();
91  }
92  return *this;
93  }
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;
100  }
101  T& operator*() const { return *m_Object; }
102  T* operator->() const { return m_Object; }
103 
104  bool operator==(const NPT_Reference<T>& ref) const {
105  return m_Object == ref.m_Object;
106  }
107  bool operator!=(const NPT_Reference<T>& ref) const {
108  return m_Object != ref.m_Object;
109  }
110 
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);
114  }
115 
116  // methods
120  T* AsPointer() const { return m_Object; }
121 
125  NPT_Cardinal GetCounter() const { return *m_Counter; }
126 
130  bool IsNull() const { return m_Object == NULL; }
131 
138  void Detach() {
139  Release(true);
140  }
141 
142 private:
143  // methods
144  void Release(bool detach_only = false) {
145  bool last_reference = false;
146  if (m_Mutex) m_Mutex->Lock();
147 
148  if (m_Counter && --(*m_Counter) == 0) {
149  delete m_Counter;
150  if (!detach_only) delete m_Object;
151  last_reference = true;
152  }
153 
154  m_Counter = NULL;
155  m_Object = NULL;
156 
157  if (m_Mutex) {
158  NPT_Mutex* mutex = m_Mutex;
159  m_Mutex = NULL;
160  mutex->Unlock();
161  if (last_reference) delete mutex;
162  }
163 
164  }
165 
166  // members
167  T* m_Object;
168  NPT_Cardinal* m_Counter;
169  NPT_Mutex* m_Mutex;
170  bool m_ThreadSafe;
171 };
172 
173 #endif // _NPT_REFERENCES_H_
T * AsPointer() const
Returns the naked pointer value.
Definition: NptReferences.h:120
Definition: NptThreads.h:76
void Detach()
Detach the reference from the shared object.
Definition: NptReferences.h:138
NPT_Cardinal GetCounter() const
Returns the reference counter value.
Definition: NptReferences.h:125
Definition: NptReferences.h:45
bool IsNull() const
Returns whether this references a NULL object.
Definition: NptReferences.h:130