[vte] lib: Add RefPtr type for holding a GObject
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] lib: Add RefPtr type for holding a GObject
- Date: Mon, 23 Apr 2018 18:53:09 +0000 (UTC)
commit d282b59690df3edf164274a082792d4b1a87bae6
Author: Christian Persch <chpe src gnome org>
Date: Mon Apr 23 20:51:18 2018 +0200
lib: Add RefPtr type for holding a GObject
src/Makefile.am | 19 +++++++-
src/refptr-test.cc | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/refptr.hh | 38 +++++++++++++++
src/vteinternal.hh | 1 +
src/vtetypes.hh | 1 +
5 files changed, 193 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 39ce8c8..7c13a5e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -76,6 +76,7 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
pty.cc \
reaper.cc \
reaper.hh \
+ refptr.hh \
ring.cc \
ring.hh \
vte.cc \
@@ -186,7 +187,7 @@ vteresources.cc: vte.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --
# Misc unit tests and utilities
-noinst_PROGRAMS += parser-cat slowcat test-modes test-tabstops test-parser
+noinst_PROGRAMS += parser-cat slowcat test-modes test-tabstops test-parser test-refptr
noinst_SCRIPTS = decset osc window
EXTRA_DIST += $(noinst_SCRIPTS)
@@ -209,6 +210,7 @@ dist_check_SCRIPTS = \
TESTS = \
test-modes \
test-parser \
+ test-refptr \
test-tabstops \
reaper \
test-vtetypes \
@@ -350,6 +352,21 @@ test_tabstops_LDADD = \
$(GLIB_LIBS) \
$(NULL)
+test_refptr_SOURCES = \
+ refptr.hh \
+ refptr-test.cc \
+ $(NULL)
+test_refptr_CPPFLAGS = \
+ -I$(builddir) \
+ -I$(srcdir) \
+ $(AM_CPPFLAGS)
+test_refptr_CXXFLAGS = \
+ $(GOBJECT_CFLAGS) \
+ $(AM_CXXFLAGS)
+test_refptr_LDADD = \
+ $(GOBJECT_LIBS) \
+ $(NULL)
+
test_vtetypes_SOURCES = \
vtetypes.cc \
vtetypes.hh \
diff --git a/src/refptr-test.cc b/src/refptr-test.cc
new file mode 100644
index 0000000..41e4b6e
--- /dev/null
+++ b/src/refptr-test.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2018 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/>.
+ */
+
+#include "config.h"
+
+#include "refptr.hh"
+
+/* Test object */
+
+typedef struct _TestObject TestObject;
+typedef struct _TestObjectClass TestObjectClass;
+
+struct _TestObject {
+ GObject parent_instance;
+};
+
+struct _TestObjectClass{
+ GObjectClass parent_class;
+};
+
+static GType test_object_get_type(void);
+
+G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT)
+
+static void
+test_object_init(TestObject* object)
+{
+}
+
+static void
+test_object_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(test_object_parent_class)->finalize(object);
+}
+
+static void
+test_object_class_init(TestObjectClass* klass)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->finalize = test_object_finalize;
+}
+
+static TestObject*
+test_object_new(void)
+{
+ return reinterpret_cast<TestObject*>(g_object_new(test_object_get_type(),
+ nullptr));
+}
+
+/* Tests */
+
+typedef union {
+ TestObject* obj;
+ void* ptr;
+} obj_t;
+
+static void
+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;
+ g_assert_true(ptr1.get() == obj1.obj);
+
+ auto ptr2 = std::move(ptr1);
+ g_assert_true(ptr1.get() == nullptr);
+ g_assert_true(ptr2.get() == obj1.obj);
+
+ obj_t obj2;
+ obj2.obj = test_object_new();
+ g_object_add_weak_pointer(G_OBJECT(obj2.obj), &obj2.ptr);
+ g_assert_nonnull(obj2.ptr);
+ ptr2 = obj2.obj;
+ g_assert_null(obj1.ptr);
+ g_assert_true(ptr2.get() == obj2.obj);
+ g_assert_nonnull(obj2.ptr);
+
+ ptr2 = nullptr;
+ g_assert_null(obj2.ptr);
+
+ obj_t obj3;
+ 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;
+ TestObject* obj4 = ptr3.release();
+ g_assert_null(ptr3.get());
+ g_assert_nonnull(obj4);
+ g_object_unref(obj4);
+ g_assert_null(obj3.ptr);
+
+ obj_t obj5;
+ obj5.obj = test_object_new();
+ g_object_add_weak_pointer(G_OBJECT(obj5.obj), &obj5.ptr);
+ g_assert_nonnull(obj5.ptr);
+ vte::glib::RefPtr<TestObject> ptr5{obj5.obj};
+
+ obj_t obj6;
+ obj6.obj = test_object_new();
+ g_object_add_weak_pointer(G_OBJECT(obj6.obj), &obj6.ptr);
+ g_assert_nonnull(obj6.ptr);
+
+ ptr5.reset(obj6.obj);
+ g_assert_null(obj5.ptr);
+
+ ptr5.reset();
+ g_assert_null(obj6.ptr);
+ g_assert_null(ptr5.get());
+}
+
+int
+main(int argc,
+ char* argv[])
+{
+ g_test_init(&argc, &argv, nullptr);
+
+ g_test_add_func("/vte/glib/refptr", test_glib_refptr);
+
+ return g_test_run();
+}
diff --git a/src/refptr.hh b/src/refptr.hh
new file mode 100644
index 0000000..ae7a96d
--- /dev/null
+++ b/src/refptr.hh
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2018 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 <memory>
+#include <glib-object.h>
+
+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} { }
+};
+
+} // namespace glib
+} // namespace vte
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 548edb0..a2c525a 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -30,6 +30,7 @@
#include "parser-glue.hh"
#include "modes.hh"
#include "tabstops.hh"
+#include "refptr.hh"
#include "vtepcre2.h"
#include "vteregexinternal.hh"
diff --git a/src/vtetypes.hh b/src/vtetypes.hh
index 885c2fb..54d9f42 100644
--- a/src/vtetypes.hh
+++ b/src/vtetypes.hh
@@ -22,6 +22,7 @@
#include <errno.h>
#include <cstdint>
+#include <memory>
#ifdef VTE_DEBUG
#define IFDEF_DEBUG(str) str
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]