[vte] lib: Improve smart pointers



commit 0604617936deb66e89f235640e1ed933ef4f3e3d
Author: Christian Persch <chpe src gnome org>
Date:   Mon Jun 1 22:48:43 2020 +0200

    lib: Improve smart pointers
    
    Save some memory by using an empty deleter class.

 src/cairo-glue.hh    | 28 ++++++++++++++++++++++++++++
 src/cxx-utils.hh     | 14 ++++++++++++++
 src/drawing-cairo.cc |  9 ++++-----
 src/drawing-cairo.hh |  4 +++-
 src/glib-glue.hh     | 18 ++++--------------
 src/meson.build      |  1 +
 src/refptr-test.cc   |  6 +++---
 src/refptr.hh        | 19 +++++++------------
 src/regex.hh         |  9 +++++++--
 src/vte.cc           |  4 ++--
 src/vteinternal.hh   |  6 +++---
 src/widget.cc        |  2 +-
 12 files changed, 77 insertions(+), 43 deletions(-)
---
diff --git a/src/cairo-glue.hh b/src/cairo-glue.hh
new file mode 100644
index 00000000..fcb0bc48
--- /dev/null
+++ b/src/cairo-glue.hh
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2020 Christian Persch
+ *
+ * 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 3 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 General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <cairo.h>
+
+#include "cxx-utils.hh"
+
+namespace vte::cairo {
+
+using Surface = vte::FreeablePtr<cairo_surface_t, decltype(&cairo_surface_destroy), &cairo_surface_destroy>;
+
+} // namespace vte::cairo
diff --git a/src/cxx-utils.hh b/src/cxx-utils.hh
index bb831165..1f3abad4 100644
--- a/src/cxx-utils.hh
+++ b/src/cxx-utils.hh
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <exception>
 #include <type_traits>
+#include <memory>
 
 namespace vte {
 
@@ -42,4 +43,17 @@ void log_exception(char const* func = __builtin_FUNCTION(),
 inline void log_exception() noexcept { }
 #endif
 
+template <typename T, typename D, D func>
+class FreeableDeleter {
+public:
+        void operator()(T* obj) const
+        {
+                if (obj)
+                        func(obj);
+        }
+};
+
+template <typename T, typename D, D func>
+using FreeablePtr = std::unique_ptr<T, FreeableDeleter<T, D, func>>;
+
 } // namespace vte
diff --git a/src/drawing-cairo.cc b/src/drawing-cairo.cc
index 667ec27c..4a3de9b5 100644
--- a/src/drawing-cairo.cc
+++ b/src/drawing-cairo.cc
@@ -521,11 +521,10 @@ DrawingContext::draw_undercurl(int x,
                                   "caching undercurl shape\n");
 
                 /* Add a line_width of margin horizontally on both sides, for nice antialias overflowing. */
-                m_undercurl_surface = {cairo_surface_create_similar (cairo_get_target (m_cr),
-                                                                     CAIRO_CONTENT_ALPHA,
-                                                                     m_cell_width + 2 * x_padding,
-                                                                     surface_bottom - surface_top),
-                                       &cairo_surface_destroy};
+                m_undercurl_surface.reset(cairo_surface_create_similar (cairo_get_target (m_cr),
+                                                                        CAIRO_CONTENT_ALPHA,
+                                                                        m_cell_width + 2 * x_padding,
+                                                                        surface_bottom - surface_top));
                 undercurl_cr = cairo_create (m_undercurl_surface.get());
                 cairo_set_operator (undercurl_cr, CAIRO_OPERATOR_OVER);
                 /* First quarter circle, similar to the left half of the tilde symbol. */
diff --git a/src/drawing-cairo.hh b/src/drawing-cairo.hh
index 8c605e35..62999a8e 100644
--- a/src/drawing-cairo.hh
+++ b/src/drawing-cairo.hh
@@ -27,6 +27,7 @@
 #include <glib.h>
 #include <gtk/gtk.h>
 
+#include "cairo-glue.hh"
 #include "fwd.hh"
 #include "minifont.hh"
 #include "vtetypes.hh"
@@ -157,7 +158,8 @@ private:
         Minifont m_minifont{};
 
         /* Cache the undercurl's rendered look. */
-        std::unique_ptr<cairo_surface_t, decltype(&cairo_surface_destroy)> m_undercurl_surface{nullptr, 
nullptr};
+        vte::cairo::Surface m_undercurl_surface{};
+
 }; // class DrawingContext
 
 } // namespace view
