[glibmm] C++11: _CLASS_GENERIC classes: Add move operations.



commit a4248547a50f2743bbef7cea03a93accfe14af9b
Author: Murray Cumming <murrayc murrayc com>
Date:   Sun Aug 23 18:52:39 2015 +0200

    C++11: _CLASS_GENERIC classes: Add move operations.
    
    These don't have much in common with each other.
    Like most of our move operations, they are completely untested,
    though they could be.

 gio/src/dbusinterfacevtable.ccg |   29 +++++++++++++++++++++++++++++
 gio/src/dbusinterfacevtable.hg  |    3 +++
 gio/src/dbussubtreevtable.ccg   |   29 +++++++++++++++++++++++++++++
 gio/src/dbussubtreevtable.hg    |    3 +++
 gio/src/fileattributeinfo.ccg   |   16 ++++++++++++++++
 gio/src/fileattributeinfo.hg    |    3 +++
 glib/src/balancedtree.hg        |    2 ++
 glib/src/iochannel.ccg          |   23 ++++++++++++++++++++++-
 glib/src/iochannel.hg           |    6 ++++++
 glib/src/keyfile.ccg            |   22 ++++++++++++++++++++++
 glib/src/keyfile.hg             |    3 +++
 glib/src/module.ccg             |   17 +++++++++++++++++
 glib/src/module.hg              |    3 +++
 glib/src/nodetree.hg            |    2 ++
 glib/src/optioncontext.ccg      |   22 ++++++++++++++++++++++
 glib/src/optioncontext.hg       |    8 ++++++++
 glib/src/optionentry.ccg        |   24 ++++++++++++++++++++++++
 glib/src/optionentry.hg         |    7 +++++++
 glib/src/optiongroup.ccg        |   31 +++++++++++++++++++++++++++++--
 glib/src/optiongroup.hg         |    6 ++++++
 glib/src/regex.ccg              |   23 +++++++++++++++++++++++
 glib/src/regex.hg               |    3 +++
 22 files changed, 282 insertions(+), 3 deletions(-)
---
diff --git a/gio/src/dbusinterfacevtable.ccg b/gio/src/dbusinterfacevtable.ccg
index d750b5c..53e52b9 100644
--- a/gio/src/dbusinterfacevtable.ccg
+++ b/gio/src/dbusinterfacevtable.ccg
@@ -143,6 +143,35 @@ InterfaceVTable::InterfaceVTable(
   gobject_.set_property = &DBusInterfaceVTable_SetProperty_giomm_callback;
 }
 
