From 13cc31d6c5e15c4c05db5504369d02357d19f292 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 7 Sep 2020 00:18:22 -0700 Subject: [PATCH] Imported Upstream version 2.51.2 --- NEWS | 20 +++++++++ configure.ac | 2 +- gio/src/action.ccg | 2 - gio/src/action.hg | 8 +--- gio/src/actionmap.ccg | 2 +- gio/src/actionmap.hg | 4 +- gio/src/simpleaction.hg | 14 ++----- glib/glibmm/class.cc | 52 ++++++++++++++++++----- glib/glibmm/class.h | 21 ++++++---- glib/glibmm/extraclassinit.cc | 32 ++++++++++++++ glib/glibmm/extraclassinit.h | 97 +++++++++++++++++++++++++++++++++++++++++++ glib/glibmm/filelist.am | 2 + glib/glibmm/interface.cc | 7 ++-- glib/glibmm/object.cc | 18 ++++---- glib/glibmm/objectbase.cc | 54 ++++++++++++++++++++++++ glib/glibmm/objectbase.h | 22 +++++++--- glib/src/variant.ccg | 20 ++------- glib/src/variant.hg | 24 ++++++----- 18 files changed, 316 insertions(+), 85 deletions(-) create mode 100644 glib/glibmm/extraclassinit.cc create mode 100644 glib/glibmm/extraclassinit.h diff --git a/NEWS b/NEWS index 568d3c1..672b214 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,23 @@ +2.51.2 (unstable): +Distro packagers should probably not package this yet. + +Glib: +* Object construction: Add custom class init and instance init functions + An extra class init function is useful in Gtk::WidgetCustomDraw and + Gtk::WidgetCustomSnapshot. + (Kjell Ahlstedt) Bug #775348 + +Gio: +* Action: #include , for convenience. + (Daniel Boles) Bug #777953 +* SimpleAction: Make set_state() public. + (Daniel Boles) Bug #777953 + +Documentation: +* Glib::Variant: Explain how to create "maybe" type. + (Daniel Boles) Bug #778219 + + 2.51.1.2 (unstable): Distro packagers should probably not package this yet. diff --git a/configure.ac b/configure.ac index 5c7c7cb..6167baf 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.51.1.2], +AC_INIT([glibmm], [2.51.2], [http://bugzilla.gnome.org/enter_bug.cgi?product=glibmm], [glibmm], [http://www.gtkmm.org/]) AC_PREREQ([2.59]) diff --git a/gio/src/action.ccg b/gio/src/action.ccg index 9dbb598..c5a1735 100644 --- a/gio/src/action.ccg +++ b/gio/src/action.ccg @@ -17,8 +17,6 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include namespace Gio diff --git a/gio/src/action.hg b/gio/src/action.hg index b9b5993..067a230 100644 --- a/gio/src/action.hg +++ b/gio/src/action.hg @@ -18,6 +18,7 @@ _CONFIGINCLUDE(giommconfig.h) #include +#include #include #include @@ -29,13 +30,6 @@ _PINCLUDE(gio/gio.h) typedef struct _GActionInterface GActionInterface; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ -namespace Glib -{ - -class VariantBase; - -} - namespace Gio { diff --git a/gio/src/actionmap.ccg b/gio/src/actionmap.ccg index 5598642..ff79bbd 100644 --- a/gio/src/actionmap.ccg +++ b/gio/src/actionmap.ccg @@ -41,7 +41,7 @@ ActionMap::add_action(const Glib::ustring& name, const ActivateSlot& slot) Glib::RefPtr ActionMap::add_action_with_parameter( - const Glib::ustring& name, const ActivateWithParameterSlot& slot, const Glib::VariantType& parameter_type) + const Glib::ustring& name, const Glib::VariantType& parameter_type, const ActivateWithParameterSlot& slot) { auto action = SimpleAction::create(name, parameter_type); action->signal_activate().connect(slot); diff --git a/gio/src/actionmap.hg b/gio/src/actionmap.hg index 1ae1615..28b6492 100644 --- a/gio/src/actionmap.hg +++ b/gio/src/actionmap.hg @@ -96,11 +96,11 @@ public: * and adding it to the ActionMap. * * @param name The name of the Action. - * @param slot The callback method to be called when the action is activated. * @param parameter_type The type of parameter to be passed to the slot. + * @param slot The callback method to be called when the action is activated. * @return The Action. */ - Glib::RefPtr add_action_with_parameter(const Glib::ustring& name, const ActivateWithParameterSlot& slot, const Glib::VariantType& parameter_type); + Glib::RefPtr add_action_with_parameter(const Glib::ustring& name, const Glib::VariantType& parameter_type, const ActivateWithParameterSlot& slot); /** A convenience method for creating a boolean-stateful SimpleAction instance diff --git a/gio/src/simpleaction.hg b/gio/src/simpleaction.hg index d1e6f23..fe7e669 100644 --- a/gio/src/simpleaction.hg +++ b/gio/src/simpleaction.hg @@ -53,9 +53,7 @@ protected: */ explicit SimpleAction(const Glib::ustring& name); - /** Creates a new new stateful action. - * - * The created action is stateless. + /** Creates a new stateful action. * * @a state is the initial state of the action. All future state values * must have the same VariantType as the initial state. @@ -146,6 +144,9 @@ public: _WRAP_METHOD(void set_enabled(bool enabled = true), g_simple_action_set_enabled) + //TODO: Add templated version of this, renaming this to set_state_variant(), like Action::change_state()? + _WRAP_METHOD(void set_state(const Glib::VariantBase& value), g_simple_action_set_state) + _WRAP_METHOD(void set_state_hint(const Glib::VariantBase& state_hint), g_simple_action_set_state_hint) _WRAP_PROPERTY("enabled", bool) @@ -158,13 +159,6 @@ public: _WRAP_SIGNAL(void activate(const Glib::VariantBase& parameter), "activate", no_default_handler) _WRAP_SIGNAL(void change_state(const Glib::VariantBase& value), "change-state", no_default_handler) - -protected: - - //TODO: Add templated version of this, renaming this to set_state_variant(), like Action::change_state()? - //This is protected because the C docs say "This should only be called by the implementor of the action." - // though that is not entirely clear. We can make this public if somebody needs it. - _WRAP_METHOD(void set_state(const Glib::VariantBase& value), g_simple_action_set_state) }; } // namespace Gio diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc index 696bf79..29ab8cf 100644 --- a/glib/glibmm/class.cc +++ b/glib/glibmm/class.cc @@ -86,7 +86,8 @@ Class::register_derived_type(GType base_type, GTypeModule* module) GType Class::clone_custom_type( - const char* custom_type_name, const interface_class_list_type& interface_classes) const + const char* custom_type_name, const interface_classes_type* interface_classes, + const class_init_funcs_type* class_init_funcs, GInstanceInitFunc instance_init_func) const { std::string full_name("gtkmm__CustomObject_"); Glib::append_canonical_typename(full_name, custom_type_name); @@ -112,29 +113,43 @@ Class::clone_custom_type( // GTypeQuery::instance_size is guint but GTypeInfo::instance_size is guint16. const guint16 instance_size = (guint16)base_query.instance_size; + // Let the wrapper's class_init_function() be the first one to call. + auto all_class_init_funcs = new class_init_funcs_type( + 1, std::tuple(class_init_func_, nullptr)); + if (class_init_funcs) + all_class_init_funcs->insert(all_class_init_funcs->end(), + class_init_funcs->begin(), class_init_funcs->end()); + const GTypeInfo derived_info = { class_size, nullptr, // base_init &Class::custom_class_base_finalize_function, // base_finalize &Class::custom_class_init_function, nullptr, // class_finalize - this, // class_data + all_class_init_funcs, // class_data instance_size, 0, // n_preallocs - nullptr, // instance_init + instance_init_func, // instance_init nullptr, // value_table }; + // custom_class_init_function() is called when the first object of the custom + // class is created, which is after clone_custom_type() has returned. + // Let custom_class_init_function() delete all_class_init_funcs. + custom_type = g_type_register_static(base_type, full_name.c_str(), &derived_info, GTypeFlags(0)); // Add derived versions of interfaces, if the C type implements any interfaces. // For instance, TreeModel_Class::add_interface(). - for (auto interface_class : interface_classes) + if (interface_classes) { - if (interface_class) + for (auto interface_class : *interface_classes) { - interface_class->add_interface(custom_type); + if (interface_class) + { + interface_class->add_interface(custom_type); + } } } } @@ -170,19 +185,36 @@ Class::custom_class_base_finalize_function(void* g_class) void Class::custom_class_init_function(void* g_class, void* class_data) { - // The class_data pointer is set to 'this' by clone_custom_type(). - const Class* const self = static_cast(class_data); + // clone_custom_type() sets the class data pointer to a pointer to a vector + // of pointers to functions to be called. + const class_init_funcs_type& class_init_funcs = + *static_cast(class_data); - g_return_if_fail(self->class_init_func_ != nullptr); + g_return_if_fail(!class_init_funcs.empty() && std::get(class_init_funcs[0]) != nullptr); // Call the wrapper's class_init_function() to redirect // the vfunc and default signal handler callbacks. - (*self->class_init_func_)(g_class, nullptr); + auto init_func = std::get(class_init_funcs[0]); + (*init_func)(g_class, nullptr); GObjectClass* const gobject_class = static_cast(g_class); gobject_class->get_property = &Glib::custom_get_property_callback; gobject_class->set_property = &Glib::custom_set_property_callback; + // Call extra class init functions, if any. + for (std::size_t i = 1; i < class_init_funcs.size(); ++i) + { + if (auto extra_init_func = std::get(class_init_funcs[i])) + { + auto extra_class_data = std::get(class_init_funcs[i]); + (*extra_init_func)(g_class, extra_class_data); + } + } + + // Assume that this function is called exactly once for each type. + // Delete the class_init_funcs_type that was created in clone_custom_type(). + delete static_cast(class_data); + // Override the properties of implemented interfaces, if any. const GType object_type = G_TYPE_FROM_CLASS(g_class); diff --git a/glib/glibmm/class.h b/glib/glibmm/class.h index 849065b..e790715 100644 --- a/glib/glibmm/class.h +++ b/glib/glibmm/class.h @@ -23,7 +23,7 @@ #include //Include this here so that the /private/*.h classes have access to GLIBMM_VFUNCS_ENABLED #include //For interface properties that custom types might override. -#include //For interface classes that custom types might implement. +#include #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -52,11 +52,13 @@ public: inline GType get_type() const; - /** The type that holds pointers to the interfaces of custom types. - * It's usually empty and never long. It's a std::forward_list to minimize - * storage requirement. + /// The type that holds pointers to the interfaces of custom types. + using interface_classes_type = std::vector; + /** The type that holds pointers to extra class init functions of custom types. + * The std::tuple contains a function pointer and a pointer to class data. + * The class data pointer can be nullptr, if the function does not need it. */ - using interface_class_list_type = std::forward_list; + using class_init_funcs_type = std::vector>; /** Register a static custom GType, derived from the parent of this class's type. * The parent type of the registered custom type is the same C class as the parent @@ -65,11 +67,16 @@ public: * @param custom_type_name The name of the registered type is * "gtkmm__CustomObject_" + canonic(custom_type_name), where canonic() * replaces special characters with '+'. - * @param interface_classes Interfaces that the custom type implements. + * @param interface_classes Interfaces that the custom type implements (can be nullptr). + * @param class_init_funcs Extra class init functions (can be nullptr). These + * functions, if any, are called after the class init function of this + * class's type, e.g. Gtk::Widget. + * @param instance_init_func Instance init function (can be nullptr). * @return The registered type. */ GType clone_custom_type( - const char* custom_type_name, const interface_class_list_type& interface_classes) const; + const char* custom_type_name, const interface_classes_type* interface_classes, + const class_init_funcs_type* class_init_funcs, GInstanceInitFunc instance_init_func) const; protected: GType gtype_; diff --git a/glib/glibmm/extraclassinit.cc b/glib/glibmm/extraclassinit.cc new file mode 100644 index 0000000..343fc6f --- /dev/null +++ b/glib/glibmm/extraclassinit.cc @@ -0,0 +1,32 @@ +/* Copyright (C) 2017 The glibmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include + +namespace Glib +{ + +ExtraClassInit::ExtraClassInit(GClassInitFunc class_init_func, void* class_data, + GInstanceInitFunc instance_init_func) +{ + if (class_init_func) + add_custom_class_init_function(class_init_func, class_data); + + if (instance_init_func) + set_custom_instance_init_function(instance_init_func); +} + +} // namespace Glib diff --git a/glib/glibmm/extraclassinit.h b/glib/glibmm/extraclassinit.h new file mode 100644 index 0000000..9d2fc60 --- /dev/null +++ b/glib/glibmm/extraclassinit.h @@ -0,0 +1,97 @@ +#ifndef _GLIBMM_EXTRACLASSINIT_H +#define _GLIBMM_EXTRACLASSINIT_H +/* Copyright (C) 2017 The glibmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include + +namespace Glib +{ + +/** A convenience class for named custom types. + * + * Use it if you need to add code to GType's class init function and/or + * need an instance init function. + * Example: + * @code + * #include + * + * class MyExtraInit : public Glib::ExtraClassInit + * { + * public: + * MyExtraInit(const Glib::ustring& css_name) + * : + * Glib::ExtraClassInit(my_extra_class_init_function, &m_css_name, my_instance_init_function), + * m_css_name(css_name) + * { } + * + * private: + * static void my_extra_class_init_function(void* g_class, void* class_data) + * { + * const auto klass = static_cast(g_class); + * const auto css_name = static_cast(class_data); + * gtk_widget_class_set_css_name(klass, css_name->c_str()); + * } + * static void my_instance_init_function(GTypeInstance* instance, void* g_class) + * { + * gtk_widget_set_has_window(GTK_WIDGET(instance), true); + * } + * + * Glib::ustring m_css_name; + * }; + * + * class MyWidget : public Gtk::WidgetCustomDraw, public MyExtraInit, public Gtk::Widget + * { + * public: + * MyWidget() + * : + * // The GType name will be gtkmm__CustomObject_MyMidget + * Glib::ObjectBase("MyWidget"), // Unique class name + * Gtk::WidgetCustomDraw(), + * MyExtraInit("my-widget"), + * Gtk::Widget() + * { + * // ... + * } + * // ... + * }; + * @endcode + * + * @note Classes derived from %ExtraClassInit (Gtk::WidgetCustomDraw and MyExtraInit + * in the example) must be listed before Glib::Object or a class derived from + * %Glib::Object (Gtk::Widget in the example) in the list of base classes. + * + * @newin{2,52} + */ +class ExtraClassInit : virtual public ObjectBase +{ +protected: + /** Constructor. + * + * @param class_init_func Pointer to an extra class init function. + * nullptr, if no extra class init function is needed. + * @param class_data Class data pointer, passed to the class init function. + * Can be nullptr, if the class init function does not need it. + * @param instance_init_func Pointer to an instance init function. + * nullptr, if no instance init function is needed. + */ + explicit ExtraClassInit(GClassInitFunc class_init_func, void* class_data = nullptr, + GInstanceInitFunc instance_init_func = nullptr); +}; + +} // namespace Glib + +#endif /* _GLIBMM_EXTRACLASSINIT_H */ diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am index afeb2b4..e04a0b7 100644 --- a/glib/glibmm/filelist.am +++ b/glib/glibmm/filelist.am @@ -14,6 +14,7 @@ glibmm_files_extra_cc = \ error.cc \ exception.cc \ exceptionhandler.cc \ + extraclassinit.cc \ init.cc \ interface.cc \ main.cc \ @@ -50,6 +51,7 @@ glibmm_files_extra_h = \ error.h \ exception.h \ exceptionhandler.h \ + extraclassinit.h \ helperlist.h \ i18n-lib.h \ i18n.h \ diff --git a/glib/glibmm/interface.cc b/glib/glibmm/interface.cc index 0429840..31a5278 100644 --- a/glib/glibmm/interface.cc +++ b/glib/glibmm/interface.cc @@ -96,10 +96,9 @@ Interface::Interface(const Interface_Class& interface_class) } else // gobject_ == nullptr { - // The GObject is not instantiated yet. Add to the custom_interface_classes_ - // and add the interface in the Glib::Object constructor. - // custom_interface_classes_ is a std::forward_list. There is no emplace_back(). - custom_interface_classes_.emplace_front(&interface_class); + // The GObject is not instantiated yet. Add to the stored custom interface + // classes, and add the interface to the GType in the Glib::Object constructor. + add_custom_interface_class(&interface_class); } } } diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc index 19f30d5..4dd8d4e 100644 --- a/glib/glibmm/object.cc +++ b/glib/glibmm/object.cc @@ -195,13 +195,12 @@ Object::Object() if (custom_type_name_ && !is_anonymous_custom_()) { object_class_.init(); - // Reverse the interface class list in order to have the interfaces added - // in the same order as they are declared. (Don't know if it makes any difference, - // but it's an inexpensive operation. The list is often empty, never long.) - custom_interface_classes_.reverse(); + // This creates a type that is derived (indirectly) from GObject. - object_type = object_class_.clone_custom_type(custom_type_name_, custom_interface_classes_); - custom_interface_classes_.clear(); + object_type = object_class_.clone_custom_type(custom_type_name_, + get_custom_interface_classes(), get_custom_class_init_functions(), + get_custom_instance_init_function()); + custom_class_init_finished(); } void* const new_object = g_object_newv(object_type, 0, nullptr); @@ -220,10 +219,11 @@ Object::Object(const Glib::ConstructParams& construct_params) if (custom_type_name_ && !is_anonymous_custom_()) { - custom_interface_classes_.reverse(); object_type = - construct_params.glibmm_class.clone_custom_type(custom_type_name_, custom_interface_classes_); - custom_interface_classes_.clear(); + construct_params.glibmm_class.clone_custom_type(custom_type_name_, + get_custom_interface_classes(), get_custom_class_init_functions(), + get_custom_instance_init_function()); + custom_class_init_finished(); } // Create a new GObject with the specified array of construct properties. diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc index 429d11d..7e36414 100644 --- a/glib/glibmm/objectbase.cc +++ b/glib/glibmm/objectbase.cc @@ -40,6 +40,17 @@ namespace Glib /**** Glib::ObjectBase *****************************************************/ +// Used only during the construction of named custom types. +struct ObjectBase::PrivImpl +{ + // Pointers to the interfaces of custom types. + Class::interface_classes_type custom_interface_classes; + // Pointers to extra class init functions. + Class::class_init_funcs_type custom_class_init_functions; + // Pointer to the instance init function. + GInstanceInitFunc custom_instance_init_function = nullptr; +}; + ObjectBase::ObjectBase() : gobject_(nullptr), custom_type_name_(anonymous_custom_type_name), @@ -379,6 +390,49 @@ ObjectBase::thaw_notify() g_object_thaw_notify(gobj()); } +void ObjectBase::add_custom_interface_class(const Interface_Class* iface_class) +{ + if (!priv_pimpl_) + priv_pimpl_ = std::make_unique(); + priv_pimpl_->custom_interface_classes.emplace_back(iface_class); +} + +void ObjectBase::add_custom_class_init_function(GClassInitFunc class_init_func, void* class_data) +{ + if (!priv_pimpl_) + priv_pimpl_ = std::make_unique(); + priv_pimpl_->custom_class_init_functions.emplace_back( + std::make_tuple(class_init_func, class_data)); +} + +void ObjectBase::set_custom_instance_init_function(GInstanceInitFunc instance_init_func) +{ + if (!priv_pimpl_) + priv_pimpl_ = std::make_unique(); + priv_pimpl_->custom_instance_init_function = instance_init_func; +} + +const Class::interface_classes_type* ObjectBase::get_custom_interface_classes() const +{ + return priv_pimpl_ ? &priv_pimpl_->custom_interface_classes : nullptr; +} + +const Class::class_init_funcs_type* ObjectBase::get_custom_class_init_functions() const +{ + return priv_pimpl_ ? &priv_pimpl_->custom_class_init_functions : nullptr; +} + +GInstanceInitFunc ObjectBase::get_custom_instance_init_function() const +{ + return priv_pimpl_ ? priv_pimpl_->custom_instance_init_function : nullptr; +} + +void ObjectBase::custom_class_init_finished() +{ + priv_pimpl_.reset(); +} + +/**** Global function *****************************************************/ bool _gobject_cppinstance_already_deleted(GObject* gobject) { diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h index 4dce060..3faed9d 100644 --- a/glib/glibmm/objectbase.h +++ b/glib/glibmm/objectbase.h @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { @@ -202,9 +203,15 @@ protected: bool is_anonymous_custom_() const; - // List of pointers to the interfaces of custom types. - // Used only during the construction of named custom types. - Class::interface_class_list_type custom_interface_classes_; + // The following 7 methods are used by Glib::ExtraClassInit, Glib::Interface + // and Glib::Object during construction of a named custom type. + void add_custom_interface_class(const Interface_Class* iface_class); + void add_custom_class_init_function(GClassInitFunc class_init_func, void* class_data = nullptr); + void set_custom_instance_init_function(GInstanceInitFunc instance_init_func); + const Class::interface_classes_type* get_custom_interface_classes() const; + const Class::class_init_funcs_type* get_custom_class_init_functions() const; + GInstanceInitFunc get_custom_instance_init_function() const; + void custom_class_init_finished(); public: // is_derived_() must be public, so that overridden vfuncs and signal handlers can call it @@ -232,12 +239,15 @@ protected: private: #ifndef DOXYGEN_SHOULD_SKIP_THIS + // Private part of implementation. + // Used only during construction of named custom types. + struct PrivImpl; + std::unique_ptr priv_pimpl_; + virtual void set_manage(); // calls g_error() -#endif // DOXYGEN_SHOULD_SKIP_THIS -#ifndef DOXYGEN_SHOULD_SKIP_THIS friend class Glib::GSigConnectionNode; // for GSigConnectionNode::notify() -#endif +#endif // DOXYGEN_SHOULD_SKIP_THIS }; #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/glib/src/variant.ccg b/glib/src/variant.ccg index 89e557d..2418798 100644 --- a/glib/src/variant.ccg +++ b/glib/src/variant.ccg @@ -28,13 +28,10 @@ VariantBase::VariantBase(GVariant* castitem, bool make_a_copy /* = false */) if (castitem) { if (g_variant_is_floating(castitem)) - { g_variant_ref_sink(castitem); - } + if (make_a_copy) - { g_variant_ref(castitem); - } } gobject_ = castitem; @@ -158,9 +155,7 @@ VariantContainerBase::create_tuple(const std::vector& children) var_ptr* const var_array = new var_ptr[children.size()]; for (std::vector::size_type i = 0; i < children.size(); i++) - { var_array[i] = const_cast(children[i].gobj()); - } VariantContainerBase result = VariantContainerBase(g_variant_new_tuple(var_array, children.size())); @@ -202,9 +197,8 @@ VariantContainerBase VariantBase::cast_dynamic(const VariantBase& v) throw(std::bad_cast) { if (!v.gobj()) - { return VariantContainerBase(); - } + if (v.get_type().is_container()) { return VariantContainerBase(const_cast(v.gobj()), true); @@ -227,7 +221,9 @@ VariantContainerBase::get_maybe(VariantBase& maybe) const return true; } else + { return false; + } } VariantIter @@ -401,9 +397,7 @@ Variant::create(const type_vec_ustring& data) // Add the elements of the vector into the builder. for (const auto& str : data) - { g_variant_builder_add(builder, element_variant_type.get_string().c_str(), str.c_str()); - } // Create the variant using the builder. auto result = @@ -438,7 +432,6 @@ Variant::get() const for (gsize i = 0; i < n_children; i++) { GVariant* gvariant = g_variant_get_child_value(const_cast(gobj()), i); - result.emplace_back(Glib::Variant(gvariant).get()); } @@ -479,9 +472,7 @@ Variant::create(const type_vec_string& data) // Add the elements of the vector into the string array. for (type_vec_string::size_type i = 0; i < data.size(); i++) - { str_array[i] = g_strdup(data[i].c_str()); - } // Terminate the string array. str_array[data.size()] = nullptr; @@ -502,9 +493,7 @@ Variant::create_from_object_paths(const type_vec_string& data) // Add the elements of the vector into the string array. for (type_vec_string::size_type i = 0; i < data.size(); i++) - { str_array[i] = g_strdup(data[i].c_str()); - } // Terminate the string array. str_array[data.size()] = nullptr; @@ -542,7 +531,6 @@ Variant::get() const for (gsize i = 0; i < n_children; i++) { GVariant* gvariant = g_variant_get_child_value(const_cast(gobj()), i); - result.emplace_back(Glib::Variant(gvariant).get()); } diff --git a/glib/src/variant.hg b/glib/src/variant.hg index 6900dbe..92e0b6b 100644 --- a/glib/src/variant.hg +++ b/glib/src/variant.hg @@ -316,8 +316,8 @@ public: _WRAP_METHOD(static bool is_signature(const std::string& string), g_variant_is_signature) }; -/** The base class from which multiple-item Variants derive, such as Variants - * containing tuples or arrays. +/** The base class for multiple-item Variants, such as Variants containing + * tuples or arrays, and also for maybe-typed (i.e. nullable) Variant types. * * @newin{2,28} * @ingroup Variant @@ -387,11 +387,12 @@ public: DataType get_child(gsize index = 0) const; */ - /** If this is a maybe-typed instance, extract its value. If the value is - * Nothing, then this function returns false. + /** If this is a maybe-typed instance, try to extract its value. If there is + * no value (the value is nothing), return falsetrue is returned. * - * @param maybe A place in which to return the value (the value may be - * 0). + * @param maybe A place in which to return the value, if it isn’t + * nothing. * @newin{2,28} */ bool get_maybe(VariantBase& maybe) const; @@ -424,6 +425,9 @@ public: /****************** Specializations ***********************************/ /** Specialization of Variant containing a VariantBase. + * Perhaps the main use of this is as a maybe-typed (i.e. nullable) Variant, as + * it inherits methods create_maybe() and get_maybe() from VariantContainerBase. + * * @newin{2,28} * @ingroup Variant */ @@ -719,7 +723,7 @@ public: _IGNORE(g_variant_get_fixed_array) /** Gets a VariantIter of the Variant. - * @return the VaraintIter. + * @return the VariantIter. * @newin{2,28} */ VariantIter get_iter() const; @@ -783,7 +787,7 @@ public: _IGNORE(g_variant_get_strv, g_variant_dup_strv) /** Gets a VariantIter of the Variant. - * @return the VaraintIter. + * @return the VariantIter. * @newin{2,28} */ VariantIter get_iter() const; @@ -859,7 +863,7 @@ public: _IGNORE(g_variant_get_objv, g_variant_dup_objv) /** Gets a VariantIter of the Variant. - * @return the VaraintIter. + * @return the VariantIter. * @newin{2,28} */ VariantIter get_iter() const; @@ -934,7 +938,7 @@ public: std::map get() const; /** Gets a VariantIter of the Variant. - * @return the VaraintIter. + * @return the VariantIter. * @newin{2,28} */ VariantIter get_iter() const; -- 2.7.4