[gparted] Use pointers to Partitions in PartitionVector class (#759726)



commit 06b8a3a14a89c5e9e33b7232c8646b93466be79a
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Jun 16 22:34:59 2015 +0100

    Use pointers to Partitions in PartitionVector class (#759726)
    
    The PartitionVector class is now internally using pointers to Partition
    objects and taking on management of their lifetimes.  It therefore has
    to implement the Big 3: destructor, copy constructor and copy assignment
    operator [1][2].  This is because the implicitly-defined copy
    constructor and assignment operator perform memberwise "shallow copying"
    and the destructor does nothing.  This not correct for classes which
    contain non-class types such as raw pointers.
    
    The semantics of the interface still copies each Partition object into
    the PartitionVector when they are added with push_back() and insert().
    
    Note that a PartitionVector object is explicitly copy assigned in
    Win_GParted::Refresh_Visual().  They are also implicitly copied when
    (1) the implementing vector is resized larger to allow it to hold more
    pointers to Partition objects than it previously had capacity for; and
    (2) a Partition object is copied including the logicals PartitionVector
    member.
    
    [1] The rule of three/five/zero
        http://en.cppreference.com/w/cpp/language/rule_of_three
    [2] Rule of Three
        https://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29
    
    Bug 759726 - Implement Partition object polymorphism

 include/PartitionVector.h |   34 +++++++++--------
 po/POTFILES.in            |    1 +
 src/Makefile.am           |    1 +
 src/PartitionVector.cc    |   88 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 108 insertions(+), 16 deletions(-)
---
diff --git a/include/PartitionVector.h b/include/PartitionVector.h
index 3a3addf..f1d6c33 100644
--- a/include/PartitionVector.h
+++ b/include/PartitionVector.h
@@ -14,9 +14,9 @@
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* Minimal implementation of a class that behaves like a std::vector<Partition> which can
- * be used in it's place with minimal change to the existing GParted code which expects to
- * be working with a std::vector<Partition>.
+/* Minimal implementation of a class with some behaviours like a std::vector<Partition>.
+ * However internally the class manages pointers to Partition objects allowing for
+ * Partition object polymorphism.
  * Reference:
  *     C++ Reference to std::vector
  *     http://www.cplusplus.com/reference/vector/vector/
@@ -44,10 +44,13 @@ class PartitionVector;  // mutually recursive classes.
 class PartitionVector {
 public:
        typedef size_t size_type;
-       typedef std::vector<Partition>::iterator iterator;
+       typedef std::vector<Partition *>::iterator iterator;
 
        PartitionVector() {};
-       ~PartitionVector() {};
+       PartitionVector( const PartitionVector & src );
+       ~PartitionVector();
+       void swap( PartitionVector & other );
+       PartitionVector & operator=( PartitionVector rhs );
 
        // Iterators
        iterator begin()                                   { return v.begin(); };
@@ -56,22 +59,21 @@ public:
        bool empty() const                                 { return v.empty(); };
 
        // Element access
-       Partition & operator[]( size_type n )              { return v[n]; };
-       const Partition & operator[]( size_type n ) const  { return v[n]; };
+       Partition & operator[]( size_type n )              { return *v[n]; };
+       const Partition & operator[]( size_type n ) const  { return *v[n]; };
        size_type size() const                             { return v.size(); };
-       const Partition & front() const                    { return v.front(); };
-       const Partition & back() const                     { return v.back(); };
+       const Partition & front() const                    { return *v.front(); };
+       const Partition & back() const                     { return *v.back(); };
 
        // Modifiers
-       void pop_back()                                    { v.pop_back(); };
-       void erase( const iterator position )              { v.erase( position ); };
-       void clear()                                       { v.clear(); };
-       void push_back( const Partition & partition )      { v.push_back( partition ); };
-       void insert( iterator position, const Partition & partition )
-                                                          { v.insert( position, partition ); };
+       void pop_back();
+       void erase( const iterator position );
+       void clear();
+       void push_back( const Partition & partition );
+       void insert( iterator position, const Partition & partition );
 
 private:
-       std::vector<Partition> v;
+       std::vector<Partition *> v;
 };
 
 } //GParted
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 29741cf..d7172e4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -31,6 +31,7 @@ src/OperationLabelFileSystem.cc
 src/OperationNamePartition.cc
 src/OperationResizeMove.cc
 src/Partition.cc
+src/PartitionVector.cc
 src/SWRaid_Info.cc
 src/TreeView_Detail.cc
 src/Utils.cc
diff --git a/src/Makefile.am b/src/Makefile.am
index 0d9cd36..1e19f66 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,7 @@ gpartedbin_SOURCES = \
        OperationNamePartition.cc       \
        OperationResizeMove.cc          \
        Partition.cc                    \
+       PartitionVector.cc              \
        PipeCapture.cc                  \
        Proc_Partitions_Info.cc         \
        SWRaid_Info.cc                  \
diff --git a/src/PartitionVector.cc b/src/PartitionVector.cc
new file mode 100644
index 0000000..f05bedf
--- /dev/null
+++ b/src/PartitionVector.cc
@@ -0,0 +1,88 @@
+/* Copyright (C) 2015 Mike Fleetwood
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../include/Partition.h"
+#include "../include/PartitionVector.h"
+
+#include <algorithm>
+
+namespace GParted
+{
+
+PartitionVector::PartitionVector( const PartitionVector & src )
+{
+       v.resize( src.size() );
+       for ( unsigned int i = 0 ; i < src.size() ; i ++ )
+               v[i] = new Partition( src[i] );
+}
+
+PartitionVector::~PartitionVector()
+{
+       for ( unsigned int i = 0 ; i < v.size() ; i ++ )
+               delete v[i];
+}
+
+void PartitionVector::swap( PartitionVector & other )
+{
+       std::swap( this->v, other.v );
+}
+
+PartitionVector & PartitionVector::operator=( PartitionVector rhs )
+{
+       // Copy assignment implemented using copy-and-swap idiom.
+       // 1) Pass-by-value to get rhs variable copy constructed from source;
+       // 2) Swap contents of this PartitionVector with rhs variable copy;
+       // 3) Method returns, rhs variable goes out of scope and destructor called on old
+       //    this PartitionVector to delete owned Partitions.
+       // Reference:
+       //     Wikibooks: More C++ Idioms / Copy-and-swap
+       //     https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap
+       rhs.swap( *this );
+       return *this;
+}
+
+void PartitionVector::pop_back()
+{
+       delete v.back();
+       v.pop_back();
+}
+
+void PartitionVector::erase( const iterator position )
+{
+       delete *position;
+       v.erase( position );
+}
+
+void PartitionVector::clear()
+{
+       for ( unsigned int i = 0 ; i < v.size() ; i ++ )
+               delete v[i];
+       v.clear();
+}
+
+void PartitionVector::push_back( const Partition & partition )
+{
+       Partition * p = new Partition( partition );
+       v.push_back( p );
+}
+
+void PartitionVector::insert( iterator position, const Partition & partition )
+{
+       Partition * p = new Partition( partition );
+       v.insert( position, p );
+}
+
+} //GParted


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]