/******************************************************************************/ /* REFERENCE-COUNTING HELPERS *************************************************/ /******************************************************************************/ #ifndef _H_EBCL_REFCOUNT #define _H_EBCL_REFCOUNT #include namespace ebcl { // A base class and pointer type that can be used to implement classes which // use in-instance reference counters. /*= REFERENCE-COUNTED INSTANCES ==============================================*/ // Base class containing the reference counter. It may be an atomic, or it // may be a simple integer. template< bool UseAtomic = false > class T_ReferenceCountedClass { public: // Is it atomic ? static const bool UsingAtomic = UseAtomic; // Reference counter type using T_ReferenceCounter = std::conditional_t< UseAtomic , std::atomic< uint32_t > , uint32_t >; // Reference-counting pointers can access the counter template< typename > friend class T_RcPtr; private: T_ReferenceCounter referenceCounter_; // Add a reference to the counter void increaseReferences_( ) noexcept; // Remove a reference from the counter, returning true if the instance // is no longer referenced. bool decreaseReferences_( ) noexcept; protected: T_ReferenceCountedClass( ) noexcept; }; // Shortcuts using T_AtomicRcClass = T_ReferenceCountedClass< true >; using T_SimpleRcClass = T_ReferenceCountedClass< false >; /*= REFERENCE-COUNTING POINTERS ==============================================*/ // Pointers that use T_ReferenceCountedClass in order to track the reference // counts of the instances it manages. template< typename Type > class T_RcPtr { static_assert( MetaOr< std::is_base_of< T_AtomicRcClass , Type > , std::is_base_of< T_SimpleRcClass , Type > >::value , "type does not include a reference counter" ); public: // Target type using T_Target = Type; // Pointer type using T_Self = T_RcPtr< Type >; // Base reference counting class using T_RcClass = std::conditional_t< std::is_base_of< T_AtomicRcClass , Type >::value , T_AtomicRcClass , T_SimpleRcClass >; private: T_Target* target_; public: // --------------------------------------------------------------------- T_RcPtr( ) noexcept; ~T_RcPtr( ) noexcept; void clear( ) noexcept; // --------------------------------------------------------------------- // Copy constructors T_RcPtr( T_Self const& other ) noexcept; template< typename Q , T_EnableForChild< Type , Q > = true > T_RcPtr( T_RcPtr< Q > const& source ) noexcept; template< typename Q , T_EnableForParent< Type , Q > = false > explicit T_RcPtr( T_RcPtr< Q > const& source ); // --------------------------------------------------------------------- // Move constructors template< typename Q , T_EnableForChild< Type , Q > = true > T_RcPtr( T_RcPtr< Q >&& other ) noexcept; template< typename Q , T_EnableForParent< Type , Q > = false > explicit T_RcPtr( T_RcPtr< Q >&& other ); }; } // namespace #endif // _H_EBCL_REFCOUNT #include