OgreSharedPtr.h
Go to the documentation of this file.
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __SharedPtr_H__
#define __SharedPtr_H__
#include "OgrePrerequisites.h"
#include "OgreAtomicScalar.h"
namespace Ogre {
enum SharedPtrFreeMethod
{
SPFM_DELETE,
SPFM_DELETE_T,
SPFM_FREE
};
struct SharedPtrInfo {
inline SharedPtrInfo()
: useCount(1)
{}
virtual ~SharedPtrInfo() {}
AtomicScalar<unsigned> useCount;
};
template <class T>
class SharedPtrInfoDelete : public SharedPtrInfo
{
T* mObject;
public:
inline SharedPtrInfoDelete(T* o) : mObject(o) {}
virtual ~SharedPtrInfoDelete()
{
OGRE_DELETE mObject;
}
};
template <class T>
class SharedPtrInfoDeleteT : public SharedPtrInfo
{
T* mObject;
public:
inline SharedPtrInfoDeleteT(T* o) : mObject(o) {}
virtual ~SharedPtrInfoDeleteT()
{
OGRE_DELETE_T(mObject, T, MEMCATEGORY_GENERAL);
}
};
template <class T>
class SharedPtrInfoFree : public SharedPtrInfo
{
T* mObject;
public:
inline SharedPtrInfoFree(T* o) : mObject(o) {}
virtual ~SharedPtrInfoFree()
{
OGRE_FREE(mObject, MEMCATEGORY_GENERAL);
}
};
template<class T> class SharedPtr
{
template<typename Y> friend class SharedPtr;
protected:
/* DO NOT ADD MEMBERS TO THIS CLASS!
*
* The average Ogre application has *thousands* of them. Every extra
* member causes extra memory use in general, and causes extra padding
* to be added to a multitude of structures.
*
* Everything you need to do can be acomplished by creatively working
* with the SharedPtrInfo object.
*
* There is no reason for this object to ever have more than two members.
*/
T* pRep;
SharedPtrInfo* pInfo;
SharedPtr(T* rep, SharedPtrInfo* info) : pRep(rep), pInfo(info)
{
}
public:
SharedPtr() : pRep(0), pInfo(0)
{}
private:
static SharedPtrInfo* createInfoForMethod(T* rep, SharedPtrFreeMethod method)
{
switch(method) {
case SPFM_DELETE: return OGRE_NEW_T(SharedPtrInfoDelete<T>, MEMCATEGORY_GENERAL) (rep);
case SPFM_DELETE_T: return OGRE_NEW_T(SharedPtrInfoDeleteT<T>, MEMCATEGORY_GENERAL) (rep);
case SPFM_FREE: return OGRE_NEW_T(SharedPtrInfoFree<T>, MEMCATEGORY_GENERAL) (rep);
}
assert(!"Bad method");
return 0;
}
public:
template< class Y>
explicit SharedPtr(Y* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE)
: pRep(rep)
, pInfo(rep ? createInfoForMethod(rep, inFreeMethod) : 0)
{
}
SharedPtr(const SharedPtr& r)
: pRep(r.pRep)
, pInfo(r.pInfo)
{
if (pRep)
{
++pInfo->useCount;
}
}
SharedPtr& operator=(const SharedPtr& r) {
if (pRep == r.pRep)
{
assert(pInfo == r.pInfo);
return *this;
}
// Swap current data into a local copy
// this ensures we deal with rhs and this being dependent
SharedPtr<T> tmp(r);
swap(tmp);
return *this;
}
/* For C++11 compilers, use enable_if to only expose functions when viable
*
* MSVC 2012 and earlier only claim conformance to C++98. This is fortunate,
* because they don't support default template parameters
*/
#if __cplusplus >= 201103L
template<class Y,
class = typename std::enable_if<std::is_convertible<Y*, T*>::value>::type>
#else
template<class Y>
#endif
SharedPtr(const SharedPtr<Y>& r)
: pRep(r.getPointer())
, pInfo(r.pInfo)
{
if (pRep)
{
++pInfo->useCount;
}
}
#if __cplusplus >= 201103L
template<class Y,
class = typename std::enable_if<std::is_assignable<T*, Y*>::value>::type>
#else
template<class Y>
#endif
SharedPtr& operator=(const SharedPtr<Y>& r)
{
if (pRep == r.pRep)
return *this;
// Swap current data into a local copy
// this ensures we deal with rhs and this being dependent
SharedPtr<T> tmp(r);
swap(tmp);
return *this;
}
~SharedPtr() {
release();
}
template<typename Y>
inline SharedPtr<Y> staticCast() const
{
if(pRep) {
++pInfo->useCount;
return SharedPtr<Y>(static_cast<Y*>(pRep), pInfo);
} else return SharedPtr<Y>();
}
template<typename Y>
inline SharedPtr<Y> dynamicCast() const
{
if(pRep) {
Y* rep = dynamic_cast<Y*>(pRep);
++pInfo->useCount;
return SharedPtr<Y>(rep, pInfo);
} else return SharedPtr<Y>();
}
inline T& operator*() const { assert(pRep); return *pRep; }
inline T* operator->() const { assert(pRep); return pRep; }
inline T* get() const { return pRep; }
void bind(T* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE) {
assert(!pRep && !pInfo);
pInfo = createInfoForMethod(rep, inFreeMethod);
pRep = rep;
}
inline bool unique() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get() == 1; }
inline unsigned int useCount() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get(); }
inline void setUseCount(unsigned value) { assert(pInfo); pInfo->useCount = value; }
inline T* getPointer() const { return pRep; }
inline bool isNull(void) const { return pRep == 0; }
inline void setNull(void) {
if (pRep)
{
release();
}
}
protected:
inline void release(void)
{
if (pRep)
{
assert(pInfo);
if(--pInfo->useCount == 0)
destroy();
}
pRep = 0;
pInfo = 0;
}
inline void destroy(void)
{
assert(pRep && pInfo);
OGRE_DELETE_T(pInfo, SharedPtrInfo, MEMCATEGORY_GENERAL);
}
inline void swap(SharedPtr<T> &other)
{
std::swap(pRep, other.pRep);
std::swap(pInfo, other.pInfo);
}
};
template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
{
return a.get() != b.get();
}
template<class T, class U> inline bool operator<(SharedPtr<T> const& a, SharedPtr<U> const& b)
{
return std::less<const void*>()(a.get(), b.get());
}
}
#endif
Ogre::SharedPtrInfo::SharedPtrInfo
SharedPtrInfo()
Definition: OgreSharedPtr.h:54
Ogre::SharedPtr::SharedPtr
SharedPtr(const SharedPtr< Y > &r)
Definition: OgreSharedPtr.h:200
Ogre::SharedPtr::setUseCount
void setUseCount(unsigned value)
Definition: OgreSharedPtr.h:271
Ogre::SharedPtr::swap
void swap(SharedPtr< T > &other)
Definition: OgreSharedPtr.h:309
Ogre::SPFM_DELETE
Use OGRE_DELETE to free the memory.
Definition: OgreSharedPtr.h:46
OGRE_DELETE
#define OGRE_DELETE
Definition: OgreMemoryAllocatorConfig.h:474
Ogre::SharedPtr::SharedPtr
SharedPtr(T *rep, SharedPtrInfo *info)
Definition: OgreSharedPtr.h:130
Ogre::SharedPtr::operator=
SharedPtr & operator=(const SharedPtr< Y > &r)
Definition: OgreSharedPtr.h:217
Ogre::SPFM_FREE
Use OGRE_FREE to free (only MEMCATEGORY_GENERAL supported)
Definition: OgreSharedPtr.h:50
Ogre::SharedPtrInfoDelete::mObject
T * mObject
Definition: OgreSharedPtr.h:66
Ogre::SharedPtr::unique
bool unique() const
Definition: OgreSharedPtr.h:269
Ogre::AtomicScalar::get
T get(void) const
Definition: OgreAtomicScalar.h:417
Ogre::SharedPtrInfo::~SharedPtrInfo
virtual ~SharedPtrInfo()
Definition: OgreSharedPtr.h:58
Ogre::SharedPtrInfo::useCount
AtomicScalar< unsigned > useCount
Definition: OgreSharedPtr.h:60
Ogre::SharedPtr::isNull
bool isNull(void) const
Definition: OgreSharedPtr.h:275
Ogre::SharedPtr::setNull
void setNull(void)
Definition: OgreSharedPtr.h:277
OgreAtomicScalar.h
Ogre::SharedPtr::pRep
T * pRep
Definition: OgreSharedPtr.h:127
Ogre::SharedPtr::~SharedPtr
~SharedPtr()
Definition: OgreSharedPtr.h:228
OgrePrerequisites.h
Ogre::SharedPtr::operator=
SharedPtr & operator=(const SharedPtr &r)
Definition: OgreSharedPtr.h:176
Ogre::SharedPtrInfoDeleteT::~SharedPtrInfoDeleteT
virtual ~SharedPtrInfoDeleteT()
Definition: OgreSharedPtr.h:83
Ogre::SharedPtr::SharedPtr
SharedPtr(const SharedPtr &r)
Definition: OgreSharedPtr.h:166
Ogre::SharedPtrInfoDelete
Definition: OgreSharedPtr.h:64
Ogre::SharedPtrInfoFree
Definition: OgreSharedPtr.h:90
Ogre::MEMCATEGORY_GENERAL
General purpose.
Definition: OgreMemoryAllocatorConfig.h:162
OGRE_FREE
#define OGRE_FREE(ptr, category)
Free the memory allocated with OGRE_MALLOC or OGRE_ALLOC_T. Category is required to be restated to en...
Definition: OgreMemoryAllocatorConfig.h:430
Ogre::operator!=
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)
Definition: OgreMemorySTLAllocator.h:202
OGRE_DELETE_T
#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...
Definition: OgreMemoryAllocatorConfig.h:437
Ogre::SharedPtr::operator->
T * operator->() const
Definition: OgreSharedPtr.h:253
Ogre::SharedPtr::release
void release(void)
Definition: OgreSharedPtr.h:286
Ogre::SharedPtr::useCount
unsigned int useCount() const
Definition: OgreSharedPtr.h:270
Ogre::SharedPtrInfoFree::~SharedPtrInfoFree
virtual ~SharedPtrInfoFree()
Definition: OgreSharedPtr.h:96
Ogre::SharedPtr::SharedPtr
SharedPtr()
Constructor, does not initialise the SharedPtr.
Definition: OgreSharedPtr.h:139
Ogre::SharedPtrInfoDelete::SharedPtrInfoDelete
SharedPtrInfoDelete(T *o)
Definition: OgreSharedPtr.h:68
Ogre::SharedPtr::dynamicCast
SharedPtr< Y > dynamicCast() const
Definition: OgreSharedPtr.h:243
OGRE_NEW_T
#define OGRE_NEW_T(T, category)
Allocate space for one primitive type, external type or non-virtual type with constructor parameters...
Definition: OgreMemoryAllocatorConfig.h:433
std::swap
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: OgreSmallVector.h:802
Ogre::SharedPtr::bind
void bind(T *rep, SharedPtrFreeMethod inFreeMethod=SPFM_DELETE)
Binds rep to the SharedPtr.
Definition: OgreSharedPtr.h:263
Ogre::AtomicScalar< unsigned >
Ogre::SharedPtr::get
T * get() const
Definition: OgreSharedPtr.h:254
Ogre
Definition: OgreAndroidLogListener.h:34
Ogre::SharedPtr::operator*
T & operator*() const
Definition: OgreSharedPtr.h:252
Ogre::SharedPtrInfoDeleteT
Definition: OgreSharedPtr.h:77
Ogre::SharedPtr::destroy
void destroy(void)
IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS BEFORE SHUTTING OGRE DOWN Use setNull() befor...
Definition: OgreSharedPtr.h:303
Ogre::SharedPtrFreeMethod
SharedPtrFreeMethod
The method to use to free memory on destruction.
Definition: OgreSharedPtr.h:43
Ogre::SharedPtrInfoDeleteT::mObject
T * mObject
Definition: OgreSharedPtr.h:79
Ogre::SharedPtr
Reference-counted shared pointer, used for objects where implicit destruction is required.
Definition: OgrePrerequisites.h:310
Ogre::SharedPtr::SharedPtr
SharedPtr(Y *rep, SharedPtrFreeMethod inFreeMethod=SPFM_DELETE)
Constructor.
Definition: OgreSharedPtr.h:160
Ogre::SharedPtr::getPointer
T * getPointer() const
Definition: OgreSharedPtr.h:273
Ogre::operator==
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)
Definition: OgreMemorySTLAllocator.h:184
Ogre::SharedPtrInfoFree::SharedPtrInfoFree
SharedPtrInfoFree(T *o)
Definition: OgreSharedPtr.h:94
Ogre::SharedPtr::pInfo
SharedPtrInfo * pInfo
Definition: OgreSharedPtr.h:128
Ogre::SharedPtr::staticCast
SharedPtr< Y > staticCast() const
Definition: OgreSharedPtr.h:234
Ogre::SPFM_DELETE_T
Use OGRE_DELETE_T to free (only MEMCATEGORY_GENERAL supported)
Definition: OgreSharedPtr.h:48
Ogre::SharedPtrInfo
Definition: OgreSharedPtr.h:53
Ogre::SharedPtrInfoDeleteT::SharedPtrInfoDeleteT
SharedPtrInfoDeleteT(T *o)
Definition: OgreSharedPtr.h:81
Ogre::SharedPtrInfoDelete::~SharedPtrInfoDelete
virtual ~SharedPtrInfoDelete()
Definition: OgreSharedPtr.h:70
Ogre::SharedPtr::createInfoForMethod
static SharedPtrInfo * createInfoForMethod(T *rep, SharedPtrFreeMethod method)
Definition: OgreSharedPtr.h:143
Ogre::SharedPtrInfoFree::mObject
T * mObject
Definition: OgreSharedPtr.h:92

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