]> git.lyx.org Git - features.git/commitdiff
Beef up copied_ptr; use it rather than cow_ptr to store the BufferParams pimpl.
authorAngus Leeming <leeming@lyx.org>
Mon, 15 Sep 2003 20:23:57 +0000 (20:23 +0000)
committerAngus Leeming <leeming@lyx.org>
Mon, 15 Sep 2003 20:23:57 +0000 (20:23 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7762 a592a061-630c-0410-9148-cb99ea01b6c8

src/ChangeLog
src/bufferparams.C
src/bufferparams.h
src/support/copied_ptr.h

index 2fa672ff7d950afcc212131975992af7d6515297..594b2ba80b7b70e33696cbac905a36b97ae8416f 100644 (file)
@@ -1,3 +1,7 @@
+2003-09-15  Angus Leeming  <leeming@lyx.org>
+
+       * bufferparams.[Ch]: store the pimpl_ as a copied_ptr, rather than as a cow_ptr.
+
 2003-09-15  Angus Leeming  <leeming@lyx.org>
 
        * LColor.h: add an EnumLColor wrapper for LColor::color.
index 4b75e387ecab29e1914905537b7f144bf732e8ed..bbe6c3009040e5240e794095983ad899343db9c6 100644 (file)
@@ -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
index 559db97c61aa1415e93cf0f90f7e0c2e9e96f60b..6df7e92ea0171bf1404b3de0004f3b5f0363ad9f 100644 (file)
@@ -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<Impl> pimpl_;
+       struct MemoryTraits {
+               static Impl * clone(Impl const *);
+               static void destroy(Impl *);
+       };
+       lyx::support::copied_ptr<Impl, MemoryTraits> pimpl_;
 };
 
 #endif
index 0683158d811a35b3934b2e4c9a3255446b2a5d85..1bf94d349abf8453517a20f52cc0918d8790c532 100644 (file)
@@ -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<Base> 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 <typename T>
+struct memory_traits {
+       static T * clone(T const * ptr) { return new T(*ptr); }
+       static void destroy(T * ptr) { delete ptr; }
+};
+
+
+template <typename T, typename Traits=memory_traits<T> >
 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 <typename T>
-copied_ptr<T>::copied_ptr(T * p)
+template <typename T, typename Traits>
+copied_ptr<T, Traits>::copied_ptr(T * p)
        : ptr_(p)
 {}
 
 
-template <typename T>
-copied_ptr<T>::~copied_ptr()
-{
-       delete ptr_;
-}
+template <typename T, typename Traits>
+copied_ptr<T, Traits>::copied_ptr(copied_ptr const & other)
+       : ptr_(other.ptr_ ? Traits::clone(other.ptr_) : 0)
+{}
 
 
-template <typename T>
-copied_ptr<T>::copied_ptr(copied_ptr const & other)
+template <typename T, typename Traits>
+copied_ptr<T, Traits>::~copied_ptr()
 {
-       copy(other.get());
+       Traits::destroy(ptr_);
 }
 
 
-template <typename T>
-copied_ptr<T> & copied_ptr<T>::operator=(copied_ptr const & other)
+template <typename T, typename Traits>
+copied_ptr<T, Traits> & copied_ptr<T, Traits>::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 <typename T>
-T & copied_ptr<T>::operator*() const
+template <typename T, typename Traits>
+T & copied_ptr<T, Traits>::operator*() const
 {
        return *ptr_;
 }
 
 
-template <typename T>
-T * copied_ptr<T>::operator->() const
+template <typename T, typename Traits>
+T * copied_ptr<T, Traits>::operator->() const
 {
        return ptr_;
 }
 
 
-template <typename T>
-T * copied_ptr<T>::get() const
+template <typename T, typename Traits>
+T * copied_ptr<T, Traits>::get() const
 {
        return ptr_;
 }
 
 
-template <typename T>
-void copied_ptr<T>::copy(copied_ptr const & other)
+template <typename T, typename Traits>
+void copied_ptr<T, Traits>::swap(copied_ptr & other)
 {
-       ptr_ = other.ptr_ ? new T(*other.ptr_) : 0;
+       std::swap( ptr_, other.ptr_ );
 }
 
 } // namespace support