#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