/*++ Copyright (c) 2006 Microsoft Corporation Module Name: obj_ref.h Abstract: Smart pointer. Author: Leonardo de Moura (leonardo) 2008-01-03. Revision History: --*/ #ifndef _OBJ_REF_H_ #define _OBJ_REF_H_ /** Smart pointer for T objects. TManager must provide the functions: - void dec_ref(T * obj) - void inc_ref(T * obj) */ template class obj_ref { T * m_obj; TManager & m_manager; void dec_ref() { if (m_obj) m_manager.dec_ref(m_obj); } void inc_ref() { if (m_obj) m_manager.inc_ref(m_obj); } public: typedef TManager manager; obj_ref(T * n, TManager & m): m_obj(n), m_manager(m) { inc_ref(); } explicit obj_ref(TManager & m): m_obj(0), m_manager(m) { } obj_ref(obj_ref const & n): m_obj(n.m_obj), m_manager(n.m_manager) { inc_ref(); } ~obj_ref() { dec_ref(); } TManager & get_manager() const { return m_manager; } TManager & m() const { return m_manager; } T * operator->() const { return m_obj; } T * get() const { return m_obj; } operator bool() const { return m_obj != 0; } bool operator!() const { return m_obj == 0; } operator T*() const { return m_obj; } T const & operator*() const { return *m_obj; } obj_ref & operator=(T * n) { if (n) { m_manager.inc_ref(n); } dec_ref(); m_obj = n; return *this; } obj_ref & operator=(obj_ref & n) { SASSERT(&m_manager == &n.m_manager); n.inc_ref(); dec_ref(); m_obj = n.m_obj; return *this; } void reset() { dec_ref(); m_obj = 0; } void swap(obj_ref & n) { std::swap(m_obj, n.m_obj); } /** \brief Steal ownership without decrementing the reference counter. */ T * steal() { T * r = m_obj; m_obj = 0; return r; } }; template inline bool operator==(obj_ref const & n1, obj_ref const & n2) { return n1.get() == n2.get(); } template inline bool operator==(obj_ref const & n1, obj_ref const & n2) { return n1.get() == n2.get(); } template inline bool operator!=(obj_ref const & n1, obj_ref const & n2) { return n1.get() != n2.get(); } template inline bool operator!=(obj_ref const & n1, obj_ref const & n2) { return n1.get() != n2.get(); } template inline void dec_range_ref(IT const & begin, IT const & end, TManager & m) { for (IT it = begin; it != end; ++it) { if (*it) { m.dec_ref(*it); } } } #endif /* _OBJ_REF_H_ */