implement HiddenPtr smart pointer type; use it for Steps. This avoids having
to write a whole copy constructor for a class just to hide a couple types from the header.
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
|
|
||||||
|
#include "RageUtil_AutoPtr.h"
|
||||||
|
REGISTER_CLASS_TRAITS( NoteData, new NoteData(*pCopy) )
|
||||||
|
|
||||||
NoteData::NoteData()
|
NoteData::NoteData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,6 +96,103 @@ inline void swap( AutoPtrCopyOnWrite<T> &a, AutoPtrCopyOnWrite<T> &b )
|
|||||||
a.Swap(b);
|
a.Swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This smart pointer template is used to safely hide implementations from
|
||||||
|
* headers, to reduce dependencies. This is the same as declaring a pointer
|
||||||
|
* to a class, and allocating/deallocating it in the implementation: only
|
||||||
|
* the implementation needs to include that class. This makes copying
|
||||||
|
* and deletion automatic, so you don't need to include a copy ctor or
|
||||||
|
* remember to delete it.
|
||||||
|
*
|
||||||
|
* There's one subtlety: in order to copy or delete an object, we need its
|
||||||
|
* definition. This is intended to avoid pulling in the definition. So,
|
||||||
|
* we use a traits class to hide it. Use REGISTER_CLASS_TRAITS for each
|
||||||
|
* class used with this template.
|
||||||
|
*
|
||||||
|
* Concepts from http://www.gotw.ca/gotw/062.htm.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
struct HiddenPtrTraits
|
||||||
|
{
|
||||||
|
static T *Copy( const T *pCopy );
|
||||||
|
static void Delete( T *p );
|
||||||
|
};
|
||||||
|
#define REGISTER_CLASS_TRAITS(T, CopyExpr) \
|
||||||
|
template<> T *HiddenPtrTraits<T>::Copy( const T *pCopy ) { return CopyExpr; } \
|
||||||
|
template<> void HiddenPtrTraits<T>::Delete( T *p ) { delete p; }
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class HiddenPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const T& operator*() const { return *m_pPtr; }
|
||||||
|
const T* operator->() const { return m_pPtr; }
|
||||||
|
T& operator*() { return *m_pPtr; }
|
||||||
|
T* operator->() { return m_pPtr; }
|
||||||
|
|
||||||
|
explicit HiddenPtr( T *p = NULL )
|
||||||
|
{
|
||||||
|
m_pPtr = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiddenPtr( const HiddenPtr<T> &cpy )
|
||||||
|
{
|
||||||
|
if( cpy.m_pPtr == NULL )
|
||||||
|
m_pPtr = NULL;
|
||||||
|
else
|
||||||
|
m_pPtr = HiddenPtrTraits<T>::Copy( cpy.m_pPtr );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
HiddenPtr( const HiddenPtr<U> &cpy )
|
||||||
|
{
|
||||||
|
if( cpy.m_pPtr == NULL )
|
||||||
|
m_pPtr = NULL;
|
||||||
|
else
|
||||||
|
m_pPtr = HiddenPtrTraits<U>::Copy( cpy.m_pPtr );
|
||||||
|
}
|
||||||
|
|
||||||
|
~HiddenPtr()
|
||||||
|
{
|
||||||
|
HiddenPtrTraits<T>::Delete( m_pPtr );
|
||||||
|
}
|
||||||
|
void Swap( HiddenPtr<T> &rhs ) { swap( m_pPtr, rhs.m_pPtr ); }
|
||||||
|
|
||||||
|
HiddenPtr<T> &operator=( T *p )
|
||||||
|
{
|
||||||
|
HiddenPtr<T> t( p );
|
||||||
|
Swap( t );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiddenPtr<T> &operator=( const HiddenPtr &cpy )
|
||||||
|
{
|
||||||
|
HiddenPtr<T> t( cpy );
|
||||||
|
Swap( t );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
HiddenPtr<T> &operator=( const HiddenPtr<U> &cpy )
|
||||||
|
{
|
||||||
|
HiddenPtr<T> t( cpy );
|
||||||
|
Swap( t );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *m_pPtr;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
friend class HiddenPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void swap( HiddenPtr<T> &a, HiddenPtr<T> &b )
|
||||||
|
{
|
||||||
|
a.Swap(b);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "Steps.h"
|
#include "Steps.h"
|
||||||
#include "StepsUtil.h"
|
#include "StepsUtil.h"
|
||||||
|
#include "song.h"
|
||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "NoteData.h"
|
#include "NoteData.h"
|
||||||
@@ -41,7 +42,6 @@ Steps::Steps()
|
|||||||
|
|
||||||
Steps::~Steps()
|
Steps::~Steps()
|
||||||
{
|
{
|
||||||
delete m_pNoteData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Steps::SetNoteData( const NoteData& noteDataNew )
|
void Steps::SetNoteData( const NoteData& noteDataNew )
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "Grade.h"
|
#include "Grade.h"
|
||||||
#include "RadarValues.h"
|
#include "RadarValues.h"
|
||||||
#include "Difficulty.h"
|
#include "Difficulty.h"
|
||||||
|
#include "RageUtil_AutoPtr.h"
|
||||||
class Profile;
|
class Profile;
|
||||||
class NoteData;
|
class NoteData;
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
@@ -76,7 +77,7 @@ protected:
|
|||||||
/* We can have one or both of these; if we have both, they're always identical.
|
/* We can have one or both of these; if we have both, they're always identical.
|
||||||
* Call Compress() to force us to only have m_sNoteDataCompressed; otherwise, creation of
|
* Call Compress() to force us to only have m_sNoteDataCompressed; otherwise, creation of
|
||||||
* these is transparent. */
|
* these is transparent. */
|
||||||
mutable NoteData *m_pNoteData;
|
mutable HiddenPtr<NoteData> m_pNoteData;
|
||||||
mutable bool m_bNoteDataIsFilled;
|
mutable bool m_bNoteDataIsFilled;
|
||||||
mutable CString m_sNoteDataCompressed;
|
mutable CString m_sNoteDataCompressed;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user