corelib/include/ebcl/Pointers.hh

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 ::ebcl::T_OwnPtr< T_ ## NAME > OP_ ## NAME; \
typedef ::ebcl::T_SharedPtr< T_ ## NAME > SP_ ## NAME; \
typedef ::ebcl::T_WeakPtr< T_ ## NAME > WP_ ## NAME
#define M_ABSTRACT_POINTERS( NAME ) \
typedef A_ ## NAME* RP_ ## NAME; \
typedef A_ ## NAME const* RPC_ ## NAME; \
typedef ::ebcl::T_OwnPtr< A_ ## NAME > OP_ ## NAME; \
typedef ::ebcl::T_SharedPtr< A_ ## NAME > SP_ ## NAME; \
typedef ::ebcl::T_WeakPtr< A_ ## NAME > WP_ ## NAME
#define M_TEMPLATE_POINTERS( NAME ) \
typedef NAME* RP; \
typedef NAME const* RPC; \
typedef ::ebcl::T_OwnPtr< NAME > OP; \
typedef ::ebcl::T_SharedPtr< NAME > SP; \
typedef ::ebcl::T_WeakPtr< NAME > WP
} // namespace
#endif // _H_EBCL_POINTERS
#include <ebcl/inline/Pointers.hh>