+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():
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
-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])
-// -*- c++ -*-
#ifndef _GLIBMM_CONTAINERS_H
#define _GLIBMM_CONTAINERS_H
#include <glibmmconfig.h>
#include <glibmm/sarray.h> /* for backward compatibility */
+#include <glibmm/wrap.h>
#include <glib.h>
#include <iterator>
#include <cstddef>
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;
-// -*- c++ -*-
-/* $Id$ */
-
/* Copyright (C) 2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
{}
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;
}
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.
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;
};
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_;
-// -*- c++ -*-
-/* $Id$ */
-
/* Copyright 1998-2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
}
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);
}
}
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;
}
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<void*>(previous_wrapper),
+ static_cast<void*>(current_wrapper));
}
//Remove the previous wrapper, without invoking destroy_notify_callback_():
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<Glib::Source> 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<Glib::Source> create_watch_vfunc(IOCondition cond) override;
};
#endif //#GLIBMM_DISABLE_DEPRECATED
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)
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()
{
{
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
{
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);
}
#include <iostream>
#include <stdlib.h>
-//A basic derived GObject, just to test Glib::ObjectBase.
+//A basic derived GObject, just to test Glib::Object.
typedef struct {
GObject parent;
} TestDerived;
{
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)
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);
}
{
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)
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
{
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**)