/******************************************************************************/ /* POINTERS *******************************************************************/ /******************************************************************************/ #ifndef _H_EBCL_POINTERS #define _H_EBCL_POINTERS #include 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