From de7312a1229df0006fcd81552566f4590c966475 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Mon, 15 Sep 2003 20:23:57 +0000 Subject: [PATCH] Beef up copied_ptr; use it rather than cow_ptr to store the BufferParams pimpl. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7762 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 4 ++ src/bufferparams.C | 13 +++++++ src/bufferparams.h | 26 +++++++------ src/support/copied_ptr.h | 82 +++++++++++++++++++++++----------------- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2fa672ff7d..594b2ba80b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2003-09-15 Angus Leeming + + * bufferparams.[Ch]: store the pimpl_ as a copied_ptr, rather than as a cow_ptr. + 2003-09-15 Angus Leeming * LColor.h: add an EnumLColor wrapper for LColor::color. diff --git a/src/bufferparams.C b/src/bufferparams.C index 4b75e387ec..bbe6c30090 100644 --- a/src/bufferparams.C +++ b/src/bufferparams.C @@ -79,6 +79,19 @@ BufferParams::Impl::Impl() } +BufferParams::Impl * +BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr) +{ + return new BufferParams::Impl(*ptr); +} + + +void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr) +{ + delete ptr; +} + + BufferParams::BufferParams() : // Initialize textclass to point to article. if `first' is // true in the returned pair, then `second' is the textclass diff --git a/src/bufferparams.h b/src/bufferparams.h index 559db97c61..6df7e92ea0 100644 --- a/src/bufferparams.h +++ b/src/bufferparams.h @@ -20,7 +20,7 @@ #include "insets/insetquotes.h" -#include "support/cow_ptr.h" +#include "support/copied_ptr.h" #include "support/types.h" #include "support/std_string.h" @@ -39,10 +39,10 @@ struct Language; /** Buffer parameters. - This class contains all the parameters for this a buffer uses. Some - work needs to be done on this class to make it nice. Now everything - is in public. -*/ + * This class contains all the parameters for this a buffer uses. Some + * work needs to be done on this class to make it nice. Now everything + * is in public. + */ class BufferParams { public: /// @@ -63,8 +63,8 @@ public: void writeFile(std::ostream &) const; /** \returns true if the babel package is used (interogates - the BufferParams and a LyXRC variable). - This returned value can then be passed to the insets... + * the BufferParams and a LyXRC variable). + * This returned value can then be passed to the insets... */ bool writeLaTeX(std::ostream &, LaTeXFeatures &, TexRow &) const; @@ -84,8 +84,8 @@ public: void setDefSkip(VSpace const & vs); /** Wether paragraphs are separated by using a indent like in - articles or by using a little skip like in letters. - */ + * articles or by using a little skip like in letters. + */ PARSEP paragraph_separation; /// InsetQuotes::quote_language quotes_language; @@ -203,10 +203,14 @@ public: private: /** Use the Pimpl idiom to hide those member variables that would otherwise - drag in other header files. + * drag in other header files. */ class Impl; - lyx::support::cow_ptr pimpl_; + struct MemoryTraits { + static Impl * clone(Impl const *); + static void destroy(Impl *); + }; + lyx::support::copied_ptr pimpl_; }; #endif diff --git a/src/support/copied_ptr.h b/src/support/copied_ptr.h index 0683158d81..1bf94d349a 100644 --- a/src/support/copied_ptr.h +++ b/src/support/copied_ptr.h @@ -4,15 +4,21 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Yonat Sharon http://ootips.org/yonat/ + * \author Angus Leeming * - * simple copy-on-create/assign pointer. + * 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. * - * Note: If the actual object pointed to belongs to a derived class, - * then copied_ptr will not create a copy of the derived class object, - * but a new base class object. - * If you want to use a polymorphic copy-on-assign pointer, use - * cloned_ptr. + * 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 @@ -22,11 +28,18 @@ 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(copied_ptr const &); + ~copied_ptr(); copied_ptr & operator=(copied_ptr const &); T & operator*() const; @@ -35,66 +48,65 @@ public: private: T * ptr_; - void copy(copied_ptr const &); + void swap(copied_ptr &); }; -template -copied_ptr::copied_ptr(T * p) +template +copied_ptr::copied_ptr(T * p) : ptr_(p) {} -template -copied_ptr::~copied_ptr() -{ - delete ptr_; -} +template +copied_ptr::copied_ptr(copied_ptr const & other) + : ptr_(other.ptr_ ? Traits::clone(other.ptr_) : 0) +{} -template -copied_ptr::copied_ptr(copied_ptr const & other) +template +copied_ptr::~copied_ptr() { - copy(other.get()); + Traits::destroy(ptr_); } -template -copied_ptr & copied_ptr::operator=(copied_ptr const & other) +template +copied_ptr & copied_ptr::operator=(copied_ptr const & other) { - if (&other != this) { - delete ptr_; - copy(other); - } - return *this; + if (&other != this) { + copied_ptr temp(other); + swap(temp); + } + return *this; } -template -T & copied_ptr::operator*() const +template +T & copied_ptr::operator*() const { return *ptr_; } -template -T * copied_ptr::operator->() const +template +T * copied_ptr::operator->() const { return ptr_; } -template -T * copied_ptr::get() const +template +T * copied_ptr::get() const { return ptr_; } -template -void copied_ptr::copy(copied_ptr const & other) +template +void copied_ptr::swap(copied_ptr & other) { - ptr_ = other.ptr_ ? new T(*other.ptr_) : 0; + std::swap( ptr_, other.ptr_ ); } } // namespace support -- 2.39.2