+InterfaceVTable::InterfaceVTable(InterfaceVTable&& other) noexcept
+: gobject_(std::move(other.gobject_)),
+  slot_method_call_(std::move(other.slot_method_call_)),
+  slot_get_property_(std::move(other.slot_get_property_)),
+  slot_set_property_(std::move(other.slot_set_property_))
+{
+  other.slot_method_call_ = nullptr;
+  other.slot_get_property_ = nullptr;
+  other.slot_set_property_ = nullptr;
+}
+
+InterfaceVTable& InterfaceVTable::operator=(InterfaceVTable&& other) noexcept
+{
+  delete slot_method_call_;
+  delete slot_get_property_;
+  delete slot_set_property_;
+
+  gobject_ = std::move(other.gobject_);
+  slot_method_call_ = std::move(other.slot_method_call_);
+  slot_get_property_ = std::move(other.slot_get_property_);
+  slot_set_property_ = std::move(other.slot_set_property_);
+
+  other.slot_method_call_ = nullptr;
+  other.slot_get_property_ = nullptr;
+  other.slot_set_property_ = nullptr;
+
+  return *this;
+}
+
 InterfaceVTable::~InterfaceVTable()
 {
   delete slot_method_call_;
diff --git a/gio/src/dbusinterfacevtable.hg b/gio/src/dbusinterfacevtable.hg
index e69df93..87aeee0 100644
--- a/gio/src/dbusinterfacevtable.hg
+++ b/gio/src/dbusinterfacevtable.hg
@@ -129,6 +129,9 @@ public:
   InterfaceVTable(const InterfaceVTable& other) = delete;
   InterfaceVTable& operator=(const InterfaceVTable& other) = delete;
 
+  InterfaceVTable(InterfaceVTable&& other) noexcept;
+  InterfaceVTable& operator=(InterfaceVTable&& other) noexcept;
+
   /// Destructor.
   virtual ~InterfaceVTable();
 
diff --git a/gio/src/dbussubtreevtable.ccg b/gio/src/dbussubtreevtable.ccg
index da8dd75..1299787 100644
--- a/gio/src/dbussubtreevtable.ccg
+++ b/gio/src/dbussubtreevtable.ccg
@@ -154,6 +154,35 @@ SubtreeVTable::SubtreeVTable(
   gobject_.dispatch = &DBusSubtreeVTable_Dispatch_giomm_callback;
 }
 
+SubtreeVTable::SubtreeVTable(SubtreeVTable&& other) noexcept
+: gobject_(std::move(other.gobject_)),
+  slot_enumerate_(std::move(other.slot_enumerate_)),
+  slot_introspect_(std::move(other.slot_introspect_)),
+  slot_dispatch_(std::move(other.slot_dispatch_))
+{
+  other.slot_enumerate_ = nullptr;
+  other.slot_introspect_ = nullptr;
+  other.slot_dispatch_ = nullptr;
+}
+
+SubtreeVTable& SubtreeVTable::operator=(SubtreeVTable&& other) noexcept
+{
+  delete slot_enumerate_;
+  delete slot_introspect_;
+  delete slot_dispatch_;
+
+  gobject_ = std::move(other.gobject_);
+  slot_enumerate_ = std::move(other.slot_enumerate_);
+  slot_introspect_ = std::move(other.slot_introspect_);
+  slot_dispatch_ = std::move(other.slot_dispatch_);
+
+  other.slot_enumerate_ = nullptr;
+  other.slot_introspect_ = nullptr;
+  other.slot_dispatch_ = nullptr;
+
+  return *this;
+}
+
 SubtreeVTable::~SubtreeVTable()
 {
   delete slot_enumerate_;
diff --git a/gio/src/dbussubtreevtable.hg b/gio/src/dbussubtreevtable.hg
index a31452b..b5e921b 100644
--- a/gio/src/dbussubtreevtable.hg
+++ b/gio/src/dbussubtreevtable.hg
@@ -138,6 +138,9 @@ public:
   SubtreeVTable(const SubtreeVTable& other) = delete;
   SubtreeVTable& operator=(const SubtreeVTable& other) = delete;
 
+  SubtreeVTable(SubtreeVTable&& other) noexcept;
+  SubtreeVTable& operator=(SubtreeVTable&& other) noexcept;
+
   /// Destructor.
   virtual ~SubtreeVTable();
 
diff --git a/gio/src/fileattributeinfo.ccg b/gio/src/fileattributeinfo.ccg
index ffb848d..d3e9597 100644
--- a/gio/src/fileattributeinfo.ccg
+++ b/gio/src/fileattributeinfo.ccg
@@ -44,6 +44,22 @@ FileAttributeInfo::operator=(const FileAttributeInfo& other)
   return *this;
 }
 
+FileAttributeInfo::FileAttributeInfo(FileAttributeInfo&& other) noexcept
+: m_name(std::move(other.m_name)),
+  m_type(std::move(other.m_type)),
+  m_flags(std::move(other.m_flags))
+{
+}
+
+FileAttributeInfo& FileAttributeInfo::operator=(FileAttributeInfo&& other) noexcept
+{
+  m_name = std::move(other.m_name);
+  m_type = std::move(other.m_type);
+  m_flags = std::move(other.m_flags);
+
+  return *this;
+}
+
 FileAttributeInfo::~FileAttributeInfo()
 {
 }
diff --git a/gio/src/fileattributeinfo.hg b/gio/src/fileattributeinfo.hg
index 7d5c92b..391249e 100644
--- a/gio/src/fileattributeinfo.hg
+++ b/gio/src/fileattributeinfo.hg
@@ -44,6 +44,9 @@ public:
   FileAttributeInfo(const FileAttributeInfo& other);
   FileAttributeInfo& operator=(const FileAttributeInfo& other);
 
+  FileAttributeInfo(FileAttributeInfo&& other) noexcept;
+  FileAttributeInfo& operator=(FileAttributeInfo&& other) noexcept;
+
   ~FileAttributeInfo();
 
   std::string get_name() const;
diff --git a/glib/src/balancedtree.hg b/glib/src/balancedtree.hg
index 5895511..9c59020 100644
--- a/glib/src/balancedtree.hg
+++ b/glib/src/balancedtree.hg
@@ -73,6 +73,8 @@ protected:
     gobject_ = g_tree_new_full(on_compare_tree, &key_compare_slot, on_destroy_key, on_destroy_value);
   }
 
