[glibmm] Glib::ObjectBase: Use std::forward_list for interface class pointers



commit d3f5134bdf9de3e3676b3479e08b37140a801a68
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Fri Nov 25 16:40:22 2016 +0100

    Glib::ObjectBase: Use std::forward_list for interface class pointers
    
    std::forward_list is ideally suited for storing pointers to the interfaces
    of custom types. The list is often empty, never long. No need to use a pointer
    to a container in order to save storage space (as I did in the previous
    commit). An empty std::forward_list consists of nothing but a pointer.

 glib/glibmm/class.cc      |    5 ++---
 glib/glibmm/class.h       |   10 +++++++---
 glib/glibmm/interface.cc  |    3 ++-
 glib/glibmm/object.cc     |   13 +++++++++----
 glib/glibmm/objectbase.cc |    9 +++------
 glib/glibmm/objectbase.h  |    5 ++---
 6 files changed, 25 insertions(+), 20 deletions(-)
---
diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc
index 2f76aba..696bf79 100644
--- a/glib/glibmm/class.cc
+++ b/glib/glibmm/class.cc
@@ -86,7 +86,7 @@ Class::register_derived_type(GType base_type, GTypeModule* module)
 
 GType
 Class::clone_custom_type(
-  const char* custom_type_name, const interface_class_vector_type& interface_classes) const
+  const char* custom_type_name, const interface_class_list_type& interface_classes) const
 {
   std::string full_name("gtkmm__CustomObject_");
   Glib::append_canonical_typename(full_name, custom_type_name);
@@ -130,9 +130,8 @@ Class::clone_custom_type(
 
     // Add derived versions of interfaces, if the C type implements any interfaces.
     // For instance, TreeModel_Class::add_interface().
-    for (interface_class_vector_type::size_type i = 0; i < interface_classes.size(); i++)
+    for (auto interface_class : interface_classes)
     {
-      const Interface_Class* interface_class = interface_classes[i];
       if (interface_class)
       {
         interface_class->add_interface(custom_type);
diff --git a/glib/glibmm/class.h b/glib/glibmm/class.h
index 813b467..849065b 100644
--- a/glib/glibmm/class.h
+++ b/glib/glibmm/class.h
@@ -23,6 +23,7 @@
 #include <glibmmconfig.h> //Include this here so that the /private/*.h classes have access to 
GLIBMM_VFUNCS_ENABLED
 
 #include <vector> //For interface properties that custom types might override.
+#include <forward_list> //For interface classes that custom types might implement.
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
@@ -51,8 +52,11 @@ public:
 
   inline GType get_type() const;
 
-  /// The type that holds pointers to the interfaces of custom types.
-  using interface_class_vector_type = std::vector<const Interface_Class*>;
+  /** 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.
+   */
+  using interface_class_list_type = std::forward_list<const Interface_Class*>;
 
   /** 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,7 +69,7 @@ public:
    * @return The registered type.
    */
   GType clone_custom_type(
-    const char* custom_type_name, const interface_class_vector_type& interface_classes) const;
+    const char* custom_type_name, const interface_class_list_type& interface_classes) const;
 
 protected:
   GType gtype_;
diff --git a/glib/glibmm/interface.cc b/glib/glibmm/interface.cc
index 62878d6..0429840 100644
--- a/glib/glibmm/interface.cc
+++ b/glib/glibmm/interface.cc
@@ -98,7 +98,8 @@ Interface::Interface(const Interface_Class& interface_class)
     {
       // The GObject is not instantiated yet. Add to the custom_interface_classes_
       // and add the interface in the Glib::Object constructor.
-      custom_interface_classes_->emplace_back(&interface_class);
+      // custom_interface_classes_ is a std::forward_list. There is no emplace_back().
+      custom_interface_classes_.emplace_front(&interface_class);
     }
   }
 }
diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc
index c4e0a6f..19f30d5 100644
--- a/glib/glibmm/object.cc
+++ b/glib/glibmm/object.cc
@@ -195,9 +195,13 @@ 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_.reset(nullptr);
+    object_type = object_class_.clone_custom_type(custom_type_name_, custom_interface_classes_);
+    custom_interface_classes_.clear();
   }
 
   void* const new_object = g_object_newv(object_type, 0, nullptr);
@@ -216,9 +220,10 @@ 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_.reset(nullptr);
+      construct_params.glibmm_class.clone_custom_type(custom_type_name_, custom_interface_classes_);
+    custom_interface_classes_.clear();
   }
 
   // Create a new GObject with the specified array of construct properties.
diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc
index 15c8197..9f05283 100644
--- a/glib/glibmm/objectbase.cc
+++ b/glib/glibmm/objectbase.cc
@@ -43,22 +43,19 @@ namespace Glib
 ObjectBase::ObjectBase()
 : gobject_(nullptr),
   custom_type_name_(anonymous_custom_type_name),
-  cpp_destruction_in_progress_(false),
-  custom_interface_classes_(nullptr)
+  cpp_destruction_in_progress_(false)
 {
 }
 
 ObjectBase::ObjectBase(const char* custom_type_name)
 : gobject_(nullptr), custom_type_name_(custom_type_name),
-  cpp_destruction_in_progress_(false),
-  custom_interface_classes_(custom_type_name_ ? new Class::interface_class_vector_type : nullptr)
+  cpp_destruction_in_progress_(false)
 {
 }
 
 ObjectBase::ObjectBase(const std::type_info& custom_type_info)
 : gobject_(nullptr), custom_type_name_(custom_type_info.name()),
-  cpp_destruction_in_progress_(false),
-  custom_interface_classes_(new Class::interface_class_vector_type)
+  cpp_destruction_in_progress_(false)
 {
 }
 
diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h
index ce7243d..ab95d6b 100644
--- a/glib/glibmm/objectbase.h
+++ b/glib/glibmm/objectbase.h
@@ -28,7 +28,6 @@
 #include <glibmm/debug.h>
 #include <sigc++/trackable.h>
 #include <typeinfo>
-#include <memory>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" {
@@ -222,9 +221,9 @@ protected:
 
   bool is_anonymous_custom_() const;
 
-  // Vector of pointers to the interfaces of custom types.
+  // List of pointers to the interfaces of custom types.
   // Used only during the construction of named custom types.
-  std::unique_ptr<Class::interface_class_vector_type> custom_interface_classes_;
+  Class::interface_class_list_type custom_interface_classes_;
 
 public:
   //  is_derived_() must be public, so that overridden vfuncs and signal handlers can call it


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]