#ifndef __SYNTHETIC_UTIL_IRRPTR_HPP__ #define __SYNTHETIC_UTIL_IRRPTR_HPP__ 1 // C++ Standard Library: #include // Irrlicht: #include namespace synthetic { namespace util { /** * @brief A smart-pointer type for reference-counted Irrlicht objects. **/ template class irr_ptr : std::enable_if::value> { public: typedef typename std::remove_pointer< IrrlichtReferenceCounted>::type element_type; typedef element_type* pointer; typedef element_type const* const_pointer; private: pointer m_ptr; void grab() { if(m_ptr) m_ptr->grab(); } void drop() { if(m_ptr) m_ptr->drop(); } public: // Construction and destruction. irr_ptr() : m_ptr(0) { } explicit irr_ptr(pointer ptr) : m_ptr(ptr) { } ~irr_ptr() { drop(); } // Copying. irr_ptr(irr_ptr const& other) : m_ptr(other.m_ptr) { grab(); } irr_ptr& operator=(irr_ptr const& other) { reset(other.m_ptr); } // Moving. irr_ptr(irr_ptr&& other) : m_ptr(other.m_ptr) { other.m_ptr = 0; } irr_ptr& operator=(irr_ptr&& other) { reset(other.m_ptr); other.m_ptr = 0; } // Operations. void reset(pointer ptr = pointer()) { if(ptr != m_ptr) { drop(); m_ptr = ptr; grab(); } } void release() { drop(); m_ptr = 0; } void swap(irr_ptr& other) { pointer hlp = other.m_ptr; other.m_ptr = m_ptr; m_ptr = other.m_ptr; } // Operator overloads. pointer get() { return m_ptr; } const_pointer get() const { return m_ptr; } element_type& operator*() { return *m_ptr; } element_type const& operator*() const { return *m_ptr; } pointer operator->() { return m_ptr; } const_pointer operator->() const { return m_ptr; } explicit operator bool() const { return (m_ptr != 0); } }; } } namespace std { template void swap( ::synthetic::util::irr_ptr& p1, ::synthetic::util::irr_ptr& p2) { p1.swap(p2); } } #endif // __SYNTHETIC_UTIL_IRRPTR_HPP__