+  //TODO: Add move operations, being careful of universal references and overload resolution.
+
 public:
   static Glib::RefPtr< BalancedTree<K, V> > create()
   {
diff --git a/glib/src/iochannel.ccg b/glib/src/iochannel.ccg
index 93faefa..fd8df45 100644
--- a/glib/src/iochannel.ccg
+++ b/glib/src/iochannel.ccg
@@ -127,6 +127,22 @@ IOChannel::IOChannel()
   reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = this;
 }
 
+IOChannel::IOChannel(IOChannel&& other) noexcept
+: gobject_(std::move(other.gobject_))
+{
+  other.gobject_ = nullptr;
+}
+
+IOChannel& IOChannel::operator=(IOChannel&& other) noexcept
+{
+  release_gobject();
+
+  gobject_ = std::move(other.gobject_);
+  other.gobject_ = nullptr;
+
+  return *this;
+}
+
 /* Construct an IOChannel wrapper for an already created GIOChannel.
  * See the comment at the top of this file for an explanation of the
  * problems with this approach.
@@ -143,7 +159,7 @@ IOChannel::IOChannel(GIOChannel* gobject, bool take_copy)
     g_io_channel_ref(gobject_);
 }
 
-IOChannel::~IOChannel()
+void IOChannel::release_gobject()
 {
   if(gobject_)
   {
@@ -167,6 +183,11 @@ IOChannel::~IOChannel()
   }
 }
 
+IOChannel::~IOChannel()
+{
+  release_gobject();
+}
+
 Glib::RefPtr<IOChannel> IOChannel::create_from_file(const std::string& filename, const std::string& mode)
 {
   GError* gerror = nullptr;
diff --git a/glib/src/iochannel.hg b/glib/src/iochannel.hg
index 9c97ce7..12b6b8d 100644
--- a/glib/src/iochannel.hg
+++ b/glib/src/iochannel.hg
@@ -84,6 +84,9 @@ class IOChannel : public sigc::trackable
 {
   _CLASS_GENERIC(IOChannel, GIOChannel)
 
+  IOChannel(IOChannel&& other) noexcept;
+  IOChannel& operator=(IOChannel&& other) noexcept;
+
   dnl // We can't support get_fd() properly because it is impossible
   dnl // to detect the specific GIOChannel type at runtime.
   _IGNORE(g_io_channel_unix_get_fd, g_io_channel_win32_get_fd)
@@ -470,6 +473,9 @@ protected:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   friend class Glib::GlibmmIOChannel;
 #endif
+
+private:
+  void release_gobject();
 };
 
 Glib::RefPtr<IOChannel> wrap(GIOChannel* gobject, bool take_copy = false);
diff --git a/glib/src/keyfile.ccg b/glib/src/keyfile.ccg
index 4488e31..5e7a215 100644
--- a/glib/src/keyfile.ccg
+++ b/glib/src/keyfile.ccg
@@ -32,6 +32,28 @@ KeyFile::KeyFile(GKeyFile* castitem, bool takes_ownership)
   owns_gobject_ = takes_ownership;
 }
 
+KeyFile::KeyFile(KeyFile&& other) noexcept
+: gobject_(std::move(other.gobject_)),
+  owns_gobject_(std::move(other.owns_gobject_))
+{
+  other.gobject_ = nullptr;
+  other.owns_gobject_ = false;
+}
+
+KeyFile& KeyFile::operator=(KeyFile&& other) noexcept
+{
+  if (owns_gobject_)
+    g_key_file_free(gobject_);
+
+  gobject_ = std::move(other.gobject_);
+  owns_gobject_ = std::move(other.owns_gobject_);
+
+  other.gobject_ = nullptr;
+  other.owns_gobject_ = false;
+
+  return *this;
+}
+
 KeyFile::~KeyFile()
 {
   if (owns_gobject_)
diff --git a/glib/src/keyfile.hg b/glib/src/keyfile.hg
index 9a9db86..f7094b6 100644
--- a/glib/src/keyfile.hg
+++ b/glib/src/keyfile.hg
@@ -109,6 +109,9 @@ public:
   KeyFile(const KeyFile&) = delete;
   KeyFile& operator=(const KeyFile&) = delete;
 
+  KeyFile(KeyFile&& other) noexcept;
+  KeyFile& operator=(KeyFile&& other) noexcept;
+
   /** Destructor
    */
   ~KeyFile();