diff --git a/src/glib-glue.hh b/src/glib-glue.hh
index dd317db9..c50f67e1 100644
--- a/src/glib-glue.hh
+++ b/src/glib-glue.hh
@@ -28,24 +28,14 @@
 
 namespace vte::glib {
 
-template <typename T, typename D, D d>
-class FreeablePtr : public std::unique_ptr<T, D>
-{
-private:
-        using base_type = std::unique_ptr<T, D>;
-
-public:
-        FreeablePtr(T* ptr = nullptr) : base_type{ptr, d} { }
-};
-
 template<typename T>
-using FreePtr = FreeablePtr<T, decltype(&g_free), &g_free>;
+using FreePtr = vte::FreeablePtr<T, decltype(&g_free), &g_free>;
 
 template<typename T>
 FreePtr<T>
 take_free_ptr(T* ptr)
 {
-        return {ptr};
+        return FreePtr<T>{ptr};
 }
 
 using StringPtr = FreePtr<char>;
@@ -62,12 +52,12 @@ dup_string(char const* str)
         return take_string(g_strdup(str));
 }
 
-using StrvPtr = FreeablePtr<char*, decltype(&g_strfreev), &g_strfreev>;
+using StrvPtr = vte::FreeablePtr<char*, decltype(&g_strfreev), &g_strfreev>;
 
 inline StrvPtr
 take_strv(char** strv)
 {
-        return {strv};
+        return StrvPtr{strv};
 }
 
 inline StrvPtr
diff --git a/src/meson.build b/src/meson.build
index a23ea5bb..ceba1f68 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -98,6 +98,7 @@ libvte_common_sources = debug_sources + glib_glue_sources + libc_glue_sources +
   'bidi.cc',
   'bidi.hh',
   'buffer.h',
+  'cairo-glue.hh',
   'caps.hh',
   'cell.hh',
   'chunk.cc',
diff --git a/src/refptr-test.cc b/src/refptr-test.cc
index 41e4b6e9..4932a72c 100644
--- a/src/refptr-test.cc
+++ b/src/refptr-test.cc
@@ -74,7 +74,7 @@ test_glib_refptr(void)
         obj_t obj1;
         obj1.obj = test_object_new();
         g_object_add_weak_pointer(G_OBJECT(obj1.obj), &obj1.ptr);
-        vte::glib::RefPtr<TestObject> ptr1 = obj1.obj;
+        auto ptr1 = vte::glib::RefPtr<TestObject>{obj1.obj};
         g_assert_true(ptr1.get() == obj1.obj);
 
         auto ptr2 = std::move(ptr1);
@@ -85,7 +85,7 @@ test_glib_refptr(void)
         obj2.obj = test_object_new();
         g_object_add_weak_pointer(G_OBJECT(obj2.obj), &obj2.ptr);
         g_assert_nonnull(obj2.ptr);
-        ptr2 = obj2.obj;
+        ptr2.reset(obj2.obj);
         g_assert_null(obj1.ptr);
         g_assert_true(ptr2.get() == obj2.obj);
         g_assert_nonnull(obj2.ptr);
@@ -97,7 +97,7 @@ test_glib_refptr(void)
         obj3.obj = test_object_new();
         g_object_add_weak_pointer(G_OBJECT(obj3.obj), &obj3.ptr);
         g_assert_nonnull(obj3.ptr);
-        vte::glib::RefPtr<TestObject> ptr3 = obj3.obj;
+        auto ptr3 = vte::glib::RefPtr<TestObject>{obj3.obj};
         TestObject* obj4 = ptr3.release();
         g_assert_null(ptr3.get());
         g_assert_nonnull(obj4);
diff --git a/src/refptr.hh b/src/refptr.hh
index 3fcc89e6..c1bc04c1 100644
--- a/src/refptr.hh
+++ b/src/refptr.hh
@@ -20,19 +20,14 @@
 #include <memory>
 #include <glib-object.h>
 
