Advertisement
Delfigamer

utils/ref.cpp

Feb 24th, 2015
596
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.02 KB | None | 0 0
  1. #include "ref.hpp"
  2. #include "logger.hpp"
  3. #include <atomic>
  4. #include <exception>
  5. #include <stdexcept>
  6. #include <utility>
  7.  
  8. #undef LOG
  9. #define LOG( ... )
  10.  
  11. namespace utils {
  12.     RefBase::RefBase() noexcept :
  13.         m_ref( ( RefObject* )0 ) {
  14.         LOG( "< Ref: %#10x : %#10x >\tRef()",
  15.             uint32_t( this ), 0 );
  16.     }
  17.    
  18.     RefBase::RefBase( RefObject* ref ) noexcept :
  19.         m_ref( ( RefObject* )0 ) {
  20.         LOG( "< Ref: %#10x : %#10x >\tRef( %#10x )",
  21.             uint32_t( this ), 0, uint32_t( ref ) );
  22.         assign_silent( ref );
  23.     }
  24.    
  25.     RefBase::RefBase( RefObject* ref, int ) noexcept :
  26.         m_ref( ref ) {
  27.         LOG( "< Ref: %#10x : %#10x >\tRef( %#10x, int() )",
  28.             uint32_t( this ), 0, uint32_t( ref ) );
  29.     }
  30.    
  31.     RefBase::RefBase( RefObject* ref, int, int id ) noexcept :
  32.         m_ref( ( RefObject* )0 ) {
  33.         LOG( "< Ref: %#10x : %#10x >\tRef( %#10x, int(), %#.8x )",
  34.             uint32_t( this ), 0, uint32_t( ref ), id );
  35.         assign_silent( ref, id );
  36.     }
  37.    
  38.     RefBase::RefBase( RefBase&& other ) noexcept :
  39.         m_ref( ( RefObject* )0 ) {
  40.         RefObject* ref = other.m_ref.exchange( 0, std::memory_order_relaxed );
  41.         possess_silent( ref );
  42.         LOG( "< Ref: %#10x : %#10x >\tRef( std::move( < Ref: %#10x : %#10x > ) )",
  43.             uint32_t( this ), 0, uint32_t( &other ), uint32_t( ref ) );
  44.     }
  45.    
  46.     RefBase::RefBase( RefBase const& other ) noexcept :
  47.         m_ref( ( RefObject* )0 ) {
  48.         RefObject* ref = other.m_ref.load( std::memory_order_relaxed );
  49.         LOG( "< Ref: %#10x : %#10x >\tRef( < Ref: %#10x : %#10x > )",
  50.             uint32_t( this ), 0, uint32_t( &other ), uint32_t( ref ) );
  51.         assign_silent( ref );
  52.     }
  53.    
  54.     RefBase::RefBase( RefBase const& other, int id ) noexcept :
  55.         m_ref( ( RefObject* )0 ) {
  56.         RefObject* ref = other.m_ref.load( std::memory_order_relaxed );
  57.         LOG( "< Ref: %#10x : %#10x >\tRef( < Ref: %#10x : %#10x >, %#.8x )",
  58.             uint32_t( this ), 0, uint32_t( &other ), uint32_t( ref ), id );
  59.         assign_silent( ref, id );
  60.     }
  61.    
  62.     RefBase::~RefBase() noexcept {
  63.         RefObject* oldref = m_ref.exchange( 0, std::memory_order_relaxed );
  64.         if( oldref ) {
  65.             oldref->release();
  66.         }
  67.         LOG( "< Ref: %#10x : %#10x >\t~Ref()",
  68.             uint32_t( this ), uint32_t( oldref ) );
  69.     }
  70.    
  71.     RefObject* RefBase::possess_silent( RefObject* ref ) noexcept {
  72.         RefObject* oldref;
  73.         oldref = m_ref.exchange( ref, std::memory_order_relaxed );
  74.         if( oldref ) {
  75.             oldref->release();
  76.         }
  77.         return oldref;
  78.     }
  79.    
  80.     RefObject* RefBase::assign_silent( RefObject* ref ) noexcept {
  81.         if( ref ) {
  82.             ref->addref();
  83.         }
  84.         RefObject* oldref = m_ref.exchange( ref, std::memory_order_relaxed );
  85.         if( oldref ) {
  86.             oldref->release();
  87.         }
  88.         return oldref;
  89.     }
  90.    
  91.     RefObject* RefBase::assign_silent( RefObject* ref, int id ) noexcept {
  92.         RefObject* newref;
  93.         if( ref ) {
  94.             if( !ref->query( id, ( void** )&newref ) ) {
  95.                 throw std::runtime_error( "RefObject cast failure" );
  96.             }
  97.         } else {
  98.             newref = 0;
  99.         }
  100.         return possess_silent( newref );
  101.     }
  102.    
  103.     RefObject* RefBase::possess( RefObject* ref ) noexcept {
  104.         RefObject* oldref = possess_silent( ref );
  105.         LOG( "< Ref: %#10x : %#10x >\tpossess( %#10x )",
  106.             uint32_t( this ), uint32_t( oldref ), uint32_t( ref ) );
  107.         return oldref;
  108.     }
  109.    
  110.     RefObject* RefBase::assign( RefObject* ref ) noexcept {
  111.         RefObject* oldref = assign_silent( ref );
  112.         LOG( "< Ref: %#10x : %#10x >\tassign( %#10x )",
  113.             uint32_t( this ), uint32_t( oldref ), uint32_t( ref ) );
  114.         return oldref;
  115.     }
  116.    
  117.     RefObject* RefBase::assign( RefObject* ref, int id ) noexcept {
  118.         RefObject* oldref = assign_silent( ref, id );
  119.         LOG( "< Ref: %#10x : %#10x >\tassign( %#10x, %#.8x )",
  120.             uint32_t( this ), uint32_t( oldref ), uint32_t( ref ), id );
  121.         return oldref;
  122.     }
  123.    
  124.     RefBase& RefBase::assign( RefBase&& other ) noexcept {
  125.         RefObject* ref = other.m_ref.exchange( 0, std::memory_order_relaxed );
  126.         RefObject* oldref = possess_silent( ref );
  127.         LOG( "< Ref: %#10x : %#10x >\tassign( std::move( < Ref: %#10x : %#10x > ) )",
  128.             uint32_t( this ), uint32_t( oldref ), uint32_t( &other ), uint32_t( ref ) );
  129.         ( void )oldref;
  130.         return *this;
  131.     }
  132.    
  133.     RefBase& RefBase::assign( RefBase const& other ) noexcept {
  134.         RefObject* ref = other.m_ref.load( std::memory_order_relaxed );
  135.         RefObject* oldref = assign_silent( ref );
  136.         LOG( "< Ref: %#10x : %#10x >\tassign( < Ref: %#10x : %#10x > )",
  137.             uint32_t( this ), uint32_t( oldref ), uint32_t( &other ), uint32_t( ref ) );
  138.         ( void )oldref;
  139.         return *this;
  140.     }
  141.    
  142.     RefBase& RefBase::assign( RefBase const& other, int id ) noexcept {
  143.         RefObject* ref = other.m_ref.load( std::memory_order_relaxed );
  144.         RefObject* oldref = assign_silent( ref, id );
  145.         LOG( "< Ref: %#10x : %#10x >\tassign( < Ref: %#10x : %#10x >, %#.8x )",
  146.             uint32_t( this ), uint32_t( oldref ), uint32_t( &other ), uint32_t( ref ), id );
  147.         ( void )oldref;
  148.         return *this;
  149.     }
  150.    
  151.     RefObject* RefBase::get() const noexcept {
  152.         RefObject* ref = m_ref.load( std::memory_order_relaxed );
  153.         LOG( "< Ref: %#10x : %#10x >\tget()", uint32_t( this ), uint32_t( ref ) );
  154.         return ref;
  155.     }
  156.    
  157.     RefObject& RefBase::deref() const {
  158.         RefObject* ref = m_ref.load( std::memory_order_relaxed );
  159.         LOG( "< Ref: %#10x : %#10x >\tderef()", uint32_t( this ), uint32_t( ref ) );
  160.         if( ref ) {
  161.             return *ref;
  162.         } else {
  163.             throw std::runtime_error( "dereferencing an empty Ref" );
  164.         }
  165.     }
  166.    
  167.     bool RefBase::operator==( RefBase const& other ) {
  168.         return m_ref.load( std::memory_order_relaxed ) == other.m_ref.load( std::memory_order_relaxed );
  169.     }
  170.    
  171.     bool RefBase::operator!=( RefBase const& other ) {
  172.         return !( *this == other );
  173.     }
  174.    
  175.     Ref< RefObject >::Ref() noexcept :
  176.         RefBase() {
  177.     }
  178.    
  179.     Ref< RefObject >::Ref( RefObject* ref ) noexcept :
  180.         RefBase( ref ) {
  181.     }
  182.    
  183.     Ref< RefObject >::Ref( RefObject* ref, int ) noexcept :
  184.         RefBase( ref, 0 ) {
  185.     }
  186.    
  187.     Ref< RefObject >::Ref( Ref< RefObject > const& other ) noexcept :
  188.         RefBase( other ) {
  189.     }
  190.    
  191.     Ref< RefObject >::Ref( RefBase const& other ) noexcept :
  192.         RefBase( other ) {
  193.     }
  194.    
  195.     Ref< RefObject >::Ref( Ref< RefObject >&& other ) noexcept :
  196.         RefBase( std::move( other ) ) {
  197.     }
  198.    
  199.     Ref< RefObject >::Ref( RefBase&& other ) noexcept :
  200.         RefBase( std::move( other ) ) {
  201.     }
  202.    
  203.     Ref< RefObject >::~Ref() noexcept {
  204.     }
  205.    
  206.     Ref< RefObject >& Ref< RefObject >::operator=( RefObject* ref ) noexcept {
  207.         RefBase::assign( ref );
  208.         return *this;
  209.     }
  210.    
  211.     Ref< RefObject >& Ref< RefObject >::operator=( Ref< RefObject > const& other ) noexcept {
  212.         RefBase::assign( other );
  213.         return *this;
  214.     }
  215.    
  216.     Ref< RefObject >& Ref< RefObject >::operator=( RefBase const& other ) noexcept {
  217.         RefBase::assign( other );
  218.         return *this;
  219.     }
  220.    
  221.     Ref< RefObject >& Ref< RefObject >::operator=( Ref< RefObject >&& other ) noexcept {
  222.         RefBase::assign( std::move( other ) );
  223.         return *this;
  224.     }
  225.    
  226.     Ref< RefObject >& Ref< RefObject >::operator=( RefBase&& other ) noexcept {
  227.         RefBase::assign( std::move( other ) );
  228.         return *this;
  229.     }
  230.    
  231.     RefObject& Ref< RefObject >::operator*() const {
  232.         return RefBase::deref();
  233.     }
  234.    
  235.     RefObject* Ref< RefObject >::operator->() const {
  236.         return &RefBase::deref();
  237.     }
  238.    
  239.     Ref< RefObject >::operator RefObject*() const noexcept {
  240.         return RefBase::get();
  241.     }
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement