// -*- C++ -*-
/**
* \file copied_ptr.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* A templated class that can serve as a pointer to an object, with the
* property that when the copied_ptr is copied, it creates its own copy
* of the object pointed to as well.
*
* The implementation was based originally on Yonat Sharon's copied_ptr templated
* class, as described at http://ootips.org/yonat/, but has evolved toward's
* Herb Sutter's HolderPtr, as described at http://www.gotw.ca/gotw/062.htm.
* (Note, HolderPtr became ValuePtr in his book, More Exceptional C++.)
*
* Warning: if the class stores 'Base * ptr_', but the actual object pointed to
* belongs to a derived class, then you must specialise memory_traits so that
* its clone and destroy member functions do the right thing. Otherwise, you'll
* end up slicing the data.
*/
#ifndef COPIED_PTR_H
#define COPIED_PTR_H
namespace lyx {
namespace support {
template
struct memory_traits {
static T * clone(T const * ptr) { return new T(*ptr); }
static void destroy(T * ptr) { delete ptr; }
};
template >
class copied_ptr {
public:
explicit copied_ptr(T * = 0);
copied_ptr(copied_ptr const &);
~copied_ptr();
copied_ptr & operator=(copied_ptr const &);
T & operator*() const;
T * operator->() const;
T * get() const;
private:
T * ptr_;
};
template
copied_ptr::copied_ptr(T * p)
: ptr_(p)
{}
template
copied_ptr::copied_ptr(copied_ptr const & other)
: ptr_(other.ptr_ ? Traits::clone(other.ptr_) : 0)
{}
template
copied_ptr::~copied_ptr()
{
Traits::destroy(ptr_);
}
template
copied_ptr & copied_ptr::operator=(copied_ptr const & other)
{
if (&other != this) {
copied_ptr temp(other);
std::swap(ptr_, temp.ptr_);
}
return *this;
}
template
T & copied_ptr::operator*() const
{
return *ptr_;
}
template
T * copied_ptr::operator->() const
{
return ptr_;
}
template
T * copied_ptr::get() const
{
return ptr_;
}
} // namespace support
} // namespace lyx
#endif // NOT COPIED_PTR_H