[gjs: 5/18] jsapi-util: Add copy and equality operator to GjsAutoPointer




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]