ref.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "atomic.h"
  18. namespace embree
  19. {
  20. static struct NullTy {
  21. } null MAYBE_UNUSED;
  22. class RefCount
  23. {
  24. public:
  25. RefCount(int val = 0) : refCounter(val) {}
  26. virtual ~RefCount() {};
  27. virtual void refInc() { refCounter.fetch_add(1); }
  28. virtual void refDec() { if (refCounter.fetch_add(-1) == 1) delete this; }
  29. private:
  30. std::atomic<size_t> refCounter;
  31. };
  32. ////////////////////////////////////////////////////////////////////////////////
  33. /// Reference to single object
  34. ////////////////////////////////////////////////////////////////////////////////
  35. template<typename Type>
  36. class Ref {
  37. public:
  38. Type* const ptr;
  39. ////////////////////////////////////////////////////////////////////////////////
  40. /// Constructors, Assignment & Cast Operators
  41. ////////////////////////////////////////////////////////////////////////////////
  42. __forceinline Ref( void ) : ptr(nullptr) {}
  43. __forceinline Ref(NullTy) : ptr(nullptr) {}
  44. __forceinline Ref( const Ref& input ) : ptr(input.ptr) { if ( ptr ) ptr->refInc(); }
  45. __forceinline Ref( Type* const input ) : ptr(input) {
  46. if ( ptr )
  47. ptr->refInc();
  48. }
  49. __forceinline ~Ref( void ) {
  50. if (ptr) ptr->refDec();
  51. }
  52. __forceinline Ref& operator= ( const Ref& input )
  53. {
  54. if ( input.ptr ) input.ptr->refInc();
  55. if (ptr) ptr->refDec();
  56. *(Type**)&ptr = input.ptr;
  57. return *this;
  58. }
  59. __forceinline Ref& operator= ( Type* const input )
  60. {
  61. if ( input ) input->refInc();
  62. if (ptr) ptr->refDec();
  63. *(Type**)&ptr = input;
  64. return *this;
  65. }
  66. __forceinline Ref& operator= ( NullTy ) {
  67. if (ptr) ptr->refDec();
  68. *(Type**)&ptr = nullptr;
  69. return *this;
  70. }
  71. __forceinline operator bool( void ) const { return ptr != nullptr; }
  72. __forceinline const Type& operator *( void ) const { return *ptr; }
  73. __forceinline Type& operator *( void ) { return *ptr; }
  74. __forceinline const Type* operator ->( void ) const { return ptr; }
  75. __forceinline Type* operator ->( void ) { return ptr; }
  76. template<typename TypeOut>
  77. __forceinline Ref<TypeOut> cast() { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }
  78. template<typename TypeOut>
  79. __forceinline const Ref<TypeOut> cast() const { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }
  80. template<typename TypeOut>
  81. __forceinline Ref<TypeOut> dynamicCast() { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }
  82. template<typename TypeOut>
  83. __forceinline const Ref<TypeOut> dynamicCast() const { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }
  84. };
  85. template<typename Type> __forceinline bool operator < ( const Ref<Type>& a, const Ref<Type>& b ) { return a.ptr < b.ptr ; }
  86. template<typename Type> __forceinline bool operator ==( const Ref<Type>& a, NullTy ) { return a.ptr == nullptr ; }
  87. template<typename Type> __forceinline bool operator ==( NullTy , const Ref<Type>& b ) { return nullptr == b.ptr ; }
  88. template<typename Type> __forceinline bool operator ==( const Ref<Type>& a, const Ref<Type>& b ) { return a.ptr == b.ptr ; }
  89. template<typename Type> __forceinline bool operator !=( const Ref<Type>& a, NullTy ) { return a.ptr != nullptr ; }
  90. template<typename Type> __forceinline bool operator !=( NullTy , const Ref<Type>& b ) { return nullptr != b.ptr ; }
  91. template<typename Type> __forceinline bool operator !=( const Ref<Type>& a, const Ref<Type>& b ) { return a.ptr != b.ptr ; }
  92. }