, ( ).
, ( ). , :
template <typename T>
struct default_constructor_factory
{
T * operator ()() { return new T; }
};
template <typename T, typename F = default_constructor_factory<T> >
class lazy_ptr : boost::noncopyable
{
public:
typedef T element_type;
typedef T value_type;
typedef F factory_type;
typedef lazy_ptr<T,F> this_type;
lazy_ptr() : m_ptr(), m_factory() { }
lazy_ptr(F factory) : m_ptr(), m_factory(factory) { }
~lazy_ptr() { if (m_ptr != NULL) delete m_ptr; }
T & operator* () const
{
return *get();
}
T * operator-> () const
{
return get();
}
T * get() const
{
if (m_ptr == NULL)
m_ptr = m_factory();
return m_ptr;
}
void reset(T * p)
{
if (p != m_ptr)
{
if (m_ptr != NULL)
delete m_ptr;
m_ptr = p;
}
}
T * release()
{
T * p = m_ptr;
m_ptr = NULL;
return p;
}
T * peek() const
{
return m_ptr;
}
bool dereferenced() const
{
return peek() != NULL;
}
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const
{
return dereferenced() ? &this_type::m_ptr : NULL;
}
private:
mutable T * m_ptr;
mutable factory_type m_factory;
};
template <typename T, typename F = default_constructor_factory<T> >
class shared_lazy_ptr
{
public:
typedef T element_type;
typedef T value_type;
typedef F factory_type;
typedef lazy_ptr<T,F> ptr_type;
typedef shared_lazy_ptr<T,F> this_type;
shared_lazy_ptr() : m_ptr(new ptr_type) { }
shared_lazy_ptr(F factory) : m_ptr(new ptr_type(factory)) { }
shared_lazy_ptr(const this_type & rhs) : m_ptr(rhs.m_ptr), m_references(rhs.m_references) { }
this_type & operator = (const this_type & rhs)
{
if (m_references.Reattach(rhs.m_references))
delete m_ptr;
m_ptr = rhs.m_ptr;
return *this;
}
~shared_lazy_ptr()
{
if (m_references.IsOnly())
delete m_ptr;
}
T & operator* () const
{
return *get();
}
T * operator-> () const
{
return get();
}
T * get() const
{
return m_ptr->get();
}
void reset(T * p)
{
if (p != get())
{
if (m_ptr != NULL)
delete m_ptr;
m_ptr = p;
}
}
T * peek() const
{
return get()->peek();
}
bool dereferenced() const
{
return peek() != NULL;
}
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const
{
return dereferenced() ? &this_type::m_ptr : NULL;
}
private:
lazy_ptr<T, F> * m_ptr;
ReferenceCount m_references;
};