#ifndef ARG_GRIN_PTR_H #define ARG_GRIN_PTR_H #ifndef ARG_COMPILER_H #include "arg_compiler.h" #endif #ifndef ARG_DEEP_COPY_UTILS_H #include "arg_deep_copy_utils.h" #endif #include ARG_STLHDR(algorithm) namespace arg { template<typename p_type> class grin_ptr { typedef void (*delete_ftn)(p_type* p); typedef p_type* (*copy_ftn)(const p_type* p); public: // Construction & assignment explicit grin_ptr(p_type* pointee) : do_copy(&my_copy_ftn), p(pointee), do_delete(my_delete_ftn) { // "sizeof(p_type)" will force a diagnostic for an incomplete type sizeof(p_type); } grin_ptr(const grin_ptr& rhs); ~grin_ptr() throw() { do_delete(p); } // Accessors - (overloaded on const) const p_type* get() const { return p; } p_type* get() { return p; } const p_type* operator->() const { return p; } p_type* operator->() { return p; } const p_type& operator*() const { return *p; } p_type& operator*() { return *p; } // Mutators void swap(grin_ptr& with) throw() { p_type* pp = p; p = with.p; with.p = pp; } grin_ptr& operator=(const grin_ptr& rhs); private: copy_ftn do_copy; p_type* p; delete_ftn do_delete; static void my_delete_ftn(p_type* p) { delete p; } static p_type* my_copy_ftn(const p_type* p) { return deep_copy(p); } }; template<typename p_type> inline grin_ptr<p_type>::grin_ptr(const grin_ptr& rhs) : do_copy(rhs.do_copy), p(do_copy(rhs.p)), do_delete(rhs.do_delete) { } template<typename p_type> inline grin_ptr<p_type>& grin_ptr<p_type>::operator=(const grin_ptr& rhs) { p_type* pp = do_copy(rhs.p); do_delete(p); p = pp; return *this; } } namespace std { template<class p_type> inline void swap( ::arg::grin_ptr<p_type>& lhs, ::arg::grin_ptr<p_type>& rhs) throw() { lhs.swap(rhs); } } #endif