+#include "cxx-utils.hh"
+
 namespace vte {
 
 namespace glib {
 
-template <typename T>
-class RefPtr : public std::unique_ptr<T, decltype(&g_object_unref)>
-{
-private:
-        using base_type = std::unique_ptr<T, decltype(&g_object_unref)>;
-
-public:
-        RefPtr(T* obj = nullptr) : base_type{obj, &g_object_unref} { }
-};
+template<typename T>
+using RefPtr = vte::FreeablePtr<T, decltype(&g_object_unref), &g_object_unref>;
 
 template<typename T>
 RefPtr<T>
@@ -40,7 +35,7 @@ make_ref(T* obj)
 {
         if (obj)
                 g_object_ref(obj);
-        return {obj};
+        return RefPtr<T>{obj};
 }
 
 template<typename T>
@@ -49,14 +44,14 @@ make_ref_sink(T* obj)
 {
         if (obj)
                 g_object_ref_sink(obj);
-        return {obj};
+        return RefPtr<T>{obj};
 }
 
 template<typename T>
 RefPtr<T>
 take_ref(T* obj)
 {
-        return {obj};
+        return RefPtr<T>{obj};
 }
 
 template<typename T>
diff --git a/src/regex.hh b/src/regex.hh
index 8db3e158..a115cdb4 100644
--- a/src/regex.hh
+++ b/src/regex.hh
@@ -25,6 +25,8 @@
 
 #include "vtepcre2.h"
 
+#include "cxx-utils.hh"
+
 namespace vte {
 
 namespace base {
@@ -45,13 +47,16 @@ public:
 
 private:
         mutable volatile int m_refcount{1};
-        std::unique_ptr<pcre2_code_8, decltype(&pcre2_code_free_8)> m_code;
+
+        using code_type = vte::FreeablePtr<pcre2_code_8, decltype(&pcre2_code_free_8), &pcre2_code_free_8>;
+        code_type m_code{};
+
         Purpose m_purpose;
 
 public:
         Regex(pcre2_code_8* code,
               Purpose purpose) noexcept :
-                m_code{code, &pcre2_code_free_8},
+                m_code{code},
                 m_purpose{purpose}
         { }
 
diff --git a/src/vte.cc b/src/vte.cc
index 99b6d341..e6545ca7 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -7277,7 +7277,7 @@ Terminal::update_font()
                 pango_font_description_set_size(desc, m_font_scale * size);
         }
 
-        m_fontdesc = {desc, &pango_font_description_free};
+        m_fontdesc.reset(desc); /* adopts */
         m_fontdirty = true;
         m_has_fonts = true;
 
@@ -7334,7 +7334,7 @@ Terminal::set_font_desc(PangoFontDescription const* font_desc)
         * detected at font creation time and respected.
         */
 
-        m_unscaled_font_desc = {desc, &pango_font_description_free};
+        m_unscaled_font_desc.reset(desc); /* adopts */
         update_font();
 
         return !same_desc;
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index e456359b..bc75888e 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -843,9 +843,9 @@ public:
 
        /* Data used when rendering the text which does not require server
         * resources and which can be kept after unrealizing. */
-        using pango_font_description_unique_type = std::unique_ptr<PangoFontDescription, 
decltype(&pango_font_description_free)>;
-        pango_font_description_unique_type m_unscaled_font_desc{nullptr, &pango_font_description_free};
-        pango_font_description_unique_type  m_fontdesc{nullptr, &pango_font_description_free};
+        using pango_font_description_type = vte::FreeablePtr<PangoFontDescription, 
decltype(&pango_font_description_free), &pango_font_description_free>;
+        pango_font_description_type m_unscaled_font_desc{};
+        pango_font_description_type  m_fontdesc{};
         double m_font_scale{1.};
 
         auto unscaled_font_description() const noexcept { return m_unscaled_font_desc.get(); }
diff --git a/src/widget.cc b/src/widget.cc
index 2967d93a..44a22717 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -477,7 +477,7 @@ Widget::realize() noexcept
         gtk_widget_register_window(m_widget, m_event_window);
 
         assert(!m_im_context);
-       m_im_context = gtk_im_multicontext_new();
+       m_im_context.reset(gtk_im_multicontext_new());
 #if GTK_CHECK_VERSION (3, 24, 14)
         g_object_set(m_im_context.get(),
                      "input-purpose", GTK_INPUT_PURPOSE_TERMINAL,


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