Advertisement
Delfigamer

utils/refobject.hpp

Feb 24th, 2015
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.58 KB | None | 0 0
  1. #ifndef UTILS_REFOBJECT_HPP__
  2. #define UTILS_REFOBJECT_HPP__
  3.  
  4. #include <cstdio>
  5. #include <atomic>
  6.  
  7. #define DEFINE_REFID( type, ptype, refid ) \
  8.     namespace utils { \
  9.         template<> struct RefId< type > { \
  10.             enum e { \
  11.                 id = int( refid ) \
  12.             }; \
  13.             typedef ptype parent; \
  14.         }; \
  15.     }
  16.  
  17. namespace utils {
  18.     template< typename T >
  19.     struct RefId {
  20.         enum e {id = 0};
  21.         typedef void parent;
  22.     };
  23.    
  24.     template< typename T >
  25.     bool queryobject( T* source, int id, void** target ) {
  26.         if( id == RefId< T >::id ) {
  27.             *target = static_cast< T* >( source );
  28.             source->addref();
  29.             return true;
  30.         } else {
  31.             return queryobject< typename RefId< T >::parent >( source, id, target );
  32.         }
  33.     }
  34.    
  35.     class RefObject {
  36.     protected:
  37.         mutable std::atomic< int > m_refcount;
  38.        
  39.     public:
  40.         int addref() const noexcept;
  41.         int release() const noexcept;
  42.         int refcount() const noexcept;
  43.         virtual bool query( int id, void** target );
  44.         RefObject() noexcept;
  45.         RefObject( RefObject const& other ) noexcept;
  46.         RefObject( RefObject&& other ) noexcept;
  47.         virtual ~RefObject() noexcept;
  48.         virtual void destroy();
  49.         RefObject& operator=( RefObject const& other ) noexcept;
  50.         RefObject& operator=( RefObject&& other ) noexcept;
  51.     };
  52. }
  53.  
  54. DEFINE_REFID( utils::RefObject, void, 0x487e69d6 )
  55.  
  56. namespace utils {
  57.     inline int RefObject::addref() const noexcept {
  58.         int rc = m_refcount.fetch_add( 1, std::memory_order_relaxed ) + 1;
  59. //      LOG( "((RefObject*) %#10x)->addref()  - %i", uint32_t( this ), rc );
  60. //      if( rc == 1 ) {
  61. //          LOG( "RefObject is brought undead! 0x%x", uint32_t( this ) );
  62. //      }
  63.         return rc;
  64.     }
  65.    
  66.     inline int RefObject::release() const noexcept {
  67.         int rc = m_refcount.fetch_sub( 1, std::memory_order_relaxed ) - 1;
  68. //      LOG( "((RefObject*) %#10x)->release() - %i", uint32_t( this ), rc );
  69.         if( rc == 0 ) {
  70.             const_cast< RefObject* >( this )->destroy();
  71.         }
  72.         return rc;
  73.     }
  74.    
  75.     inline int RefObject::refcount() const noexcept {
  76.         return m_refcount.load( std::memory_order_relaxed );
  77.     }
  78.    
  79. //  template<> bool queryobject< RefObject >( RefObject* source, int id, void** target );
  80.     template<> bool queryobject< void >( void* source, int id, void** target );
  81.        
  82.     template< typename T, typename S >
  83.     T* refptr_cast( S* s ) {
  84.         if( s ) {
  85.             T* result;
  86.             s->query( RefId< T >::id, ( void** )&result );
  87.             return result;
  88.         } else {
  89.             return 0;
  90.         }
  91.     }
  92. }
  93.  
  94. extern "C" {
  95.     int refobject_addref( utils::RefObject* ro ) noexcept;
  96.     int refobject_release( utils::RefObject* ro ) noexcept;
  97.     utils::RefObject* refobject_refcast( utils::RefObject* ro, int id ) noexcept;
  98. }
  99.  
  100. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement