Commit 06046179 authored by Christian Persch's avatar Christian Persch

lib: Improve smart pointers

Save some memory by using an empty deleter class.
parent b0ef5036
/*
* 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
......@@ -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
......@@ -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. */
......
......@@ -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
......
......@@ -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
......
......@@ -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',
......
......@@ -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);
......
......@@ -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>
......
......@@ -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}
{ }
......
......@@ -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;
......
......@@ -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(); }
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment