Imported Upstream version 2.51.1.2 upstream/2.51.1.2
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:18:01 +0000 (00:18 -0700)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:18:01 +0000 (00:18 -0700)
40 files changed:
MSVC_Net2013/glibmm-install.props
NEWS
configure.ac
examples/child_watch/main.cc
examples/network/socket-client.cc
examples/network/socket-server.cc
gio/src/action.hg
gio/src/actiongroup.hg
gio/src/actionmap.ccg
gio/src/actionmap.hg
gio/src/asyncresult.hg
gio/src/file.hg
gio/src/fileinfo.hg
gio/src/fileiostream.hg
gio/src/fileoutputstream.hg
gio/src/gio_vfuncs.defs
gio/src/memoryinputstream.ccg
gio/src/networkmonitor.hg
gio/src/remoteactiongroup.hg
glib/glibmm/dispatcher.cc
glib/glibmm/dispatcher.h
glib/glibmm/init.cc
glib/glibmm/init.h
glib/glibmm/refptr.h
glib/glibmm/ustring.h
glib/glibmm/utility.h
glib/src/balancedtree.hg
glib/src/binding.hg
glib/src/checksum.hg
glib/src/value_basictypes.cc.m4
glib/src/value_basictypes.h.m4
glib/src/variant.ccg
glib/src/variant.hg
glib/src/varianttype.ccg
glib/src/varianttype.hg
tests/giomm_listmodel/main.cc
tests/giomm_stream_vfuncs/main.cc
tests/glibmm_interface_move/main.cc
tests/glibmm_nodetree/main.cc
tests/glibmm_variant/main.cc

index 2848409..f28a0c8 100644 (file)
@@ -11,7 +11,9 @@
 mkdir $(CopyDir)
 mkdir $(CopyDir)\bin
 copy $(BinDir)\glibmm-vc$(VSVer)0-$(ApiMajorVersion)_$(ApiMinorVersion).dll $(CopyDir)\bin
+copy $(BinDir)\glibmm-vc$(VSVer)0-$(ApiMajorVersion)_$(ApiMinorVersion).pdb $(CopyDir)\bin
 copy $(BinDir)\giomm-vc$(VSVer)0-$(ApiMajorVersion)_$(ApiMinorVersion).dll $(CopyDir)\bin
+copy $(BinDir)\giomm-vc$(VSVer)0-$(ApiMajorVersion)_$(ApiMinorVersion).pdb $(CopyDir)\bin
 
 mkdir $(CopyDir)\lib\glibmm-$(ApiMajorVersion).$(ApiMinorVersion)\include
 mkdir $(CopyDir)\lib\giomm-$(ApiMajorVersion).$(ApiMinorVersion)\include
diff --git a/NEWS b/NEWS
index 8a2ead1..568d3c1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,50 @@
-2.51.1.1:
+2.51.1.2 (unstable):
+Distro packagers should probably not package this yet.
+
+Glib:
+* Remove some deprecated API
+  (Kjell Ahlstedt)
+* Variant: Remove the string specializations of cast_dynamic.
+  (Kjell Ahlstedt)
+* Glib::VariantType: Add get_item_types(), removing first() and
+  next().
+  (Kjell Ahlstedt) Bug #775741
+
+
+Gio:
+* init(): Set the global locale.
+  (Kjell Ahlstedt) Bug #661588
+* ActionBase: get_state_hint_variant() now returns VariantContainerBase.
+  (Kjell Ahlstedt)
+* ActionMap: add_action_with_parameter(): Register the parameter type,
+  to make this work.
+  (Daniel Boles) Bug #774444
+* ActionResult: Add is_tagged_vfunc().
+  (Kjell Ahlstedt)
+* Glib::Dispatcher: Implement the pimpl idiom
+  (Kjell Ahlstedt) Bug #651942
+* File, FileInfo, FileIOStream, FileOutputStream: Use Glib::ustring for
+  (UTF-8) file attributes of string type.
+  (Kjell Ahlstedt) Bug #615950
+* NetworkMonitor: Derive from Gio::Initable.
+  (Kjell Ahlstedt)
+* RemoteActionGroup: Rename some vfuncs to add _full().
+  (Murray Cumming)
+
+Documentation:
+* ActionMap:
+  - ActivateSlot: Mention add_action_bool().
+  - ActivateWithParameterSlot: Be more specific.
+  (Daniel Boles) Bug #774444
+
+Build:
+* Update the Visual Studio project files.
+  (Chun-wei Fan)
+* Some minor cppcheck fixes.
+  (Murray Cumming)
+
+
+2.51.1.1 (unstable):
 
 General:
 * Remove no_default_handler in some _WRAP_SIGNAL()s
@@ -67,7 +113,7 @@ Gio::Dbus:
   (Murray Cumming)
 
 
-2.51.1:
+2.51.1 (unstable):
 
 This is the first release of the glibmm-2.52 API/ABI.
 It installs in parallel with the gtkmm-2.4 API/ABI, of which
index 899d3d3..5c7c7cb 100644 (file)
@@ -15,7 +15,7 @@
 ## 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.51.1.1],
