#pragma once namespace pfc { struct _rcptr_null; typedef _rcptr_null* t_rcptr_null; static const t_rcptr_null rcptr_null = NULL; class rc_container_base { public: long add_ref() throw() { return ++m_counter; } long release() throw() { long ret = --m_counter; if (ret == 0) PFC_ASSERT_NO_EXCEPTION( delete this ); return ret; } protected: virtual ~rc_container_base() {} private: refcounter m_counter; }; template class rc_container_t : public rc_container_base { public: template rc_container_t(arg_t && ... arg) : m_object(std::forward(arg) ...) {} t_object m_object; }; template class rcptr_t { private: typedef rcptr_t t_self; typedef rc_container_base t_container; typedef rc_container_t t_container_impl; public: rcptr_t(t_rcptr_null) throw() {_clear();} rcptr_t() throw() {_clear();} rcptr_t(const t_self & p_source) throw() {__init(p_source);} t_self const & operator=(const t_self & p_source) throw() {__copy(p_source); return *this;} template rcptr_t(const rcptr_t & p_source) throw() {__init(p_source);} template const t_self & operator=(const rcptr_t & p_source) throw() {__copy(p_source); return *this;} rcptr_t(t_self && p_source) throw() {_move(p_source);} const t_self & operator=(t_self && p_source) throw() {release(); _move(p_source); return *this;} const t_self & operator=(t_rcptr_null) throw() {release(); return *this;} /* template operator rcptr_t() const throw() { rcptr_t temp; if (is_valid()) temp.__set_from_cast(this->m_container,this->m_ptr); return temp; }*/ template bool operator==(const rcptr_t & p_other) const throw() { return m_container == p_other.__container(); } template bool operator!=(const rcptr_t & p_other) const throw() { return m_container != p_other.__container(); } void __set_from_cast(t_container * p_container,t_object * p_ptr) throw() { //addref first because in rare cases this is the same pointer as the one we currently own if (p_container != NULL) p_container->add_ref(); release(); m_container = p_container; m_ptr = p_ptr; } bool is_valid() const throw() {return m_container != NULL;} bool is_empty() const throw() {return m_container == NULL;} ~rcptr_t() throw() {release();} void release() throw() { t_container * temp = m_container; m_ptr = NULL; m_container = NULL; if (temp != NULL) temp->release(); } template rcptr_t static_cast_t() const throw() { rcptr_t temp; if (is_valid()) temp.__set_from_cast(this->m_container,static_cast(this->m_ptr)); return temp; } void new_t() { on_new(new t_container_impl()); } template void new_t(arg_t && ... arg) { on_new(new t_container_impl(std::forward(arg) ...)); } static t_self g_new_t() { t_self temp; temp.new_t(); return temp; } template static t_self g_new_t(arg_t && ... arg) { t_self temp; temp.new_t(std::forward(arg) ...); return temp; } t_object & operator*() const throw() {return *this->m_ptr;} t_object * operator->() const throw() {return this->m_ptr;} t_container * __container() const throw() {return m_container;} // FOR INTERNAL USE ONLY void _clear() throw() {m_container = NULL; m_ptr = NULL;} private: template void __init(const rcptr_t & p_source) throw() { m_container = p_source.__container(); m_ptr = &*p_source; if (m_container != NULL) m_container->add_ref(); } template void _move(rcptr_t & p_source) throw() { m_container = p_source.__container(); m_ptr = &*p_source; p_source._clear(); } template void __copy(const rcptr_t & p_source) throw() { __set_from_cast(p_source.__container(),&*p_source); } void on_new(t_container_impl * p_container) throw() { this->release(); p_container->add_ref(); this->m_ptr = &p_container->m_object; this->m_container = p_container; } t_container * m_container; t_object * m_ptr; }; template rcptr_t rcnew_t(arg_t && ... arg) { rcptr_t temp; temp.new_t(std::forward(arg) ...); return temp; } class traits_rcptr : public traits_default { public: enum { realloc_safe = true, constructor_may_fail = false }; }; template class traits_t > : public traits_rcptr {}; }