diff --git a/glib/src/module.ccg b/glib/src/module.ccg
index 4e4666c..bcce3e4 100644
--- a/glib/src/module.ccg
+++ b/glib/src/module.ccg
@@ -26,6 +26,23 @@ Module::Module(const std::string& file_name, ModuleFlags flags)
   gobject_ (g_module_open(file_name.c_str(), (GModuleFlags) flags))
 {}
 
+Module::Module(Module&& other) noexcept
+: gobject_(std::move(other.gobject_))
+{
+  other.gobject_ = nullptr;
+}
+
+Module& Module::operator=(Module&& other) noexcept
+{
+  if(gobject_)
+    g_module_close(gobject_);
+
+  gobject_ = std::move(other.gobject_);
+  other.gobject_ = nullptr;
+
+  return *this;
+}
+
 Module::~Module()
 {
   if(gobject_)
diff --git a/glib/src/module.hg b/glib/src/module.hg
index ca98689..2009c03 100644
--- a/glib/src/module.hg
+++ b/glib/src/module.hg
@@ -74,6 +74,9 @@ public:
   Module(const Module&) = delete;
   Module& operator=(const Module&) = delete;
 
+  Module(Module&& other) noexcept;
+  Module& operator=(Module&& other) noexcept;
+
   /** Close a module. The module will be removed from memory, unless
    * <tt>make_resident</tt> has been called.
    */
diff --git a/glib/src/nodetree.hg b/glib/src/nodetree.hg
index fb0ff7b..60e8276 100644
--- a/glib/src/nodetree.hg
+++ b/glib/src/nodetree.hg
@@ -100,6 +100,8 @@ public:
     clone(&node);
   }
 
+  //TODO: Add move operations, being careful of universal references and overload resolution.
+
   /** Removes the instance and its children from the tree,
    * freeing any memory allocated.
    */
diff --git a/glib/src/optioncontext.ccg b/glib/src/optioncontext.ccg
index 56980b4..7bd3c07 100644
--- a/glib/src/optioncontext.ccg
+++ b/glib/src/optioncontext.ccg
@@ -60,6 +60,28 @@ OptionContext::OptionContext(GOptionContext* castitem, bool take_ownership)
 {
 }
 