+AC_INIT([glibmm], [2.51.1.2],
         [http://bugzilla.gnome.org/enter_bug.cgi?product=glibmm],
         [glibmm], [http://www.gtkmm.org/])
 AC_PREREQ([2.59])
index 7738904..a995f5a 100644 (file)
@@ -25,7 +25,7 @@ using namespace std;
 class ChildWatch : public sigc::trackable
 {
 public:
-  ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}
+  explicit ChildWatch(const Glib::RefPtr<Glib::MainLoop>& mainLoop) : m_mainLoop(mainLoop) {}
 
   void on_child_exited(GPid pid, int status);
   void run(); // fork a child and call signal_child_watch
index c364d9b..dcb8e90 100644 (file)
@@ -128,7 +128,7 @@ cancel_thread(Glib::RefPtr<Gio::Cancellable> cancellable)
 class JoinAndDelete
 {
 public:
-  void operator()(std::thread* thread)
+  void operator()(std::thread* thread) const
   {
     stop_thread = true;
     cond_thread.notify_all();
index fb9d6ea..5f25442 100644 (file)
@@ -134,7 +134,7 @@ cancel_thread(Glib::RefPtr<Gio::Cancellable> cancellable)
 class JoinAndDelete
 {
 public:
-  void operator()(std::thread* thread)
+  void operator()(std::thread* thread) const
   {
     stop_thread = true;
     cond_thread.notify_all();
index ffff582..b9b5993 100644 (file)
@@ -102,10 +102,7 @@ public:
   template <typename T_Value>
   void get_state_hint(T_Value& value) const;
 
-  //TODO: When we can break ABI, Return a Glib::VariantContainerBase,
-  // as we already do for ActionGroup::get_action_state_hint(),
-  // because that is what this returns (to specify a range).
-  _WRAP_METHOD(Glib::VariantBase get_state_hint_variant() const, g_action_get_state_hint)
+  _WRAP_METHOD(Glib::VariantContainerBase get_state_hint_variant() const, g_action_get_state_hint)
 
   _WRAP_METHOD(bool get_enabled() const, g_action_get_enabled)
 
index 5877e20..6d250ba 100644 (file)
@@ -75,9 +75,6 @@ public:
   _WRAP_METHOD(Glib::VariantType get_action_parameter_type(const Glib::ustring& action_name) const, g_action_group_get_action_parameter_type)
   _WRAP_METHOD(Glib::VariantType get_action_state_type(const Glib::ustring& action_name) const, g_action_group_get_action_state_type)
 
-
-  _WRAP_METHOD(Glib::VariantContainerBase get_action_state_hint(const Glib::ustring& action_name) const, g_action_group_get_action_state_hint, deprecated "Use the get_action_state() method that takes an output parameter instead.")
-
   //TODO: How do we check for a nullptr Variant?
   /**
    * Requests a hint about the valid range of values for the state of the
index da803bb..5598642 100644 (file)
@@ -32,19 +32,19 @@ ActionMap::add_action(const Glib::ustring& name)
 }
 
 Glib::RefPtr<SimpleAction>
-ActionMap::add_action_with_parameter(
-  const Glib::ustring& name, const ActivateWithParameterSlot& slot)
+ActionMap::add_action(const Glib::ustring& name, const ActivateSlot& slot)
 {
   auto action = add_action(name);
-  action->signal_activate().connect(slot);
+  action->signal_activate().connect(sigc::hide(slot));
   return action;
 }
 
 Glib::RefPtr<SimpleAction>
-ActionMap::add_action(const Glib::ustring& name, const ActivateSlot& slot)
+ActionMap::add_action_with_parameter(
+  const Glib::ustring& name, const ActivateWithParameterSlot& slot, const Glib::VariantType& parameter_type)
 {
-  auto action = add_action(name);
-  action->signal_activate().connect(sigc::hide(slot));
+  auto action = SimpleAction::create(name, parameter_type);
+  action->signal_activate().connect(slot);
   return action;
 }
 
index b5f885d..1ae1615 100644 (file)
@@ -45,19 +45,17 @@ class ActionMap : public Glib::Interface
 {
   _CLASS_INTERFACE(ActionMap, GActionMap, G_ACTION_MAP, GActionMapInterface)
 
+  // The various add_action...() methods are our equivalent for g_action_map_add_action_entries().
+  _IGNORE(g_action_map_add_action_entries)
+
 public:
+  _WRAP_METHOD(void add_action(const Glib::RefPtr<Action>& action), g_action_map_add_action)
+  _WRAP_METHOD(void remove_action(const Glib::ustring& action_name), g_action_map_remove_action)
+
   _WRAP_METHOD(Glib::RefPtr<Action> lookup_action(const Glib::ustring& action_name), g_action_map_lookup_action, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Action> lookup_action(const Glib::ustring& action_name) const, g_action_map_lookup_action, constversion, refreturn)
 
-  /** A Slot to be called when an action has been activated.
-   * See add_action_with_parameter().
-   *
-   * For instance,
-   * void on_slot_activated(const Glib::VariantBase& parameter);
-   */
-  using ActivateWithParameterSlot = sigc::slot<void(const Glib::VariantBase&)>;
 
-  //This is an equivalent for g_action_map_add_action_entries().
   /** A convenience method for creating a SimpleAction instance
    * and adding it to the ActionMap.
    *
@@ -66,7 +64,15 @@ public:
    */
   Glib::RefPtr<SimpleAction> add_action(const Glib::ustring& name);
 
-  //This is an equivalent for g_action_map_add_action_entries().
+  /** A Slot to be called when an action has been activated,
+   * without passing a parameter to the slot.
+   * See add_action() and add_action_bool().
+   *
+   * For instance,
+   * void on_slot_activated();
+   */
+  using ActivateSlot = sigc::slot<void()>;
+
   /** A convenience method for creating a SimpleAction instance
    * and adding it to the ActionMap.
    *
@@ -74,26 +80,27 @@ public:
    * @param slot The callback method to be called when the action is activated.
    * @return The Action.
    */
-  Glib::RefPtr<SimpleAction> add_action_with_parameter(const Glib::ustring& name, const ActivateWithParameterSlot& slot);
-  _IGNORE(g_action_map_add_action_entries)
+  Glib::RefPtr<SimpleAction> add_action(const Glib::ustring& name, const ActivateSlot& slot);
+
 
   /** A Slot to be called when an action has been activated,
-   * without passing a parameter to the slot.
-   * See add_action().
+   * passing a parameter of a specified type.
+   * See add_action_with_parameter().
    *
    * For instance,
-   * void on_slot_activated();
+   * void on_slot_activated(const Glib::VariantBase& parameter);
    */
-  using ActivateSlot = sigc::slot<void()>;
+  using ActivateWithParameterSlot = sigc::slot<void(const Glib::VariantBase&)>;
 
   /** A convenience method for creating a SimpleAction instance
    * 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.
    * @return The Action.
    */
-  Glib::RefPtr<SimpleAction> add_action(const Glib::ustring& name, const ActivateSlot& slot);
+  Glib::RefPtr<SimpleAction> add_action_with_parameter(const Glib::ustring& name, const ActivateWithParameterSlot& slot, const Glib::VariantType& parameter_type);
 
 
   /** A convenience method for creating a boolean-stateful SimpleAction instance
@@ -130,7 +137,7 @@ public:
    * See add_action_radio_string().
    *
    * For instance,
-   * void on_slot_activated(const Glib::VariantBase& parameter);
+   * void on_slot_activated(const Glib::ustring& parameter);
    */
   using ActivateWithStringParameterSlot = sigc::slot<void(const Glib::ustring&)>;
 
@@ -145,6 +152,7 @@ public:
    */
   Glib::RefPtr<SimpleAction> add_action_radio_string(const Glib::ustring& name, const ActivateWithStringParameterSlot& slot, const Glib::ustring& state);
 
+
 //TODO: Docs: Add hints about how to specify the various possible states in the GtkBuilder XML.
   /** A convenience method for creating an integer-based radio SimpleAction instance
    * and adding it to the ActionMap.
@@ -156,10 +164,10 @@ public:
   Glib::RefPtr<SimpleAction> add_action_radio_integer(const Glib::ustring& name, gint32 state);
 
   /** A Slot to be called when an action has been activated.
-   * See add_action_radio_int().
+   * See add_action_radio_integer().
    *
    * For instance,
-   * void on_slot_activated(const Glib::VariantBase& parameter);
+   * void on_slot_activated(int parameter);
    */
   using ActivateWithIntParameterSlot = sigc::slot<void(int)>;
   
@@ -175,9 +183,6 @@ public:
   Glib::RefPtr<SimpleAction> add_action_radio_integer(const Glib::ustring& name, const ActivateWithIntParameterSlot& slot, gint32 state);
 
 
-  _WRAP_METHOD(void add_action(const Glib::RefPtr<Action>& action), g_action_map_add_action)
-  _WRAP_METHOD(void remove_action(const Glib::ustring& action_name), g_action_map_remove_action)
-
 #m4 _CONVERSION(`Glib::RefPtr<Action>', `GAction*', `Glib::unwrap($3)')
   _WRAP_VFUNC(Glib::RefPtr<Action> lookup_action(const Glib::ustring& name) const, "lookup_action", refreturn)
 
index 31b6a15..f0d2d68 100644 (file)
@@ -117,15 +117,12 @@ public:
 
   _WRAP_METHOD(bool is_tagged(gpointer source_tag) const, g_async_result_is_tagged)
 
-
-  // TODO: For some reason, the compiler cannot find an unwrap() for ObjectBase.
+  // The compiler cannot find an unwrap() for ObjectBase, because
+  // ObjectBase::BaseObjectType is not declared.
   //#m4 _CONVERSION(`Glib::RefPtr<Glib::ObjectBase>',`GObject*',__CONVERT_REFPTR_TO_P)
 #m4 _CONVERSION(`Glib::RefPtr<Glib::ObjectBase>',`GObject*',`unwrap_objectbase_custom($3)')
-  _WRAP_VFUNC(Glib::RefPtr<Glib::ObjectBase> get_source_object(),
-              "get_source_object")
-
-  //TODO: is_tagged() vfunc when we can break ABI.
+  _WRAP_VFUNC(Glib::RefPtr<Glib::ObjectBase> get_source_object(), "get_source_object")
+  _WRAP_VFUNC(bool is_tagged(gpointer source_tag), "is_tagged")
 };
 
 } // namespace Gio
-
index cbe8bac..f2b595a 100644 (file)
@@ -1399,7 +1399,7 @@ public:
 
   bool set_attributes_finish(const Glib::RefPtr<AsyncResult>& result, const Glib::RefPtr<FileInfo>& info);
 
-  _WRAP_METHOD(bool set_attribute_string(const std::string& attribute, const std::string& value, FileQueryInfoFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}),
+  _WRAP_METHOD(bool set_attribute_string(const std::string& attribute, const Glib::ustring& value, FileQueryInfoFlags flags, const Glib::RefPtr<Cancellable>& cancellable{?}),
                g_file_set_attribute_string,
                errthrow)
 
index 54841f9..6596e47 100644 (file)
@@ -1,5 +1,3 @@
-// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -109,8 +107,7 @@ public:
 
   _WRAP_METHOD(FileAttributeStatus get_attribute_status(const std::string& attribute) const, g_file_info_get_attribute_status)
 
-  //TODO: This should return a ustring instead: https://bugzilla.gnome.org/show_bug.cgi?id=615950#c7
-  _WRAP_METHOD(std::string get_attribute_string(const std::string& attribute) const,
+  _WRAP_METHOD(Glib::ustring get_attribute_string(const std::string& attribute) const,
                g_file_info_get_attribute_string)
 
 #m4 _CONVERSION(`char**',`std::vector<Glib::ustring>',`Glib::ArrayHandler<Glib::ustring>::array_to_vector($3, Glib::OWNERSHIP_NONE)')
@@ -135,8 +132,7 @@ public:
 
   _WRAP_METHOD(bool set_attribute_status(const std::string& attribute, FileAttributeStatus status), g_file_info_set_attribute_status)
 
-  //TODO: This should take a ustring value instead: https://bugzilla.gnome.org/show_bug.cgi?id=615950#c7
-  _WRAP_METHOD(void set_attribute_string(const std::string& attribute, const std::string& attr_value),
+  _WRAP_METHOD(void set_attribute_string(const std::string& attribute, const Glib::ustring& attr_value),
                g_file_info_set_attribute_string)
 
 #m4 _CONVERSION(`const std::vector<Glib::ustring>&',`char**',`const_cast<char**>(Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data())')
@@ -167,11 +163,9 @@ public:
   _WRAP_METHOD(bool is_symlink() const, g_file_info_get_is_symlink)
   _WRAP_METHOD(std::string get_name() const, g_file_info_get_name)
 
-  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(std::string get_display_name() const, g_file_info_get_display_name)
+  _WRAP_METHOD(Glib::ustring get_display_name() const, g_file_info_get_display_name)
 
-  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(std::string get_edit_name() const, g_file_info_get_edit_name)
+  _WRAP_METHOD(Glib::ustring get_edit_name() const, g_file_info_get_edit_name)
 
   _WRAP_METHOD(Glib::RefPtr<Icon> get_icon(), g_file_info_get_icon, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_icon() const, g_file_info_get_icon, refreturn, constversion)
@@ -179,8 +173,7 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Icon> get_symbolic_icon(), g_file_info_get_symbolic_icon, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Icon> get_symbolic_icon() const, g_file_info_get_symbolic_icon, refreturn, constversion)
 
-  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(std::string get_content_type() const, g_file_info_get_content_type)
+  _WRAP_METHOD(Glib::ustring get_content_type() const, g_file_info_get_content_type)
 
   _WRAP_METHOD(goffset get_size() const, g_file_info_get_size)
 
@@ -189,8 +182,7 @@ public:
 
   _WRAP_METHOD(std::string get_symlink_target() const, g_file_info_get_symlink_target)
 
-  //TODO: This should return a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(std::string get_etag() const, g_file_info_get_etag)
+  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_info_get_etag)
 
   _WRAP_METHOD(gint32 get_sort_order() const, g_file_info_get_sort_order)
   _WRAP_METHOD(void set_attribute_mask(const Glib::RefPtr<FileAttributeMatcher>& mask),
@@ -204,17 +196,14 @@ public:
   _WRAP_METHOD(void set_is_symlink(bool symlink = true), g_file_info_set_is_symlink)
   _WRAP_METHOD(void set_name(const std::string& name), g_file_info_set_name)
 
-  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(void set_display_name(const std::string& display_name), g_file_info_set_display_name)
+  _WRAP_METHOD(void set_display_name(const Glib::ustring& display_name), g_file_info_set_display_name)
 
-  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(void set_edit_name(const std::string& edit_name), g_file_info_set_edit_name)
+  _WRAP_METHOD(void set_edit_name(const Glib::ustring& edit_name), g_file_info_set_edit_name)
 
   _WRAP_METHOD(void set_icon(const Glib::RefPtr<Icon>& icon), g_file_info_set_icon)
   _WRAP_METHOD(void set_symbolic_icon(const Glib::RefPtr<Icon>& icon), g_file_info_set_symbolic_icon)
 
-  //TODO: This should take a ustring instead. See https://bugzilla.gnome.org/show_bug.cgi?id=615950#c4
-  _WRAP_METHOD(void set_content_type(const std::string& content_type), g_file_info_set_content_type)
+  _WRAP_METHOD(void set_content_type(const Glib::ustring& content_type), g_file_info_set_content_type)
 
   _WRAP_METHOD(void set_size(goffset size), g_file_info_set_size)
 
index b015268..3f2ca9c 100644 (file)
@@ -1,5 +1,3 @@
-// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-
 /* Copyright (C) 2007 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -100,7 +98,7 @@ public:
   _WRAP_METHOD(Glib::RefPtr<FileInfo> query_info_finish(const Glib::RefPtr<AsyncResult>& result),
                g_file_io_stream_query_info_finish,
                errthrow)
-  _WRAP_METHOD(std::string get_etag() const, g_file_io_stream_get_etag)
+  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_io_stream_get_etag)
 
 };
 
index a31567b..3539c4c 100644 (file)
@@ -135,7 +135,7 @@ public:
                g_file_output_stream_query_info_finish,
                refreturn, errthrow)
 
-  _WRAP_METHOD(std::string get_etag() const, g_file_output_stream_get_etag)
+  _WRAP_METHOD(Glib::ustring get_etag() const, g_file_output_stream_get_etag)
 };
 
 } // namespace Gio
index 116b003..f8c94da 100644 (file)
   (return-type "GObject*")
 )
 
+(define-vfunc is_tagged
+  (of-object "GAsyncResult")
+  (return-type "gboolean")
+ (parameters
+  '("gpointer" "source_tag")
+ )
+)
+
 ; GBufferedInputStream
 
 (define-vfunc fill
index 9c5068c..38126a4 100644 (file)
@@ -30,6 +30,9 @@ public:
   {
   }
 
+  SlotWithData(const SlotWithData& src) = delete;
+  SlotWithData& operator=(const SlotWithData& src) = delete;
+
   ~SlotWithData() { delete m_slot; }
 
   void operator()() { (*m_slot)(m_data); }
index df55fda..ca84559 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <glibmm/interface.h>
+#include <giomm/initable.h>
 #include <giomm/asyncresult.h>
 #include <giomm/cancellable.h>
 #include <giomm/socketconnectable.h>
 #include <gio/gio.h>
 
 _DEFS(giomm,gio)
-_PINCLUDE(glibmm/private/interface_p.h)
+_PINCLUDE(giomm/private/initable_p.h)
 _PINCLUDE(gio/gio.h)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -39,9 +39,9 @@ _WRAP_ENUM(NetworkConnectivity, GNetworkConnectivity, NO_GTYPE)
  *
  * @newin{2,44}
  */
-class NetworkMonitor : public Glib::Interface
+class NetworkMonitor : public Initable
 {
-  _CLASS_INTERFACE(NetworkMonitor, GNetworkMonitor, G_NETWORK_MONITOR, GNetworkMonitorInterface)
+  _CLASS_INTERFACE(NetworkMonitor, GNetworkMonitor, G_NETWORK_MONITOR, GNetworkMonitorInterface, Initable, GInitable)
 
 public:
   _WRAP_METHOD(static Glib::RefPtr<NetworkMonitor> get_default(), g_network_monitor_get_default, newin "2,44")
index 5a70ac6..57ec71d 100644 (file)
@@ -61,8 +61,8 @@ public:
 
 #m4 _CONVERSION(`GVariant*',`const Glib::VariantBase&',`Glib::wrap($3, true)')
 
-  _WRAP_VFUNC(void activate_action(const Glib::ustring& action_name, const Glib::VariantBase& parameter, const Glib::VariantBase& platform_data), "activate_action_full")
-  _WRAP_VFUNC(void change_action_state(const Glib::ustring& action_name, const Glib::VariantBase& value, const Glib::VariantBase& platform_data), "change_action_state_full")
+  _WRAP_VFUNC(void activate_action_full(const Glib::ustring& action_name, const Glib::VariantBase& parameter, const Glib::VariantBase& platform_data), "activate_action_full")
+  _WRAP_VFUNC(void change_action_state_full(const Glib::ustring& action_name, const Glib::VariantBase& value, const Glib::VariantBase& platform_data), "change_action_state_full")
 };
 
 } // namespace Gio
index 73b69be..2e23526 100644 (file)
@@ -23,7 +23,8 @@
 #include <cerrno>
 #include <fcntl.h>
 #include <glib.h>
-#include <set>
+#include <forward_list>
+#include <memory>
 #include <utility> // For std::move()
 
 #ifdef G_OS_WIN32
 #define EINTR 0 /* TODO: should use the real define */
 #endif
 
+namespace Glib
+{
+class DispatchNotifier;
+}
+
 namespace
 {
 
 struct DispatchNotifyData
 {
-  Glib::Dispatcher* dispatcher;
+  Glib::Dispatcher::Impl* dispatcher_impl;
   Glib::DispatchNotifier* notifier;
 
-  DispatchNotifyData() : dispatcher(nullptr), notifier(nullptr) {}
+  DispatchNotifyData()
+  : dispatcher_impl(nullptr), notifier(nullptr)
+  {}
 
-  DispatchNotifyData(Glib::Dispatcher* d, Glib::DispatchNotifier* n) : dispatcher(d), notifier(n) {}
+  DispatchNotifyData(Glib::Dispatcher::Impl* d, Glib::DispatchNotifier* n)
+  : dispatcher_impl(d), notifier(n)
+  {}
 };
 
 static void
@@ -117,11 +127,33 @@ fd_close_and_invalidate(int& fd)
 }
 #endif /* !G_OS_WIN32 */
 
+void warn_dropped_dispatcher_message()
+{
+  g_warning("Dropped dispatcher message as the dispatcher no longer exists.");
+}
+
 } // anonymous namespace
 
 namespace Glib
 {
 
+// The most important reason for having the dispatcher implementation in a separate
+// class is that its deletion can be delayed until it's safe to delete it.
+// Deletion is safe when the pipe does not contain any message to the dispatcher
+// to delete. When the pipe is empty, it's surely safe.
+struct Dispatcher::Impl
+{
+public:
+  sigc::signal<void()> signal_;
+  DispatchNotifier*  notifier_;
+
+  explicit Impl(const Glib::RefPtr<MainContext>& context);
+
+  // noncopyable
+  Impl(const Impl&) = delete;
+  Impl& operator=(const Impl&) = delete;
+};
+
 class DispatchNotifier : public sigc::trackable
 {
 public:
@@ -131,11 +163,10 @@ public:
   DispatchNotifier(const DispatchNotifier&) = delete;
   DispatchNotifier& operator=(const DispatchNotifier&) = delete;
 
-  static DispatchNotifier* reference_instance(
-    const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher);
-  static void unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher);
+  static DispatchNotifier* reference_instance(const Glib::RefPtr<MainContext>& context);
+  static void unreference_instance(DispatchNotifier* notifier, Dispatcher::Impl* dispatcher_impl);
 
-  void send_notification(Dispatcher* dispatcher);
+  void send_notification(Dispatcher::Impl* dispatcher_impl);
 
 protected:
   // Only used by reference_instance().  Should be private, but that triggers
@@ -145,8 +176,8 @@ protected:
 private:
   static thread_local DispatchNotifier* thread_specific_instance_;
 
-  std::set<const Dispatcher*> deleted_dispatchers_;
-
+  using UniqueImplPtr = std::unique_ptr<Dispatcher::Impl>;
+  std::forward_list<UniqueImplPtr> orphaned_dispatcher_impl_;
   long ref_count_;
   Glib::RefPtr<MainContext> context_;
 #ifdef G_OS_WIN32
@@ -168,7 +199,7 @@ private:
 thread_local DispatchNotifier* DispatchNotifier::thread_specific_instance_ = nullptr;
 
 DispatchNotifier::DispatchNotifier(const Glib::RefPtr<MainContext>& context)
-: deleted_dispatchers_(),
+: orphaned_dispatcher_impl_(),
   ref_count_(0),
   context_(context),
 #ifdef G_OS_WIN32
@@ -264,9 +295,8 @@ DispatchNotifier::create_pipe()
 }
 
 // static
-DispatchNotifier*
-DispatchNotifier::reference_instance(
-  const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher)
+DispatchNotifier* DispatchNotifier::reference_instance(
+  const Glib::RefPtr<MainContext>& context)
 {
   DispatchNotifier* instance = thread_specific_instance_;
 
@@ -279,17 +309,6 @@ DispatchNotifier::reference_instance(
   {
     // Prevent massive mess-up.
     g_return_val_if_fail(instance->context_ == context, nullptr);
-
-    // In the possible but unlikely case that a new dispatcher gets the same
-    // address as a newly deleted one, if the pipe still contains messages to
-    // the deleted dispatcher, those messages will be delivered to the new one.
-    // Not ideal, but perhaps the best that can be done without breaking ABI.
-    // The alternative would be to remove the following erase(), and risk not
-    // delivering messages sent to the new dispatcher.
-    // TODO: When we can break ABI, a better solution without this drawback can
-    // be implemented. See https://bugzilla.gnome.org/show_bug.cgi?id=651942
-    // especially comment 16.
-    instance->deleted_dispatchers_.erase(dispatcher);
   }
 
   ++instance->ref_count_; // initially 0
@@ -298,8 +317,8 @@ DispatchNotifier::reference_instance(
 }
 
 // static
-void
-DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher)
+void DispatchNotifier::unreference_instance(
+  DispatchNotifier* notifier, Dispatcher::Impl* dispatcher_impl)
 {
   DispatchNotifier* const instance = thread_specific_instance_;
 
@@ -307,12 +326,22 @@ DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatc
   g_return_if_fail(instance == notifier);
 
   if (instance->pipe_is_empty())
-    // No messages in the pipe. No need to keep track of deleted dispatchers.
-    instance->deleted_dispatchers_.clear();
+  {
+    // No messages in the pipe. Delete the Dispatcher::Impl immediately.
+    delete dispatcher_impl;
+    instance->orphaned_dispatcher_impl_.clear();
+  }
   else
-    // There are messages in the pipe, possibly to the deleted dispatcher.
-    // Keep its address, so pipe_io_handler() can avoid delivering messages to it.
-    instance->deleted_dispatchers_.insert(dispatcher);
+  {
+    // There are messages in the pipe, possibly to the orphaned Dispatcher::Impl.
+    // Keep it around until it can safely be deleted.
+    // Delete all slots connected to the Dispatcher. Then the signal emission
+    // in pipe_io_handler() will do nothing.
+    dispatcher_impl->signal_.clear();
+    // Add a slot that will warn that a message has been dropped.
+    dispatcher_impl->signal_.connect(sigc::ptr_fun(warn_dropped_dispatcher_message));
+    instance->orphaned_dispatcher_impl_.push_front(UniqueImplPtr(dispatcher_impl));
+  }
 
   if (--instance->ref_count_ <= 0)
   {
@@ -323,15 +352,14 @@ DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatc
   }
 }
 
-void
-DispatchNotifier::send_notification(Dispatcher* dispatcher)
+void DispatchNotifier::send_notification(Dispatcher::Impl* dispatcher_impl)
 {
 #ifdef G_OS_WIN32
   {
     const std::lock_guard<std::mutex> lock(mutex_);
 
     const bool was_empty = notify_queue_.empty();
-    notify_queue_.emplace_back(DispatchNotifyData(dispatcher, this));
+    notify_queue_.emplace_back(DispatchNotifyData(dispatcher_impl, this));
 
     if (was_empty)
     {
@@ -343,7 +371,7 @@ DispatchNotifier::send_notification(Dispatcher* dispatcher)
   }
 #else /* !G_OS_WIN32 */
 
-  DispatchNotifyData data(dispatcher, this);
+  DispatchNotifyData data(dispatcher_impl, this);
   gssize n_written;
 
   do
@@ -437,75 +465,69 @@ bool DispatchNotifier::pipe_io_handler(Glib::IOCondition)
 
   g_return_val_if_fail(data.notifier == this, true);
 
-  // Drop the received message, if it is addressed to a deleted dispatcher.
-  const bool drop_message =
-    (deleted_dispatchers_.find(data.dispatcher) != deleted_dispatchers_.end());
-
-  // If the pipe is empty, there can be no messages to deleted dispatchers.
-  // No reason to keep track of them any more.
-  if (!deleted_dispatchers_.empty() && pipe_is_empty())
-    deleted_dispatchers_.clear();
-
-  if (drop_message)
-  {
-    g_warning("Dropped dispatcher message as the dispatcher no longer exists");
-    return true;
-  }
-
   // Actually, we wouldn't need the try/catch block because the Glib::Source
   // C callback already does it for us.  However, we do it anyway because the
   // default return value is 'false', which is not what we want.
   try
   {
-    data.dispatcher->signal_(); // emit
+    data.dispatcher_impl->signal_(); // emit
   }
   catch (...)
   {
     Glib::exception_handlers_invoke();
   }
 
+  if (!orphaned_dispatcher_impl_.empty() && pipe_is_empty())
+    orphaned_dispatcher_impl_.clear();
+
   return true;
 }
 
-/**** Glib::Dispatcher *****************************************************/
+/**** Glib::Dispatcher and Glib::Dispatcher::Impl **************************/
 
-Dispatcher::Dispatcher()
-: signal_(), notifier_(DispatchNotifier::reference_instance(MainContext::get_default(), this))
+Dispatcher::Impl::Impl(const Glib::RefPtr<MainContext>& context)
+: signal_(),
+  notifier_(DispatchNotifier::reference_instance(context))
 {
 }
 
+Dispatcher::Dispatcher()
+: impl_(new Dispatcher::Impl(MainContext::get_default()))
+{}
+
+
 Dispatcher::Dispatcher(const Glib::RefPtr<MainContext>& context)
-: signal_(), notifier_(DispatchNotifier::reference_instance(context, this))
+: impl_(new Dispatcher::Impl(context))
 {
 }
 
 Dispatcher::~Dispatcher() noexcept
 {
-  DispatchNotifier::unreference_instance(notifier_, this);
+  DispatchNotifier::unreference_instance(impl_->notifier_, impl_);
 }
 
 void
 Dispatcher::emit()
 {
-  notifier_->send_notification(this);
+  impl_->notifier_->send_notification(impl_);
 }
 
 void
 Dispatcher::operator()()
 {
-  notifier_->send_notification(this);
+  impl_->notifier_->send_notification(impl_);
 }
 
 sigc::connection
 Dispatcher::connect(const sigc::slot<void()>& slot)
 {
-  return signal_.connect(slot);
+  return impl_->signal_.connect(slot);
 }
 
 sigc::connection
 Dispatcher::connect(sigc::slot<void()>&& slot)
 {
-  return signal_.connect(std::move(slot));
+  return impl_->signal_.connect(std::move(slot));
 }
 
 } // namespace Glib
index 2109560..f66a523 100644 (file)
 namespace Glib
 {
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-class DispatchNotifier;
-#endif
-
 /** Signal class for inter-thread communication.
  * @ingroup Threads
  * Glib::Dispatcher works similar to sigc::signal<void()>.  But unlike normal
@@ -93,13 +89,12 @@ public:
    */
   sigc::connection connect(sigc::slot<void()>&& slot);
 
-private:
-  sigc::signal<void()> signal_;
-  DispatchNotifier* notifier_;
+  #ifndef DOXYGEN_SHOULD_SKIP_THIS
+  struct Impl;
+  #endif
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-  friend class Glib::DispatchNotifier;
-#endif
+private:
+  Impl* impl_; // hidden implementation
 };
 
 /*! A Glib::Dispatcher example.
index cc3b84c..f42cdf5 100644 (file)
 
 #include <glibmm/init.h>
 #include <glibmm/error.h>
+#include <locale>
+#include <clocale>
+#include <stdexcept>
+
+namespace
+{
+  bool init_to_users_preferred_locale = true;
+
+} // anonymous namespace
 
 namespace Glib
 {
+void set_init_to_users_preferred_locale(bool state)
+{
+  init_to_users_preferred_locale = state;
+}
+
+bool get_init_to_users_preferred_locale()
+{
+  return init_to_users_preferred_locale;
+}
 
-void
-init()
+void init()
 {
+  static bool is_initialized = false;
+
+  if (is_initialized)
+    return;
+
+  if (init_to_users_preferred_locale)
+  {
+    try
+    {
+      // Set the global locale for C++ functions and the locale for C functions
+      // to the user-preferred locale.
+      std::locale::global(std::locale(""));
+    }
+    catch (const std::runtime_error& ex)
+    {
+      g_warning("Can't set the global locale to the user's preferred locale.\n"
+        "   %s\n   The environment variable LANG may be wrong.\n", ex.what());
+    }
+  }
+  else
+  {
+    try
+    {
+      // Make the C++ locale equal to the C locale.
+      std::locale::global(std::locale(std::setlocale(LC_ALL, nullptr)));
+    }
+    catch (const std::runtime_error& ex)
+    {
+      g_warning("Can't make the global C++ locale equal to the C locale.\n"
+        "   %s\n   C locale = %s\n", ex.what(), std::setlocale(LC_ALL, nullptr));
+    }
+  }
+
   // Also calls Glib::wrap_register_init() and Glib::wrap_init().
   Glib::Error::register_init();
+
+  is_initialized = true;
 }
 
 } // namespace Glib
index 844945a..a736093 100644 (file)
@@ -1,9 +1,6 @@
-// -*- c++ -*-
 #ifndef _GLIBMM_INIT_H
 #define _GLIBMM_INIT_H
 
-/* $Id$ */
-
 /* Copyright (C) 2002 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -25,12 +22,50 @@ namespace Glib
 {
 
 /** Initialize glibmm.
- * You may call this more than once.
- * You do not need to call this if you are using Glib::MainLoop or Gtk::Main,
- * because they call it for you.
+ *
+ * You may call this more than once. Calls after the first one have no effect.
+ * Sets the global locale as specified by set_init_to_users_preferred_locale().
+ * You do not need to call %Glib::init() if you are using Gtk::Application,
+ * because it calls %Glib::init() for you.
+ *
+ * @see set_init_to_users_preferred_locale()
  */
 void init();
 
+/** Instruct Glib::init() which global locale to set.
+ *
+ * To have the intended effect, this function must be called before init() is called.
+ * Not calling it has the same effect as calling it with @a state = <tt>true</tt>.
+ *
+ * Note the confusing difference between C locale and "C" locale.
+ * The C locale is the locale used by C code, set by std::setlocale(LC_ALL,&nbsp;locale_name).
+ * The "C" locale is the classic locale, set by std::setlocale(LC_ALL,&nbsp;"C")
+ * or std::locale::global(std::locale::classic()). It's the default global locale
+ * in a C or C++ program.
+ *
+ * In a mixed C and C++ program, like a program using glibmm, having the C global
+ * locale differ from std::locale::global() is error prone. Glib::init() tries
+ * to avoid that.
+ *
+ * @param state If <tt>true</tt>, init() will set the C and C++ global locale
+ *              to the user's preferred locale (std::locale::global(std::locale(""))).
+ *              The user's preferred locale is set in the program's environment,
+ *              usually with the LANG environment variable.<br>
+ *              If <tt>false</tt>, init() will set the C++ global locale to the C global locale
+ *              (std::locale::global(std::locale(std::setlocale(LC_ALL,&nbsp;nullptr)))).
+ *
+ * @newin{2,52}
+ */
+void set_init_to_users_preferred_locale(bool state = true);
+
+/** Get the state, set with set_init_to_users_preferred_locale().
+ * @returns The state, set with set_init_to_users_preferred_locale(); <tt>true</tt>
+ *          if set_init_to_users_preferred_locale() has not been called.
+ *
+ * @newin{2,52}
+ */
+bool get_init_to_users_preferred_locale();
+
 } // namespace Glib
 
 #endif /* _GLIBMM_INIT_H */
index 892b6a6..ed3df91 100644 (file)
@@ -167,12 +167,6 @@ public:
    */
   inline explicit operator bool() const noexcept;
 
-#ifndef GLIBMM_DISABLE_DEPRECATED
-  /// @deprecated Use reset() instead because this leads to confusion with clear() methods on the
-  /// underlying class. For instance, people use .clear() when they mean ->clear().
-  inline void clear() noexcept;
-#endif // GLIBMM_DISABLE_DEPRECATED
-
   /** Set underlying instance to nullptr, decrementing reference count of existing instance
    * appropriately.
    * @newin{2,16}
@@ -402,15 +396,6 @@ inline RefPtr<T_CppObject>::operator bool() const noexcept
   return (pCppObject_ != nullptr);
 }
 
-#ifndef GLIBMM_DISABLE_DEPRECATED
-template <class T_CppObject>
-inline void
-RefPtr<T_CppObject>::clear() noexcept
-{
-  reset();
-}
-#endif // GLIBMM_DISABLE_DEPRECATED
-
 template <class T_CppObject>
 inline void
 RefPtr<T_CppObject>::reset() noexcept
index fe45c1a..ba6289d 100644 (file)
@@ -184,7 +184,9 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
  * If you're using std::ostringstream to build strings for display in the
  * user interface, you must convert the result back to UTF-8 as shown below:
  * @code
- * std::locale::global(std::locale("")); // set the global locale to the user's preferred locale
+ * std::locale::global(std::locale("")); // Set the global locale to the user's preferred locale.
+ *                                       // Usually unnecessary here, because Glib::init()
+ *                                       // does it for you.
  * std::ostringstream output;
  * output << percentage << " % done";
  * label->set_text(Glib::locale_to_utf8(output.str()));
index 096b9fe..3cbca14 100644 (file)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-#ifndef GLIBMM_DISABLE_DEPRECATED
-/* Occasionally, a struct variable has to be initialized after its definition,
- * i.e. when using structs as class member data.  For convenience, the macro
- * GLIBMM_INITIALIZE_STRUCT(Var, Type) is provided.  It even avoids creating
- * a temporary if the compiler is GCC.
- *
- * @deprecated Use e.g. std::memset() instead.
- * It's not used any more in the code generated by _CLASS_BOXEDTYPE_STATIC.
- * It generates compiler warnings if __STRICT_ANSI__ is defined.
- */
-#if ((__GNUC__ >= 3) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) && !defined(__STRICT_ANSI__)
-
-#define GLIBMM_INITIALIZE_STRUCT(Var, Type) __builtin_memset(&(Var), 0, sizeof(Type))
-
-#else
-
-// TODO: This causes warnings like this:
-//"missing initializer for member"
-#define GLIBMM_INITIALIZE_STRUCT(Var, Type) \
-  G_STMT_START                              \
-  {                                         \
-    Type const temp_initializer__ = {       \
-      0,                                    \
-    };                                      \
-    (Var) = temp_initializer__;             \
-  }                                         \
-  G_STMT_END
-
-#endif
-#endif // GLIBMM_DISABLE_DEPRECATED
-
 namespace Glib
 {
 
 // These are used by gmmproc-generated type conversions:
 
-#ifndef GLIBMM_DISABLE_DEPRECATED
-/** Helper to deal with memory allocated
- * by GLib functions in an exception-safe manner.
- *
- * @deprecated Use make_unique_ptr_gfree() instead.
- */
-template <typename T>
-class ScopedPtr
-{
-private:
-  T* ptr_;
-  ScopedPtr(const ScopedPtr<T>&);
-  ScopedPtr<T>& operator=(const ScopedPtr<T>&);
-
-public:
-  ScopedPtr() : ptr_(nullptr) {}
-  explicit ScopedPtr(T* ptr) : ptr_(ptr) {}
-  ~ScopedPtr() noexcept { g_free(ptr_); }
-  T* get() const { return ptr_; }
-  T** addr() { return &ptr_; }
-};
-#endif // GLIBMM_DISABLE_DEPRECATED
-
 /** Helper to deal with memory allocated
  * by GLib functions in an exception-safe manner.
  *
index 5444046..a7628fc 100644 (file)
@@ -67,7 +67,7 @@ protected:
     gobject_ = g_tree_new_full(on_compare_tree, &key_compare_slot, on_destroy_key, on_destroy_value);
   }
 
-  BalancedTree(const CompareFunc &key_compare_slot_) :
+  explicit BalancedTree(const CompareFunc &key_compare_slot_) :
     key_compare_slot(key_compare_slot_)
   {
     gobject_ = g_tree_new_full(on_compare_tree, &key_compare_slot, on_destroy_key, on_destroy_value);
index 730baad..db2baa1 100644 (file)
@@ -396,7 +396,7 @@ private:
   public:
     using SlotTypedTransform = sigc::slot<bool(const T_from&, T_to&)>;
 
-    TransformProp(const SlotTypedTransform& slot) : typed_transform(slot) {}
+    explicit TransformProp(const SlotTypedTransform& slot) : typed_transform(slot) {}
 
     bool operator()(const GValue* from_value, GValue* to_value)
     {
index 26770dd..b3a5555 100644 (file)
@@ -61,9 +61,7 @@ public:
 
   _WRAP_METHOD(void reset(), g_checksum_reset)
 
-  //TODO: length should really be gssize, not gsize, when we can break ABI:
-#m4 _CONVERSION(`gsize',`gssize',`(gssize)($3)')
-  _WRAP_METHOD(void update(const guchar* data, gsize length), g_checksum_update)
+  _WRAP_METHOD(void update(const guchar* data, gssize length), g_checksum_update)
 
   /** Feeds data into an existing Checksum.
    * The checksum must still be open, that is get_string() or get_digest() must not have been called on the checksum.
@@ -99,4 +97,3 @@ public:
 };
 
 } //namespace Glib
-
index ec37c61..f2448dc 100644 (file)
@@ -78,9 +78,6 @@ G_GNUC_EXTENSION typedef long long long_long;
 G_GNUC_EXTENSION typedef unsigned long long unsigned_long_long;
 
 GLIB_VALUE_BASIC(bool, boolean)
-#ifndef GLIBMM_DISABLE_DEPRECATED
-GLIB_VALUE_BASIC(char, char, -128, 127)
-#endif // GLIBMM_DISABLE_DEPRECATED
 GLIB_VALUE_BASIC(signed char, schar, -128, 127)
 GLIB_VALUE_BASIC(unsigned char, uchar, 0, 255)
 GLIB_VALUE_BASIC(int, int, G_MININT, G_MAXINT)
index 91a3a4b..e4b5885 100644 (file)
@@ -67,10 +67,6 @@ divert[]dnl
 namespace Glib
 {
 GLIB_VALUE_BASIC(bool, boolean)
-#ifndef GLIBMM_DISABLE_DEPRECATED
-/// @deprecated Use Value<signed char> instead.
-GLIB_VALUE_BASIC(char, char)
-#endif // GLIBMM_DISABLE_DEPRECATED
 /// @newin{2,44}
 GLIB_VALUE_BASIC(signed char, int8)
 GLIB_VALUE_BASIC(unsigned char, uchar)
index 37576c0..89e557d 100644 (file)
@@ -328,30 +328,6 @@ Variant<Glib::ustring>::get() const
   return convert_const_gchar_ptr_to_ustring(g_variant_get_string(gobject_, nullptr));
 }
 
-// Variant<Glib::ustring> makes sense for multiple types.
-// See http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
-template <>
-Variant<Glib::ustring>
-VariantBase::cast_dynamic<Variant<Glib::ustring>>(const VariantBase& v) throw(std::bad_cast)
-{
-  if (!v.gobj())
-  {
-    return Variant<Glib::ustring>();
-  }
-
-  const VariantType vtype = v.get_type();
-  if (vtype.equal(VARIANT_TYPE_STRING) || vtype.equal(VARIANT_TYPE_OBJECT_PATH) ||
-      vtype.equal(VARIANT_TYPE_SIGNATURE))
-  {
-    return Variant<Glib::ustring>(const_cast<GVariant*>(v.gobj()), true);
-  }
-  else
-  {
-    // std::cerr << "vtype=" << v.get_type_string() << std::endl;
-    throw std::bad_cast();
-  }
-}
-
 /*--------------------Variant<std::string>---------------------*/
 
 Variant<std::string>::Variant() : VariantStringBase()
@@ -377,30 +353,6 @@ Variant<std::string>::create(const std::string& data)
   return result;
 }
 
-// Variant<std::string> makes sense for multiple types.
-// See http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
-template <>
-Variant<std::string>
-VariantBase::cast_dynamic<Variant<std::string>>(const VariantBase& v) throw(std::bad_cast)
-{
-  if (!v.gobj())
-  {
-    return Variant<std::string>();
-  }
-
-  const VariantType vtype = v.get_type();
-  if (vtype.equal(VARIANT_TYPE_STRING) || vtype.equal(VARIANT_TYPE_BYTESTRING) ||
-      vtype.equal(VARIANT_TYPE_OBJECT_PATH) || vtype.equal(VARIANT_TYPE_SIGNATURE))
-  {
-    return Variant<std::string>(const_cast<GVariant*>(v.gobj()), true);
-  }
-  else
-  {
-    // std::cerr << "vtype=" << v.get_type_string() << std::endl;
-    throw std::bad_cast();
-  }
-}
-
 std::string
 Variant<std::string>::get() const
 {
index 7749a34..6900dbe 100644 (file)
@@ -563,11 +563,6 @@ public:
   _IGNORE(g_variant_get_string, g_variant_dup_string)
 };
 
-//TODO: When we can break ABI, remove this template specialization.
-template<>
-Variant<Glib::ustring> VariantBase::cast_dynamic< Variant<Glib::ustring> >(const VariantBase& v)
-throw(std::bad_cast);
-
 /** Specialization of Variant containing a std::string, for variants of type
  * bytestring, string, object path, or signature.
  * See also Variant<Glib::ustring> for UTF-8 strings.
@@ -612,11 +607,6 @@ public:
   _IGNORE(g_variant_get_bytestring, g_variant_dup_bytestring)
 };
 
-//TODO: When we can break ABI, remove this template specialization.
-template<>
-Variant<std::string> VariantBase::cast_dynamic< Variant<std::string> >(const VariantBase& v)
-throw(std::bad_cast);
-
 /** Specialization of Variant containing a dictionary entry.  See also
  * Variant< std::map<K, V> >.
  * @newin{2,28}
index 8274c93..d4032c1 100644 (file)
@@ -122,4 +122,17 @@ VariantType::get_string() const
 {
   return std::string(g_variant_type_peek_string(gobj()), g_variant_type_get_string_length(gobj()));
 }
+
+std::vector<VariantType> VariantType::get_item_types() const
+{
+  std::vector<VariantType> result;
+  auto next_item_type = g_variant_type_first(gobj());
+  while (next_item_type)
+  {
+    result.emplace_back(const_cast<GVariantType*>(next_item_type), true);
+    next_item_type = g_variant_type_next(next_item_type);
+  }
+  return result;
 }
+
+} // namespace GLib
index 19327ab..509eaa6 100644 (file)
@@ -162,15 +162,31 @@ public:
   _WRAP_METHOD(bool is_subtype_of(const VariantType& supertype) const, g_variant_type_is_subtype_of)
 
 // It's necessary to take an extra reference of the 'const GVariantType*'
-// returned by g_variant_type_element() because it doesn't do that already.
+// returned by g_variant_type_element(), g_variant_type_key() and
+// g_variant_type_value() because they don't do that already.
 #m4 _CONVERSION(`const GVariantType*',`VariantType',`Glib::wrap(const_cast<GVariantType*>($3), true)')
   _WRAP_METHOD(VariantType element() const, g_variant_type_element)
-  _WRAP_METHOD(VariantType first() const, g_variant_type_first)
-  _WRAP_METHOD(VariantType next () const, g_variant_type_next)
   _WRAP_METHOD(gsize n_items() const, g_variant_type_n_items)
   _WRAP_METHOD(VariantType key() const, g_variant_type_key)
   _WRAP_METHOD(VariantType value() const, g_variant_type_value)
 
+  /** Determines the item types of a tuple or dictionary entry type.
+   *
+   * This function may only be used with tuple or dictionary entry types,
+   * but must not be used with the generic tuple type VARIANT_TYPE_TUPLE.
+   *
+   * In the case of a dictionary entry type, returns a vector with
+   * 2 elements, the type of the key followed by the value type.
+   *
+   * An empty vector is returned in case of this %VariantType being VARIANT_TYPE_UNIT.
+   *
+   * @newin{2,52}
+   *
+   * @return The item types of this %VariantType, or an empty vector.
+   */
+  std::vector<VariantType> get_item_types() const;
+  _IGNORE(g_variant_type_first, g_variant_type_next)
+
   // This function is part of unexposed API in gvarianttypeinfo.{h,c} for an
   // also unexposed GVariantTypeInfo structure of glib.
   _IGNORE(g_variant_type_info_get)
index f40a943..1016b58 100644 (file)
@@ -255,7 +255,7 @@ void test_store_sorted1()
 class MyObject : public Glib::Object
 {
 protected:
-  MyObject(int id) : m_id(id) {}
+  explicit MyObject(int id) : m_id(id) {}
 
 public:
   static Glib::RefPtr<MyObject> create(int id)
index f70a1fa..7284ebb 100644 (file)
@@ -32,7 +32,7 @@ public:
   }
 
 protected:
-  Base64OutputStream(const Glib::RefPtr<Gio::OutputStream>& base_stream)
+  explicit Base64OutputStream(const Glib::RefPtr<Gio::OutputStream>& base_stream)
     : Gio::FilterOutputStream(base_stream), column(0), bit_count(0), bit_buffer(0), column_width(72) {}
 
   gssize write_vfunc(const void* buffer, gsize count, const Glib::RefPtr<Gio::Cancellable>& cancellable) override
index c097cbb..16fa72a 100644 (file)
@@ -109,7 +109,7 @@ class TestInterface : public Glib::Interface
 protected:
   using CppClassType = TestInterface_Class;
 
-  TestInterface() : Glib::Interface(derived_interface_class_.init()) {}
+  TestInterface() : Glib::Interface(derived_interface_class_.init()), i_(0) {}
 
 public:
   // A real application would never make the constructor public.
@@ -187,7 +187,7 @@ public:
 
   // A real application would never make the constructor public.
   // It would instead have a protected constructor and a public create() method.
-  DerivedObject(int i)
+  explicit DerivedObject(int i)
   : Glib::ObjectBase(nullptr),
     Glib::Object(Glib::ConstructParams(derived_object_class_.init())),
     i_(i)
index 0554c48..c4033de 100644 (file)
@@ -14,7 +14,6 @@ node_build_string(type_nodetree_string& node, std::string& string)
 int
 main()
 {
-  std::list<std::string> alma;
   std::string tstring, cstring;
   type_nodetree_string* root;
   type_nodetree_string* node;
index 8ac5d50..dca4ee3 100644 (file)
@@ -401,7 +401,7 @@ get_log_flags()
 
 struct WarnCatcher
 {
-  WarnCatcher(const std::string& domain)
+  explicit WarnCatcher(const std::string& domain)
   : m_domain(domain), m_old_flags(g_log_set_fatal_mask(m_domain.c_str(), get_log_flags()))
   {
   }