OgreSharedPtr.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __SharedPtr_H__
29#define __SharedPtr_H__
30
31#include "OgrePrerequisites.h"
32#include "OgreAtomicScalar.h"
33
34namespace Ogre {
44 {
51 };
52
54 inline SharedPtrInfo()
55 : useCount(1)
56 {}
57
58 virtual ~SharedPtrInfo() {}
59
61 };
62
63 template <class T>
65 {
67 public:
69
71 {
73 }
74 };
75
76 template <class T>
78 {
80 public:
82
84 {
86 }
87 };
88
89 template <class T>
91 {
93 public:
94 inline SharedPtrInfoFree(T* o) : mObject(o) {}
95
97 {
99 }
100 };
101
102
111 template<class T> class SharedPtr
112 {
113 template<typename Y> friend class SharedPtr;
114 protected:
115 /* DO NOT ADD MEMBERS TO THIS CLASS!
116 *
117 * The average Ogre application has *thousands* of them. Every extra
118 * member causes extra memory use in general, and causes extra padding
119 * to be added to a multitude of structures.
120 *
121 * Everything you need to do can be acomplished by creatively working
122 * with the SharedPtrInfo object.
123 *
124 * There is no reason for this object to ever have more than two members.
125 */
126
129
131 {
132 }
133
134 public:
140 {}
141
142 private:
144 {
145 switch(method) {
149 }
150 assert(!"Bad method");
151 return 0;
152 }
153 public:
154
159 template< class Y>
161 : pRep(rep)
163 {
164 }
165
167 : pRep(r.pRep)
168 , pInfo(r.pInfo)
169 {
170 if (pRep)
171 {
172 ++pInfo->useCount;
173 }
174 }
175
177 if (pRep == r.pRep)
178 {
179 assert(pInfo == r.pInfo);
180 return *this;
181 }
182 // Swap current data into a local copy
183 // this ensures we deal with rhs and this being dependent
184 SharedPtr<T> tmp(r);
185 swap(tmp);
186 return *this;
187 }
188
189 /* For C++11 compilers, use enable_if to only expose functions when viable
190 *
191 * MSVC 2012 and earlier only claim conformance to C++98. This is fortunate,
192 * because they don't support default template parameters
193 */
194#if __cplusplus >= 201103L
195 template<class Y,
196 class = typename std::enable_if<std::is_convertible<Y*, T*>::value>::type>
197#else
198 template<class Y>
199#endif
201 : pRep(r.getPointer())
202 , pInfo(r.pInfo)
203 {
204 if (pRep)
205 {
206 ++pInfo->useCount;
207 }
208 }
209
210
211#if __cplusplus >= 201103L
212 template<class Y,
213 class = typename std::enable_if<std::is_assignable<T*, Y*>::value>::type>
214#else
215 template<class Y>
216#endif
218 {
219 if (pRep == r.pRep)
220 return *this;
221 // Swap current data into a local copy
222 // this ensures we deal with rhs and this being dependent
223 SharedPtr<T> tmp(r);
224 swap(tmp);
225 return *this;
226 }
227
229 release();
230 }
231
232
233 template<typename Y>
235 {
236 if(pRep) {
237 ++pInfo->useCount;
238 return SharedPtr<Y>(static_cast<Y*>(pRep), pInfo);
239 } else return SharedPtr<Y>();
240 }
241
242 template<typename Y>
244 {
245 if(pRep) {
246 Y* rep = dynamic_cast<Y*>(pRep);
247 ++pInfo->useCount;
248 return SharedPtr<Y>(rep, pInfo);
249 } else return SharedPtr<Y>();
250 }
251
252 inline T& operator*() const { assert(pRep); return *pRep; }
253 inline T* operator->() const { assert(pRep); return pRep; }
254 inline T* get() const { return pRep; }
255
264 assert(!pRep && !pInfo);
266 pRep = rep;
267 }
268
269 inline bool unique() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get() == 1; }
270 inline unsigned int useCount() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get(); }
271 inline void setUseCount(unsigned value) { assert(pInfo); pInfo->useCount = value; }
272
273 inline T* getPointer() const { return pRep; }
274
275 inline bool isNull(void) const { return pRep == 0; }
276
277 inline void setNull(void) {
278 if (pRep)
279 {
280 release();
281 }
282 }
283
284 protected:
285
286 inline void release(void)
287 {
288 if (pRep)
289 {
290 assert(pInfo);
291 if(--pInfo->useCount == 0)
292 destroy();
293 }
294
295 pRep = 0;
296 pInfo = 0;
297 }
298
303 inline void destroy(void)
304 {
305 assert(pRep && pInfo);
307 }
308
309 inline void swap(SharedPtr<T> &other)
310 {
311 std::swap(pRep, other.pRep);
312 std::swap(pInfo, other.pInfo);
313 }
314 };
315
316 template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
317 {
318 return a.get() == b.get();
319 }
320
321 template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
322 {
323 return a.get() != b.get();
324 }
325
326 template<class T, class U> inline bool operator<(SharedPtr<T> const& a, SharedPtr<U> const& b)
327 {
328 return std::less<const void*>()(a.get(), b.get());
329 }
332}
333
334
335
336#endif
Reference-counted shared pointer, used for objects where implicit destruction is required.
bool unique() const
SharedPtr & operator=(const SharedPtr< Y > &r)
T & operator*() const
SharedPtr(T *rep, SharedPtrInfo *info)
void setUseCount(unsigned value)
void destroy(void)
IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS BEFORE SHUTTING OGRE DOWN Use setNull() befor...
SharedPtrInfo * pInfo
SharedPtr()
Constructor, does not initialise the SharedPtr.
static SharedPtrInfo * createInfoForMethod(T *rep, SharedPtrFreeMethod method)
void swap(SharedPtr< T > &other)
unsigned int useCount() const
SharedPtr(Y *rep, SharedPtrFreeMethod inFreeMethod=SPFM_DELETE)
Constructor.
bool isNull(void) const
SharedPtr & operator=(const SharedPtr &r)
void release(void)
SharedPtr(const SharedPtr &r)
T * operator->() const
SharedPtr< Y > dynamicCast() const
void bind(T *rep, SharedPtrFreeMethod inFreeMethod=SPFM_DELETE)
Binds rep to the SharedPtr.
SharedPtr(const SharedPtr< Y > &r)
T * getPointer() const
friend class SharedPtr
T * get() const
void setNull(void)
SharedPtr< Y > staticCast() const
SharedPtrFreeMethod
The method to use to free memory on destruction.
bool operator<(SharedPtr< T > const &a, SharedPtr< U > const &b)
@ SPFM_DELETE_T
Use OGRE_DELETE_T to free (only MEMCATEGORY_GENERAL supported)
@ SPFM_DELETE
Use OGRE_DELETE to free the memory.
@ SPFM_FREE
Use OGRE_FREE to free (only MEMCATEGORY_GENERAL supported)
#define OGRE_DELETE_T(ptr, T, category)
Free the memory allocated with OGRE_NEW_T. Category is required to be restated to ensure the matching...
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator,...
#define OGRE_NEW_T(T, category)
Allocate space for one primitive type, external type or non-virtual type with constructor parameters.
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator,...
#define OGRE_FREE(ptr, category)
Free the memory allocated with OGRE_MALLOC or OGRE_ALLOC_T. Category is required to be restated to en...
#define OGRE_DELETE
@ MEMCATEGORY_GENERAL
General purpose.
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
AtomicScalar< unsigned > useCount

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.