+OptionContext::OptionContext(OptionContext&& other) noexcept
+: gobject_(std::move(other.gobject_)),
+  has_ownership_(std::move(other.has_ownership_))
+{
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+}
+
+OptionContext& OptionContext::operator=(OptionContext&& other) noexcept
+{
+  if(has_ownership_)
+    g_option_context_free(gobj());
+
+  gobject_ = std::move(other.gobject_);
+  has_ownership_ = std::move(other.has_ownership_);
+
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+
+  return *this;
+}
+
 OptionContext::~OptionContext()
 {
   if(has_ownership_)
diff --git a/glib/src/optioncontext.hg b/glib/src/optioncontext.hg
index 321bb66..f20ec36 100644
--- a/glib/src/optioncontext.hg
+++ b/glib/src/optioncontext.hg
@@ -98,6 +98,14 @@ public:
   //Note that, unlike Glib::Wrap(), this would create a second C++ instance for the same C instance,u
   //so it should be used carefully. For instance you could not access data in a derived class via this 
second instance.
   explicit OptionContext(GOptionContext* castitem, bool take_ownership = false);
+
+  //TODO?:
+  //OptionContext(const OptionContext& other) = delete;
+  //OptionContext& operator=(const OptionContext& other) = delete;
+
+  OptionContext(OptionContext&& other) noexcept;
+  OptionContext& operator=(OptionContext&& other) noexcept;
+
   virtual ~OptionContext();
 
   _WRAP_METHOD(void set_help_enabled(bool help_enabled = true), g_option_context_set_help_enabled)
diff --git a/glib/src/optionentry.ccg b/glib/src/optionentry.ccg
index 3764169..85df578 100644
--- a/glib/src/optionentry.ccg
+++ b/glib/src/optionentry.ccg
@@ -28,6 +28,14 @@ OptionEntry::OptionEntry()
 
 OptionEntry::~OptionEntry()
 {
+  release_gobject();
+}
+
+void OptionEntry::release_gobject() noexcept
+{
+  if(!gobject_)
+    return;
+
   g_free(const_cast<char*>(gobject_->long_name));
   g_free(const_cast<char*>(gobject_->description));
   g_free(const_cast<char*>(gobject_->arg_description));
@@ -70,6 +78,22 @@ OptionEntry& OptionEntry::operator=(const OptionEntry& src)
   return *this;
 }
 
+OptionEntry::OptionEntry(OptionEntry&& other) noexcept
+: gobject_(std::move(other.gobject_))
+{
+  other.gobject_ = nullptr;
+}
+
+OptionEntry& OptionEntry::operator=(OptionEntry&& other) noexcept
+{
+  release_gobject();
+
+  gobject_ = std::move(other.gobject_);
+  other.gobject_ = nullptr;
+
+  return *this;
+}
+
 void OptionEntry::set_long_name(const Glib::ustring& value)
 {
   if(gobject_->long_name)
diff --git a/glib/src/optionentry.hg b/glib/src/optionentry.hg
index d77eab7..8ff4a11 100644
--- a/glib/src/optionentry.hg
+++ b/glib/src/optionentry.hg
@@ -59,6 +59,10 @@ public:
 
   OptionEntry();
   OptionEntry(const OptionEntry& src);
+
+  OptionEntry(OptionEntry&& other) noexcept;
+  OptionEntry& operator=(OptionEntry&& other) noexcept;
+
   virtual ~OptionEntry();
 
   OptionEntry& operator=(const OptionEntry& src);
@@ -91,6 +95,9 @@ public:
   GOptionEntry*       gobj()       { return gobject_; }
   const GOptionEntry* gobj() const { return gobject_; }
 
+private:
+  void release_gobject() noexcept;
+
 protected:
 
   GOptionEntry* gobject_;
diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg
index 4d26a8f..2ce9102 100644
--- a/glib/src/optiongroup.ccg
+++ b/glib/src/optiongroup.ccg
@@ -281,8 +281,30 @@ OptionGroup::OptionGroup(GOptionGroup* castitem)
   //Always takes ownership - never takes copy.
 }
 
+OptionGroup::OptionGroup(OptionGroup&& other) noexcept
+: map_entries_(std::move(other.map_entries_)),
+  gobject_(std::move(other.gobject_)),
+  has_ownership_(std::move(other.has_ownership_))
+{
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+}
 
-OptionGroup::~OptionGroup()
+OptionGroup& OptionGroup::operator=(OptionGroup&& other) noexcept
+{
+  release_gobject();
+
+  map_entries_ = std::move(other.map_entries_);
+  gobject_ = std::move(other.gobject_);
+  has_ownership_ = std::move(other.has_ownership_);
+
+  other.gobject_ = nullptr;
+  other.has_ownership_ = false;
+
+  return *this;
+}
+
+void OptionGroup::release_gobject() noexcept
 {
   //Free any C types that were allocated during add_entry():
   for(auto& the_pair : map_entries_)
@@ -291,13 +313,18 @@ OptionGroup::~OptionGroup()
     cpp_entry.release_c_arg();
   }
 
-  if(has_ownership_)
+  if(has_ownership_ && gobject_)
   {
     g_option_group_unref(gobj());
     gobject_ = nullptr;
   }
 }
 
