[glibmm] C++11: _CLASS_GENERIC classes: Add move operations.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] C++11: _CLASS_GENERIC classes: Add move operations.
- Date: Sun, 23 Aug 2015 18:03:28 +0000 (UTC)
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]