From 14d519186bb505ccf3a766c9bd6f1a03fd0aae46 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 7 Sep 2020 00:08:10 -0700 Subject: [PATCH] Imported Upstream version 2.46.2 --- NEWS | 93 ++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- glib/glibmm/containers.h | 2 +- glib/glibmm/error.h | 2 +- glib/glibmm/interface.cc | 20 ++++---- glib/glibmm/main.h | 18 +++---- glib/glibmm/object.cc | 10 ++-- glib/glibmm/objectbase.cc | 27 +++++++---- glib/glibmm/streamiochannel.h | 14 +++--- tests/glibmm_interface_move/main.cc | 18 +++++-- tests/glibmm_object_move/main.cc | 20 ++++---- tests/glibmm_objectbase_move/main.cc | 22 +++++---- 12 files changed, 184 insertions(+), 64 deletions(-) diff --git a/NEWS b/NEWS index 3d8beb5..ff3e87a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,96 @@ +2.46.2: + +* ObjectBase, Object, Interface: Correct move constructors and move assignment + operators. + (Kjell Ahlstedt) Bug #756962 + + +Changes in 2.46 compared to 2.44: + +General: +* Use, and require C++11, using features such as move operations, noexcept + auto, = delete, nulltpr, override. + (Murray Cumming, Kjell Ahlstedt)) + +Glib:: +* RefPtr: + - Make it possible to stop use of RefPtr with certain classes. + (Kjell Ahlstedt) + - Make methods noexcept (C++11). + (Murray Cumming) + - Add move operations. + (Murray Cumming, Marcin Kolny, Kjell Ahlstedt) + * Add release(): + (Marcin Kolny) +* ObjectBase: Don't use std::auto_ptr (deprecated in C++11). + (Kjell Ahlstedt) +* ObjectBase, Object, Interface, IOChannel, Markup: Add move operations + (Murray Cumming) Add C++11 move operations. + (Murray Cumming) +* HelperList: fix iterator check in operator[] + (Maks Naumov) +* Add SettingsSchema, SettingsSchemaKey and SettingsSchemaSource. + (Murray Cumming) +* Add Glib::format_size(). + (Kjell Ahlstedt) +* Add get_user_special_dir(UserDirectory), deprecating + get_user_special_dir(GUserDirectory directory). + (Kjell Ahlstedt) +* Threads::Thread: Use GThread only via a pointer. + Kjell Ahlstedt +* VariantBase: Add is_castable_to(). +* VariantContainerBase: get_iter(): Accept casts of complicated types + containing object paths and DBus type signatures to Variant<> types + containing Glib::ustring and std::string. + (Kjell Ahlstedt) +* Variant: Wrap handles and add get_data_as_bytes() + (Kjell Ahlstedt) +* Added SignalProxyDetailed. + +Gio: +* Application: Add the shutdown signal. + (Murray Cumming) +* NetworkMonitor: Add get_network_metered() and property. + (Murray Cumming) +* Settings: Add signal_changed(key). + (Kjell Ahlstedt, Murray Cumming) +* Added SimpleIOStream. + (Kjell Ahlstedt) +* SocketService: Add active property. + (Murray Cumming) +* TlsClientConnection: Add copy_session_state(). + (Murray Cumming) + +Gio::Dbus: +* Connection::signal_subscribe(): Pass nullptr instead of "". + (Murray Cumming) + +gmmproc: +* Generate C++11 move operations. + (Murray Cumming) +* Mark all _CLASS_OPAQUE_REFCOUNTED classes as final (C++11). + (Murray Cumming) +* generate_wrap_init.pl: Allow use of nested namespaces for whole module. + (Marcin Kolny) +* _WRAP_METHOD: deprecated: Use G_GNUC_[BEGIN|END]_IGNORE_DEPRECATIONS + per function, instead of one big undef [G|GDK|GTK]_DISABLE_DEPRECATED. + (Kjell Ahlstedt) +* Add _IGNORE_PROPERTY() and _IGNORE_CHILD_PROPERTY() macros. + (Kjell Ahlstedt) +* Add support for 'newin "n,m"' in some _WRAP macros. + (Kjell Ahlstedt) +* _WRAP_SIGNAL: Add support for detail_name. + (Kjell Ahlstedt) +* Fetch property documentation from the docs.xml file, if available there. + (Kjell Ahlstedt) + +Build: +* MSVC Builds: Many improvements + (Chun-wei Fan) +* Add missing GLIBMM_API for Interface + (Mikhail Titov) + + 2.46.1 (stable): * gmmmproc: _CLASS_GOBJECT(): diff --git a/configure.ac b/configure.ac index e8dd8ce..ad1ce5f 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ ## You should have received a copy of the GNU Lesser General Public License ## along with this library. If not, see . -AC_INIT([glibmm], [2.46.1], +AC_INIT([glibmm], [2.46.2], [http://bugzilla.gnome.org/enter_bug.cgi?product=glibmm], [glibmm], [http://www.gtkmm.org/]) AC_PREREQ([2.59]) diff --git a/glib/glibmm/containers.h b/glib/glibmm/containers.h index 7d78854..a25ff6f 100644 --- a/glib/glibmm/containers.h +++ b/glib/glibmm/containers.h @@ -1,4 +1,3 @@ -// -*- c++ -*- #ifndef _GLIBMM_CONTAINERS_H #define _GLIBMM_CONTAINERS_H @@ -23,6 +22,7 @@ #include #include /* for backward compatibility */ +#include #include #include #include diff --git a/glib/glibmm/error.h b/glib/glibmm/error.h index 1886d9a..c9758ab 100644 --- a/glib/glibmm/error.h +++ b/glib/glibmm/error.h @@ -42,7 +42,7 @@ public: GQuark domain() const; int code() const; - virtual Glib::ustring what() const; + Glib::ustring what() const override; bool matches(GQuark error_domain, int error_code) const; diff --git a/glib/glibmm/interface.cc b/glib/glibmm/interface.cc index 7af932c..9d2bf30 100644 --- a/glib/glibmm/interface.cc +++ b/glib/glibmm/interface.cc @@ -1,6 +1,3 @@ -// -*- c++ -*- -/* $Id$ */ - /* Copyright (C) 2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or @@ -118,18 +115,25 @@ Interface::Interface() {} Interface::Interface(Interface&& src) noexcept -: ObjectBase(std::move(src)) +: sigc::trackable(std::move(src)), //not actually called because it's a virtual base + ObjectBase(std::move(src)) //not actually called because it's a virtual base { - //We don't call initialize_move() because we + //We don't call initialize_move() because we //want the derived move constructor to only cause it //to be called once, so we just let it be called - //by the implementing class, such as Entry (implementing Editable). + //by the implementing class, such as Gtk::Entry (implementing Gtk::Editable + //and Gtk::CellEditable), via the call to Object::Object(Object&& src). //ObjectBase::initialize_move(src.gobject_, &src); } -Interface& Interface::operator=(Interface&& src) noexcept +Interface& Interface::operator=(Interface&& /* src */) noexcept { - ObjectBase::operator=(std::move(src)); + //We don't call ObjectBase::operator=(ObjectBase&& src) because we + //want the derived move assignment operator to only cause it + //to be called once, so we just let it be called + //by the implementing class, such as Gtk::Entry (implementing Gtk::Editable + //and Gtk::CellEditable), via the call to Object::operator=(Object&& src). + //ObjectBase::operator=(std::move(src)); return *this; } diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h index 2dd9358..51d7ff9 100644 --- a/glib/glibmm/main.h +++ b/glib/glibmm/main.h @@ -821,9 +821,9 @@ protected: explicit TimeoutSource(unsigned int interval); virtual ~TimeoutSource() noexcept; - virtual bool prepare(int& timeout); - virtual bool check(); - virtual bool dispatch(sigc::slot_base* slot); + bool prepare(int& timeout) override; + bool check() override; + bool dispatch(sigc::slot_base* slot) override; private: //TODO: Replace with gint64, because TimeVal is deprecated, when we can break ABI. @@ -845,9 +845,9 @@ protected: IdleSource(); virtual ~IdleSource() noexcept; - virtual bool prepare(int& timeout); - virtual bool check(); - virtual bool dispatch(sigc::slot_base* slot_data); + bool prepare(int& timeout) override; + bool check() override; + bool dispatch(sigc::slot_base* slot_data) override; }; @@ -873,9 +873,9 @@ protected: virtual ~IOSource() noexcept; - virtual bool prepare(int& timeout); - virtual bool check(); - virtual bool dispatch(sigc::slot_base* slot); + bool prepare(int& timeout) override; + bool check() override; + bool dispatch(sigc::slot_base* slot) override; private: PollFD poll_fd_; diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc index 0373c5d..2f20189 100644 --- a/glib/glibmm/object.cc +++ b/glib/glibmm/object.cc @@ -1,6 +1,3 @@ -// -*- c++ -*- -/* $Id$ */ - /* Copyright 1998-2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or @@ -286,8 +283,13 @@ Object::Object(GObject* castitem) } Object::Object(Object&& src) noexcept -: ObjectBase(std::move(src)) //not actually called because it's a virtual base +: sigc::trackable(std::move(src)), //not actually called because it's a virtual base + ObjectBase(std::move(src)) //not actually called because it's a virtual base { + // Perhaps trackable's move constructor has not been called. Do its job here. + // (No harm is done if notify_callbacks() is called twice. The second call + // won't do anything.) + src.notify_callbacks(); ObjectBase::initialize_move(src.gobject_, &src); } diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc index 1a1f522..874958f 100644 --- a/glib/glibmm/objectbase.cc +++ b/glib/glibmm/objectbase.cc @@ -113,22 +113,28 @@ void ObjectBase::initialize_move(GObject* castitem, Glib::ObjectBase* previous_w } ObjectBase::ObjectBase(ObjectBase&& src) noexcept -: sigc::trackable(std::move(src)), - gobject_(std::move(src.gobject_)), - custom_type_name_(std::move(src.custom_type_name_)), - cpp_destruction_in_progress_(std::move(src.custom_type_name_)) +: sigc::trackable(std::move(src)), //not actually called because it's a virtual base + gobject_(nullptr), + custom_type_name_(src.custom_type_name_), + cpp_destruction_in_progress_(src.cpp_destruction_in_progress_) {} ObjectBase& ObjectBase::operator=(ObjectBase&& src) noexcept { + if (this == &src) + return *this; + sigc::trackable::operator=(std::move(src)); - if(gobject_) + if (gobject_) + { + // Remove the wrapper, without invoking destroy_notify_callback_(): + g_object_steal_qdata(gobject_, Glib::quark_); + // Remove a reference, without deleting *this. unreference(); - - gobject_ = std::move(src.gobject_); - custom_type_name_ = std::move(src.custom_type_name_); - cpp_destruction_in_progress_ = std::move(src.custom_type_name_); + gobject_ = nullptr; + } + initialize_move(src.gobject_, &src); return *this; } @@ -229,7 +235,8 @@ void ObjectBase::_move_current_wrapper(GObject* object, Glib::ObjectBase* previo g_warning("%s: Unexpected previous wrapper, for object of type %s.\n" "previous_wrapper=%p, current_wrapper=%p", G_STRFUNC, G_OBJECT_TYPE_NAME(object), - previous_wrapper, current_wrapper); + static_cast(previous_wrapper), + static_cast(current_wrapper)); } //Remove the previous wrapper, without invoking destroy_notify_callback_(): diff --git a/glib/glibmm/streamiochannel.h b/glib/glibmm/streamiochannel.h index 7c243ba..8b6f98c 100644 --- a/glib/glibmm/streamiochannel.h +++ b/glib/glibmm/streamiochannel.h @@ -46,13 +46,13 @@ protected: StreamIOChannel(std::istream* stream_in, std::ostream* stream_out); - virtual IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read); - virtual IOStatus write_vfunc(const char* buf, gsize count, gsize& bytes_written); - virtual IOStatus seek_vfunc(gint64 offset, SeekType type); - virtual IOStatus close_vfunc(); - virtual IOStatus set_flags_vfunc(IOFlags flags); - virtual IOFlags get_flags_vfunc(); - virtual Glib::RefPtr create_watch_vfunc(IOCondition cond); + IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read) override; + IOStatus write_vfunc(const char* buf, gsize count, gsize& bytes_written) override; + IOStatus seek_vfunc(gint64 offset, SeekType type) override; + IOStatus close_vfunc() override; + IOStatus set_flags_vfunc(IOFlags flags) override; + IOFlags get_flags_vfunc() override; + Glib::RefPtr create_watch_vfunc(IOCondition cond) override; }; #endif //#GLIBMM_DISABLE_DEPRECATED diff --git a/tests/glibmm_interface_move/main.cc b/tests/glibmm_interface_move/main.cc index 29662e9..28b8e8f 100644 --- a/tests/glibmm_interface_move/main.cc +++ b/tests/glibmm_interface_move/main.cc @@ -106,7 +106,7 @@ protected: public: //A real application would never make the constructor public. - //It would instead have a protectd constructor and a public create() method. + //It would instead have a protected constructor and a public create() method. TestInterface(GObject* gobject, int i) : Glib::Interface(gobject), i_(i) @@ -220,7 +220,10 @@ private: DerivedObject::CppClassType DerivedObject::derived_object_class_; // initialize static member -/* TODO: Shouldn't this work too? +/* Shouldn't this work too? + * No, because Glib::Interface::Interface(Interface&& src) does not call + * Glib::ObjectBase::initialize_move(), and Glib::Interface::operator=(Interface&& src) + * does not call Glib::ObjectBase::operator=(std::move(src)). static void test_interface_move_constructor() { @@ -258,11 +261,13 @@ void test_object_with_interface_move_constructor() { DerivedObject derived(5); g_assert_cmpint(derived.i_, ==, 5); - GObject *gobject = derived.gobj(); + GObject* gobject = derived.gobj(); g_assert(derived.gobj() == gobject); + DerivedObject derived2(std::move(derived)); g_assert_cmpint(derived2.i_, ==, 5); g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } static @@ -270,11 +275,14 @@ void test_object_with_interface_move_assignment_operator() { DerivedObject derived(5); g_assert_cmpint(derived.i_, ==, 5); - GObject *gobject = derived.gobj(); + GObject* gobject = derived.gobj(); g_assert(derived.gobj() == gobject); - DerivedObject derived2 = std::move(derived); + + DerivedObject derived2(6); + derived2 = std::move(derived); g_assert_cmpint(derived2.i_, ==, 5); g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } diff --git a/tests/glibmm_object_move/main.cc b/tests/glibmm_object_move/main.cc index a62bcf9..7868b17 100644 --- a/tests/glibmm_object_move/main.cc +++ b/tests/glibmm_object_move/main.cc @@ -2,7 +2,7 @@ #include #include -//A basic derived GObject, just to test Glib::ObjectBase. +//A basic derived GObject, just to test Glib::Object. typedef struct { GObject parent; } TestDerived; @@ -27,7 +27,7 @@ class DerivedObject : public Glib::Object { public: //A real application would never make the constructor public. - //It would instead have a protectd constructor and a public create() method. + //It would instead have a protected constructor and a public create() method. DerivedObject(GObject* gobject, int i) : Glib::Object(gobject), i_(i) @@ -56,32 +56,34 @@ public: static void test_object_move_constructor() { - GObject *gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); - g_object_ref(gobject); - + GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); DerivedObject derived(gobject, 5); std::cout << "debug: gobj(): " << derived.gobj() << std::endl; g_assert(derived.gobj() == gobject); + DerivedObject derived2(std::move(derived)); g_assert_cmpint(derived2.i_, ==, 5); std::cout << "debug: gobj(): " << derived2.gobj() << std::endl; g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } static void test_object_move_assignment_operator() { - GObject *gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); - g_object_ref(gobject); - + GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); DerivedObject derived(gobject, 5); //std::cout << "debug: gobj(): " << derived.gobj() << std::endl; g_assert(derived.gobj() == gobject); - DerivedObject derived2 = std::move(derived); + + GObject* gobject2 = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); + DerivedObject derived2(gobject2, 6); + derived2 = std::move(derived); g_assert_cmpint(derived2.i_, ==, 5); //std::cout << "debug: gobj(): " << derived2.gobj() << std::endl; g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } diff --git a/tests/glibmm_objectbase_move/main.cc b/tests/glibmm_objectbase_move/main.cc index ed71fe1..e70ff3b 100644 --- a/tests/glibmm_objectbase_move/main.cc +++ b/tests/glibmm_objectbase_move/main.cc @@ -28,7 +28,7 @@ class DerivedObjectBase : public Glib::ObjectBase { public: //A real application would never make the constructor public. - //It would instead have a protectd constructor and a public create() method. + //It would instead have a protected constructor and a public create() method. DerivedObjectBase(GObject* gobject, int i) : Glib::ObjectBase(nullptr), i_(i) @@ -42,7 +42,9 @@ public: DerivedObjectBase(DerivedObjectBase&& src) noexcept : Glib::ObjectBase(std::move(src)), i_(std::move(src.i_)) - {} + { + ObjectBase::initialize_move(src.gobject_, &src); + } DerivedObjectBase& operator=(DerivedObjectBase&& src) noexcept { @@ -58,31 +60,33 @@ public: static void test_objectbase_move_constructor() { - GObject *gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); - g_object_ref(gobject); - + GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); DerivedObjectBase derived(gobject, 5); //std::cout << "debug: gobj(): " << derived.gobj() << std::endl; g_assert(derived.gobj() == gobject); + DerivedObjectBase derived2(std::move(derived)); g_assert_cmpint(derived2.i_, ==, 5); //std::cout << "debug: gobj(): " << derived2.gobj() << std::endl; g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } static void test_objectbase_move_assignment_operator() { - GObject *gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); - g_object_ref(gobject); - + GObject* gobject = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); DerivedObjectBase derived(gobject, 5); //std::cout << "debug: gobj(): " << derived.gobj() << std::endl; g_assert(derived.gobj() == gobject); - DerivedObjectBase derived2 = std::move(derived); + + GObject* gobject2 = G_OBJECT(g_object_new(TEST_TYPE_DERIVED, nullptr)); + DerivedObjectBase derived2(gobject2, 6); + derived2 = std::move(derived); g_assert_cmpint(derived2.i_, ==, 5); //std::cout << "debug: gobj(): " << derived2.gobj() << std::endl; g_assert(derived2.gobj() == gobject); + g_assert(derived.gobj() == nullptr); } int main(int, char**) -- 2.7.4