423 lines
11 KiB
C++
423 lines
11 KiB
C++
/******************************************************************************/
|
|
/* POINTERS *******************************************************************/
|
|
/******************************************************************************/
|
|
|
|
#ifndef _H_EBCL_POINTERS
|
|
#define _H_EBCL_POINTERS
|
|
#include <ebcl/Utilities.hh>
|
|
namespace ebcl {
|
|
|
|
template< typename T > class T_OwnPtr;
|
|
template< typename T > class T_SharedPtr;
|
|
template< typename T > class T_WeakPtr;
|
|
|
|
/*= OWNING POINTERS ==========================================================*/
|
|
|
|
template< typename T >
|
|
class T_OwnPtr
|
|
{
|
|
template< typename RT , typename... AT >
|
|
friend T_OwnPtr< RT > NewOwned( AT&& ... arguments );
|
|
|
|
template<
|
|
typename RT
|
|
> friend T_OwnPtr< RT > OwnRawPointer( RT*& ) noexcept;
|
|
|
|
template<
|
|
typename RT , typename OT ,
|
|
T_EnableForChild< RT , OT >
|
|
> friend T_OwnPtr< RT > OwnRawPointer( OT*& ) noexcept;
|
|
|
|
template<
|
|
typename RT , typename OT ,
|
|
T_EnableForParent< RT , OT >
|
|
> friend T_OwnPtr< RT > OwnRawPointer( OT*& );
|
|
|
|
template< typename >
|
|
friend class T_OwnPtr;
|
|
|
|
friend T_SharedPtr< T >;
|
|
|
|
private:
|
|
typedef T_OwnPtr< T > MyType_;
|
|
|
|
T* p_;
|
|
|
|
T_OwnPtr( T* p ) noexcept;
|
|
|
|
public:
|
|
T_OwnPtr( );
|
|
~T_OwnPtr( );
|
|
|
|
T_OwnPtr( MyType_ const& ) = delete;
|
|
MyType_& operator= ( MyType_ const& ) = delete;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_OwnPtr( T_OwnPtr< Q >&& source ) noexcept;
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_OwnPtr( T_OwnPtr< Q >&& source );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
MyType_& operator= ( T_OwnPtr< Q >&& source ) noexcept;
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
MyType_& operator= ( T_OwnPtr< Q >&& source );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename TP >
|
|
friend void swap( T_OwnPtr< TP >& lhs , T_OwnPtr< TP >& rhs ) noexcept;
|
|
|
|
void clear( );
|
|
|
|
bool operator== ( const T* p ) const;
|
|
bool operator!= ( const T* p ) const;
|
|
operator bool ( ) const;
|
|
bool operator! ( ) const;
|
|
|
|
T * get( ) const;
|
|
T* operator-> ( ) const;
|
|
T& operator* ( ) const;
|
|
|
|
T_SharedPtr< T > makeShared( );
|
|
};
|
|
|
|
|
|
// NewOwned< T >( ... ) - New T as an owned pointer
|
|
template<
|
|
typename Type ,
|
|
typename... ArgTypes
|
|
>
|
|
T_OwnPtr< Type > NewOwned( ArgTypes&& ... arguments );
|
|
|
|
// OwnRawPointer< T >( pointer ) - Transfer a raw pointer to an owned pointer.
|
|
// The raw pointer will be set to nullptr.
|
|
template< typename Type >
|
|
T_OwnPtr< Type > OwnRawPointer( Type*& pointer ) noexcept;
|
|
|
|
template<
|
|
typename Type , typename Other ,
|
|
T_EnableForChild< Type , Other > = true ,
|
|
std::enable_if_t< !std::is_same< Type , Other >::value , bool > = true
|
|
> T_OwnPtr< Type > OwnRawPointer( Other*& pointer ) noexcept;
|
|
|
|
template<
|
|
typename Type , typename Other ,
|
|
T_EnableForParent< Type , Other > = false
|
|
> T_OwnPtr< Type > OwnRawPointer( Other*& pointer );
|
|
|
|
|
|
/*= SHARED POINTERS ==========================================================*/
|
|
/* WARNING: these pointers are NOT thread-safe! */
|
|
|
|
class T_Reference_;
|
|
|
|
// Weak pointer chaining
|
|
struct T_WeakChain_
|
|
{
|
|
T_Reference_* * const ref;
|
|
T_WeakChain_* prev;
|
|
T_WeakChain_* next;
|
|
|
|
explicit T_WeakChain_( T_Reference_*& ref );
|
|
void unchain( );
|
|
void init( );
|
|
};
|
|
|
|
|
|
// Base class for shared and weak pointers
|
|
template< typename T >
|
|
class T_BasePtr_
|
|
{
|
|
protected:
|
|
typedef T_BasePtr_< T > T_Base_;
|
|
|
|
T_Reference_* ref_;
|
|
|
|
explicit T_BasePtr_( T_Reference_* ref ) noexcept;
|
|
|
|
T_BasePtr_( ) = delete;
|
|
T_BasePtr_( T_Base_ const& ) = delete;
|
|
T_BasePtr_( T_Base_&& ) = delete;
|
|
|
|
public:
|
|
operator bool ( ) const;
|
|
bool operator! ( ) const;
|
|
|
|
T* operator-> ( ) const;
|
|
explicit operator T* ( ) const;
|
|
T& operator* ( ) const;
|
|
};
|
|
|
|
|
|
// Exception thrown when makeOwned( ) is called on a shared pointers that has
|
|
// more than one reference.
|
|
class X_TooManyReferences : public std::runtime_error
|
|
{
|
|
public:
|
|
X_TooManyReferences( );
|
|
};
|
|
|
|
|
|
// T_SharedPtr< T > - Shared pointer implementation
|
|
template< typename T >
|
|
class T_SharedPtr : public T_BasePtr_< T >
|
|
{
|
|
private:
|
|
typedef T_BasePtr_< T > T_Base_;
|
|
typedef T_SharedPtr< T > T_Self_;
|
|
typedef T_WeakPtr< T > T_Weak_;
|
|
|
|
template< typename >
|
|
friend class T_SharedPtr;
|
|
|
|
template< typename >
|
|
friend class T_WeakPtr;
|
|
|
|
template<
|
|
typename RT
|
|
> friend T_SharedPtr< RT > ShareRawPointer( RT*& ) noexcept;
|
|
|
|
template<
|
|
typename RT , typename OT ,
|
|
T_EnableForChild< RT , OT >
|
|
> friend T_SharedPtr< RT > ShareRawPointer( OT*& ) noexcept;
|
|
|
|
template<
|
|
typename RT , typename OT ,
|
|
T_EnableForParent< RT , OT >
|
|
> friend T_SharedPtr< RT > ShareRawPointer( OT*& );
|
|
|
|
template< typename OT , typename... AT >
|
|
friend T_SharedPtr< OT > NewShared( AT&& ... arguments );
|
|
friend T_OwnPtr< T >;
|
|
|
|
using T_Base_::ref_;
|
|
|
|
T_Reference_ * setRef( T_Reference_* from );
|
|
void clearRef( );
|
|
|
|
explicit T_SharedPtr( T* ptr );
|
|
|
|
public:
|
|
T_SharedPtr( ) noexcept;
|
|
~T_SharedPtr( );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Copy constructors
|
|
|
|
T_SharedPtr( T_Self_ const& source );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_SharedPtr( T_SharedPtr< Q > const& source );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_SharedPtr( T_SharedPtr< Q > const& source );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Move constructors
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_SharedPtr( T_SharedPtr< Q >&& source ) noexcept;
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_SharedPtr( T_SharedPtr< Q >&& source );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Copy assignment operators
|
|
|
|
T_Self_& operator= ( T_Self_ const& other );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_Self_& operator= ( T_SharedPtr< Q > const& other );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
T_Self_& operator= ( T_SharedPtr< Q > const& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Move assignment operators
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_Self_& operator= ( T_SharedPtr< Q >&& other ) noexcept;
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
T_Self_& operator= ( T_SharedPtr< Q >&& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename TP >
|
|
friend void swap( T_SharedPtr< TP >& lhs , T_SharedPtr< TP >& rhs ) noexcept;
|
|
|
|
bool operator== ( T_Self_ const& other ) const;
|
|
bool operator!= ( T_Self_ const& other ) const;
|
|
bool operator== ( T_Weak_ const& other ) const;
|
|
bool operator!= ( T_Weak_ const& other ) const;
|
|
|
|
void clear( );
|
|
|
|
T_OwnPtr< T > makeOwned( );
|
|
};
|
|
|
|
|
|
// T_WeakPtr< T > - Weak pointer implementation
|
|
template< typename T >
|
|
class T_WeakPtr : public T_BasePtr_< T >
|
|
{
|
|
private:
|
|
typedef T_BasePtr_< T > T_Base_;
|
|
typedef T_SharedPtr< T > T_Shared_;
|
|
typedef T_WeakPtr< T > T_Self_;
|
|
|
|
template< typename > friend class T_SharedPtr;
|
|
template< typename > friend class T_WeakPtr;
|
|
friend T_Reference_;
|
|
|
|
using T_Base_::ref_;
|
|
|
|
T_WeakChain_ chain_;
|
|
|
|
T_WeakPtr( T_Reference_* ref );
|
|
|
|
public:
|
|
|
|
T_WeakPtr( );
|
|
~T_WeakPtr( );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Copy constructors
|
|
|
|
T_WeakPtr( T_Self_ const& other );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_WeakPtr( T_WeakPtr< Q > const& other );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_WeakPtr( T_WeakPtr< Q > const& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Move constructors
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_WeakPtr( T_WeakPtr< Q >&& other ) noexcept;
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_WeakPtr( T_WeakPtr< Q >&& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Construct from shared pointer
|
|
|
|
explicit T_WeakPtr( T_Shared_ const& shared );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
explicit T_WeakPtr( T_SharedPtr< Q > const& shared );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
explicit T_WeakPtr( T_SharedPtr< Q > const& shared );
|
|
|
|
explicit T_WeakPtr( T_Shared_&& shared ) = delete;
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Copy assignment operators
|
|
|
|
T_Self_& operator= ( T_Self_ const& other );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_Self_& operator =( T_WeakPtr< Q > const& other );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
T_Self_& operator =( T_WeakPtr< Q > const& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Move assignment operators
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_Self_& operator =( T_WeakPtr< Q >&& other );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
T_Self_& operator =( T_WeakPtr< Q >&& other );
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Assign from shared pointer
|
|
|
|
T_Self_& operator= ( T_Shared_ const& shared );
|
|
|
|
template< typename Q , T_EnableForChild< T , Q > = true >
|
|
T_Self_& operator= ( T_SharedPtr< Q > const& shared );
|
|
|
|
template< typename Q , T_EnableForParent< T , Q > = false >
|
|
T_Self_& operator= ( T_SharedPtr< Q > const& shared );
|
|
|
|
T_Self_& operator= ( T_Shared_&& ) = delete;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename TP >
|
|
friend void swap( T_WeakPtr< TP >& lhs , T_WeakPtr< TP >& rhs );
|
|
|
|
bool operator== ( T_Self_ const& other ) const;
|
|
bool operator!= ( T_Self_ const& other ) const;
|
|
bool operator== ( T_Shared_ const& other ) const;
|
|
bool operator!= ( T_Shared_ const& other ) const;
|
|
|
|
void clear( );
|
|
};
|
|
|
|
|
|
// NewShared< T >( ... ) - New T as shared pointer
|
|
template<
|
|
typename Type ,
|
|
typename... ArgTypes
|
|
>
|
|
T_SharedPtr< Type > NewShared( ArgTypes&& ... arguments );
|
|
|
|
// ShareRawPointer< T >( pointer ) - Transfer a raw pointer to a shared pointer.
|
|
// The raw pointer will be set to nullptr.
|
|
template< typename Type >
|
|
T_SharedPtr< Type > ShareRawPointer(
|
|
Type*& pointer ) noexcept;
|
|
|
|
template<
|
|
typename Type , typename Other ,
|
|
T_EnableForChild< Type , Other > = true ,
|
|
std::enable_if_t< !std::is_same< Type , Other >::value , bool > = true
|
|
> T_SharedPtr< Type > ShareRawPointer(
|
|
Other*& pointer ) noexcept;
|
|
|
|
template<
|
|
typename Type , typename Other ,
|
|
T_EnableForParent< Type , Other > = false
|
|
> T_SharedPtr< Type > ShareRawPointer( Other*& pointer );
|
|
|
|
|
|
/*= HELPER MACROS ============================================================*/
|
|
|
|
#define M_CLASS_POINTERS( NAME ) \
|
|
typedef T_ ## NAME* RP_ ## NAME; \
|
|
typedef T_ ## NAME const* RPC_ ## NAME; \
|
|
typedef T_OwnPtr< T_ ## NAME > OP_ ## NAME; \
|
|
typedef T_SharedPtr< T_ ## NAME > SP_ ## NAME; \
|
|
typedef T_WeakPtr< T_ ## NAME > WP_ ## NAME
|
|
|
|
#define M_ABSTRACT_POINTERS( NAME ) \
|
|
typedef A_ ## NAME* RP_ ## NAME; \
|
|
typedef A_ ## NAME const* RPC_ ## NAME; \
|
|
typedef T_OwnPtr< A_ ## NAME > OP_ ## NAME; \
|
|
typedef T_SharedPtr< A_ ## NAME > SP_ ## NAME; \
|
|
typedef T_WeakPtr< A_ ## NAME > WP_ ## NAME
|
|
|
|
#define M_TEMPLATE_POINTERS( NAME ) \
|
|
typedef NAME* RP; \
|
|
typedef NAME const* RPC; \
|
|
typedef T_OwnPtr< NAME > OP; \
|
|
typedef T_SharedPtr< NAME > SP; \
|
|
typedef T_WeakPtr< NAME > WP
|
|
|
|
|
|
} // namespace
|
|
#endif // _H_EBCL_POINTERS
|
|
#include <ebcl/inline/Pointers.hh>
|