[gjs: 5/18] jsapi-util: Add copy and equality operator to GjsAutoPointer
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 5/18] jsapi-util: Add copy and equality operator to GjsAutoPointer
- Date: Fri, 20 Nov 2020 01:52:03 +0000 (UTC)
commit 55fa159bcd58ddede392e5b295b1923038350743
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Thu Oct 1 13:46:26 2020 +0200
jsapi-util: Add copy and equality operator to GjsAutoPointer
Not being an unique_ptr anymore we've some more freedom (that will be
way more when C++ will allow us to do more static checks), one of the
good gain we've now, is that we can easily implement a copy and swap
idiom to allow to pass the wrappers by value ensuring an internal copy.
This will not work (unfortunately only with runtime checks! :-( ) if the
wrapper doesn't provide a copy function, but this is still nice.
Tests included.
gjs/jsapi-util.h | 17 +++++++++
test/gjs-test-jsapi-utils.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+)
---
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index aa2f391e..61bce271 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -62,6 +62,9 @@ struct GjsAutoPointer {
constexpr GjsAutoPointer(GjsAutoPointer&& other) : GjsAutoPointer() {
this->swap(other);
}
+ constexpr GjsAutoPointer(GjsAutoPointer const& other) : GjsAutoPointer() {
+ *this = other;
+ }
constexpr GjsAutoPointer& operator=(Ptr ptr) {
reset(ptr);
@@ -73,6 +76,12 @@ struct GjsAutoPointer {
return *this;
}
+ GjsAutoPointer& operator=(GjsAutoPointer const& other) {
+ GjsAutoPointer dup(other.get(), GjsAutoTakeOwnership());
+ this->swap(dup);
+ return *this;
+ }
+
template <typename U = T>
constexpr std::enable_if_t<!std::is_array_v<U>, Ptr> operator->() {
return m_ptr;
@@ -141,6 +150,14 @@ struct GjsAutoPointer {
Ptr m_ptr;
};
+template <typename T, typename F = void, void (*free_func)(F*) = free,
+ F* (*ref_func)(F*) = nullptr>
+constexpr bool operator==(
+ GjsAutoPointer<T, F, free_func, ref_func> const& lhs,
+ GjsAutoPointer<T, F, free_func, ref_func> const& rhs) {
+ return lhs.get() == rhs.get();
+}
+
template <typename T>
using GjsAutoFree = GjsAutoPointer<T>;
diff --git a/test/gjs-test-jsapi-utils.cpp b/test/gjs-test-jsapi-utils.cpp
index 5489ffa7..0a2ab493 100644
--- a/test/gjs-test-jsapi-utils.cpp
+++ b/test/gjs-test-jsapi-utils.cpp
@@ -75,6 +75,21 @@ static void test_gjs_autopointer_ctor_assign() {
g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 1);
}
+static void test_gjs_autopointer_ctor_assign_other() {
+ auto* ptr = gjs_test_object_new();
+ g_assert_nonnull(ptr);
+
+ GjsAutoTestObject autoptr1 = ptr;
+ GjsAutoTestObject autoptr2 = autoptr1;
+
+ g_assert(autoptr1 == ptr);
+ g_assert(autoptr1.get() == ptr);
+ g_assert(autoptr2 == ptr);
+ g_assert(autoptr2.get() == ptr);
+
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 2);
+}
+
static void test_gjs_autopointer_dtor() {
auto* ptr = gjs_test_object_new();
g_assert_nonnull(ptr);
@@ -199,6 +214,64 @@ static void test_gjs_autopointer_assign_operator_self_ptr() {
g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 1);
}
+static void test_gjs_autopointer_assign_operator_object() {
+ GjsAutoTestObject autoptr1;
+ GjsAutoTestObject autoptr2;
+ auto* ptr = gjs_test_object_new();
+
+ autoptr1 = ptr;
+ autoptr2 = autoptr1;
+
+ g_assert(autoptr1 == autoptr2);
+ g_assert(autoptr2.get() == ptr);
+
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 2);
+}
+
+static void test_gjs_autopointer_assign_operator_other_object() {
+ auto* ptr1 = gjs_test_object_new();
+ auto* ptr2 = gjs_test_object_new();
+
+ GjsAutoTestObject autoptr1(ptr1);
+ GjsAutoTestObject autoptr2(ptr2);
+
+ g_object_ref(ptr1);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr1), ==, 2);
+
+ autoptr1 = autoptr2;
+
+ g_assert(autoptr1 == ptr2);
+ g_assert(autoptr2 == ptr2);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr1), ==, 1);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr2), ==, 2);
+ g_object_unref(ptr1);
+}
+
+static void test_gjs_autopointer_assign_operator_self_object() {
+ auto* ptr = gjs_test_object_new();
+
+ GjsAutoTestObject autoptr(ptr);
+
+ autoptr = autoptr;
+
+ g_assert(autoptr == ptr);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 1);
+}
+
+static void test_gjs_autopointer_assign_operator_copy_and_swap() {
+ auto* ptr = gjs_test_object_new();
+ GjsAutoTestObject autoptr(ptr);
+
+ auto test_copy_fun = [ptr](GjsAutoTestObject data) {
+ g_assert(data == ptr);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(data), ==, 2);
+ };
+
+ test_copy_fun(autoptr);
+ g_assert(autoptr == ptr);
+ g_assert_cmpuint(test_gjs_autopointer_refcount(ptr), ==, 1);
+}
+
static void test_gjs_autopointer_operator_move() {
auto* ptr = gjs_test_object_new();
GjsAutoTestObject autoptr(ptr);
@@ -474,6 +547,9 @@ void gjs_test_add_tests_for_jsapi_utils(void) {
test_gjs_autopointer_ctor_take_ownership);
g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/constructor/assignment",
test_gjs_autopointer_ctor_assign);
+ g_test_add_func(
+ "/gjs/jsapi-utils/gjs-autopointer/constructor/assignment/other",
+ test_gjs_autopointer_ctor_assign_other);
g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/destructor",
test_gjs_autopointer_dtor);
g_test_add_func(
@@ -490,6 +566,17 @@ void gjs_test_add_tests_for_jsapi_utils(void) {
test_gjs_autopointer_assign_operator_other_ptr);
g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/operator/assign/self_ptr",
test_gjs_autopointer_assign_operator_self_ptr);
+ g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/operator/assign/object",
+ test_gjs_autopointer_assign_operator_object);
+ g_test_add_func(
+ "/gjs/jsapi-utils/gjs-autopointer/operator/assign/other_object",
+ test_gjs_autopointer_assign_operator_other_object);
+ g_test_add_func(
+ "/gjs/jsapi-utils/gjs-autopointer/operator/assign/self_object",
+ test_gjs_autopointer_assign_operator_self_object);
+ g_test_add_func(
+ "/gjs/jsapi-utils/gjs-autopointer/operator/assign/copy_and_swap",
+ test_gjs_autopointer_assign_operator_copy_and_swap);
g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/operator/move",
test_gjs_autopointer_operator_move);
g_test_add_func("/gjs/jsapi-utils/gjs-autopointer/operator/swap",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]