+OptionGroup::~OptionGroup()
+{
+  release_gobject();
+}
+
 void OptionGroup::add_entry(const OptionEntry& entry)
 {
   //It does not copy the entry, so it needs to live as long as the group.
diff --git a/glib/src/optiongroup.hg b/glib/src/optiongroup.hg
index 4afe9c1..5cfe0e5 100644
--- a/glib/src/optiongroup.hg
+++ b/glib/src/optiongroup.hg
@@ -69,6 +69,9 @@ public:
   explicit OptionGroup(GOptionGroup* castitem);
   _IGNORE(g_option_group_new, g_option_group_ref)
 
+  OptionGroup(OptionGroup&& other) noexcept;
+  OptionGroup& operator=(OptionGroup&& other) noexcept;
+
   virtual ~OptionGroup();
   _IGNORE(g_option_group_free, g_option_group_unref)
 
@@ -196,6 +199,9 @@ protected:
   GOptionGroup* gobject_;
   bool has_ownership_; //Whether the gobject_ belongs to this C++ instance.
 #endif //DOXYGEN_SHOULD_SKIP_THIS
+
+private:
+  void release_gobject() noexcept;
 };
 
 } // namespace Glib
diff --git a/glib/src/regex.ccg b/glib/src/regex.ccg
index 61408cc..3b9e2b2 100644
--- a/glib/src/regex.ccg
+++ b/glib/src/regex.ccg
@@ -248,6 +248,29 @@ MatchInfo::MatchInfo(GMatchInfo* castitem, bool take_the_ownership)
 {
 }
 
+
+MatchInfo::MatchInfo(MatchInfo&& other) noexcept
+: gobject_(std::move(other.gobject_)),
+  take_ownership(std::move(other.take_ownership))
+{
+  other.gobject_ = nullptr;
+  other.take_ownership = false;
+}
+
+MatchInfo& MatchInfo::operator=(MatchInfo&& other) noexcept
+{
+  if(take_ownership && gobject_)
+    g_match_info_free(gobject_);
+
+  gobject_ = std::move(other.gobject_);
+  take_ownership = std::move(other.take_ownership);
+
+  other.gobject_ = nullptr;
+  other.take_ownership = false;
+
+  return *this;
+}
+
 void MatchInfo::set_gobject(GMatchInfo* castitem, bool take_the_ownership)
 {
   if(gobject_ && this->take_ownership)
diff --git a/glib/src/regex.hg b/glib/src/regex.hg
index 6e0d9d3..0044b12 100644
--- a/glib/src/regex.hg
+++ b/glib/src/regex.hg
@@ -230,6 +230,9 @@ public:
   MatchInfo(const MatchInfo& other) = delete;
   MatchInfo& operator=(const MatchInfo& other) = delete;
 
+  MatchInfo(MatchInfo&& other) noexcept;
+  MatchInfo& operator=(MatchInfo&& other) noexcept;
+
   /// Destructor.
   virtual ~MatchInfo();
 


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