1. #ifndef __SYNTHETIC_UTIL_IRRPTR_HPP__
  2. #define __SYNTHETIC_UTIL_IRRPTR_HPP__ 1
  3.  
  4. // C++ Standard Library:
  5. #include <type_traits>
  6.  
  7. // Irrlicht:
  8. #include <irrlicht/IReferenceCounted.h>
  9.  
  10. namespace synthetic
  11. {
  12.    namespace util
  13.    {
  14.       /**
  15.       * @brief A smart-pointer type for reference-counted Irrlicht objects.
  16.       **/
  17.       template<typename IrrlichtReferenceCounted>
  18.       class irr_ptr : std::enable_if<std::is_base_of<irr::IReferenceCounted,
  19.                            IrrlichtReferenceCounted>::value>
  20.       {
  21.       public:
  22.          typedef typename std::remove_pointer<
  23.             IrrlichtReferenceCounted>::type element_type;
  24.          typedef element_type* pointer;
  25.          typedef element_type const* const_pointer;
  26.    
  27.       private:
  28.          pointer m_ptr;
  29.    
  30.          void grab()
  31.          {
  32.             if(m_ptr) m_ptr->grab();
  33.          }
  34.    
  35.          void drop()
  36.          {
  37.             if(m_ptr) m_ptr->drop();
  38.          }
  39.    
  40.       public:
  41.    
  42.          // Construction and destruction.
  43.          irr_ptr()
  44.             : m_ptr(0)
  45.          { }
  46.    
  47.          explicit irr_ptr(pointer ptr)
  48.             : m_ptr(ptr)
  49.          { }
  50.    
  51.          ~irr_ptr()
  52.          {
  53.             drop();
  54.          }
  55.    
  56.          // Copying.
  57.          irr_ptr(irr_ptr<element_type> const& other)
  58.             : m_ptr(other.m_ptr)
  59.          {
  60.             grab();
  61.          }
  62.    
  63.          irr_ptr<element_type>& operator=(irr_ptr<element_type> const& other)
  64.          {
  65.             reset(other.m_ptr);
  66.          }
  67.    
  68.          // Moving.
  69.          irr_ptr(irr_ptr<element_type>&& other)
  70.             : m_ptr(other.m_ptr)
  71.          {
  72.             other.m_ptr = 0;
  73.          }
  74.    
  75.          irr_ptr<element_type>& operator=(irr_ptr<element_type>&& other)
  76.          {
  77.             reset(other.m_ptr);
  78.             other.m_ptr = 0;
  79.          }
  80.    
  81.          // Operations.
  82.          void reset(pointer ptr = pointer())
  83.          {
  84.             if(ptr != m_ptr)
  85.             {
  86.                 drop();
  87.                 m_ptr = ptr;
  88.                 grab();
  89.             }
  90.          }
  91.    
  92.          void release()
  93.          {
  94.             drop();
  95.             m_ptr = 0;
  96.          }
  97.    
  98.          void swap(irr_ptr<element_type>& other)
  99.          {
  100.             pointer hlp = other.m_ptr;
  101.             other.m_ptr = m_ptr;
  102.             m_ptr = other.m_ptr;
  103.          }
  104.    
  105.          // Operator overloads.
  106.          pointer get()
  107.          {
  108.             return m_ptr;
  109.          }
  110.    
  111.          const_pointer get() const
  112.          {
  113.             return m_ptr;
  114.          }
  115.    
  116.          element_type& operator*()
  117.          {
  118.             return *m_ptr;
  119.          }
  120.    
  121.          element_type const& operator*() const
  122.          {
  123.             return *m_ptr;
  124.          }
  125.    
  126.          pointer operator->()
  127.          {
  128.             return m_ptr;
  129.          }
  130.    
  131.          const_pointer operator->() const
  132.          {
  133.             return m_ptr;
  134.          }
  135.    
  136.          explicit operator bool() const
  137.          {
  138.             return (m_ptr != 0);
  139.          }
  140.       };
  141.    }
  142. }
  143.  
  144. namespace std
  145. {
  146.    template<class IrrlichtReferenceCounted>
  147.    void swap(  ::synthetic::util::irr_ptr<IrrlichtReferenceCounted>& p1,
  148.                ::synthetic::util::irr_ptr<IrrlichtReferenceCounted>& p2)
  149.    {
  150.       p1.swap(p2);
  151.    }
  152. }
  153.  
  154. #endif // __SYNTHETIC_UTIL_IRRPTR_HPP__