1 /* rcbox.c: Reference counted data
3 * Copyright 2018 Emmanuele Bassi
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 static Point
*global_point
;
27 /* test_rcbox_new: Test g_rc_box_new() */
31 Point
*a
= g_rc_box_new (Point
);
34 g_assert_cmpuint (g_rc_box_get_size (a
), ==, sizeof (Point
));
38 a
= g_rc_box_new0 (Point
);
40 g_assert_cmpfloat (a
->x
, ==, 0.f
);
41 g_assert_cmpfloat (a
->y
, ==, 0.f
);
46 /* test_atomic_rcbox_new: Test g_atomic_rc_box_new() */
48 test_atomic_rcbox_new (void)
50 Point
*a
= g_atomic_rc_box_new (Point
);
53 g_assert_cmpuint (g_atomic_rc_box_get_size (a
), ==, sizeof (Point
));
55 g_atomic_rc_box_release (a
);
57 a
= g_atomic_rc_box_new0 (Point
);
59 g_assert_cmpfloat (a
->x
, ==, 0.f
);
60 g_assert_cmpfloat (a
->y
, ==, 0.f
);
62 g_atomic_rc_box_release (a
);
66 point_clear (Point
*p
)
69 g_assert_true (global_point
== p
);
71 g_assert_cmpfloat (p
->x
, ==, 42.0f
);
72 g_assert_cmpfloat (p
->y
, ==, 47.0f
);
74 g_test_message ("global_point = %p", p
);
78 /* test_rcbox_release_full: Verify that g_rc_box_release_full() calls
79 * the clear function only when the last reference is released
82 test_rcbox_release_full (void)
84 Point
*p
= g_rc_box_new (Point
);
92 g_assert_true (g_rc_box_acquire (p
) == p
);
94 g_rc_box_release_full (p
, (GDestroyNotify
) point_clear
);
95 g_assert_nonnull (global_point
);
96 g_assert_true (p
== global_point
);
98 g_rc_box_release_full (p
, (GDestroyNotify
) point_clear
);
99 g_assert_null (global_point
);
102 /* test_atomic_rcbox_release_full: Verify that g_atomic_rc_box_release_full()
103 * calls the clear function only when the last reference is released
106 test_atomic_rcbox_release_full (void)
108 Point
*p
= g_atomic_rc_box_new (Point
);
110 g_assert_nonnull (p
);
116 g_assert_true (g_atomic_rc_box_acquire (p
) == p
);
118 g_atomic_rc_box_release_full (p
, (GDestroyNotify
) point_clear
);
119 g_assert_nonnull (global_point
);
120 g_assert_true (p
== global_point
);
122 g_atomic_rc_box_release_full (p
, (GDestroyNotify
) point_clear
);
123 g_assert_null (global_point
);
126 static Point
*global_point_a
;
127 static Point
*global_point_b
;
130 point_clear_dup_a (Point
*a
)
132 g_assert_true (a
== global_point_a
);
134 g_test_message ("global_point_a = %p", a
);
135 global_point_a
= NULL
;
139 point_clear_dup_b (Point
*b
)
141 g_assert_true (b
== global_point_b
);
143 g_test_message ("global_point_b = %p", b
);
144 global_point_b
= NULL
;
147 /* test_rcbox_dup: Verify that g_rc_box_dup() copies only the
148 * data and does not change the reference count of the original
151 test_rcbox_dup (void)
155 a
= g_rc_box_new (Point
);
159 b
= g_rc_box_dup (sizeof (Point
), a
);
160 g_assert_true (a
!= b
);
161 g_assert_cmpfloat (a
->x
, ==, b
->x
);
162 g_assert_cmpfloat (a
->y
, ==, b
->y
);
169 g_assert_cmpfloat (a
->x
, !=, b
->x
);
170 g_assert_cmpfloat (a
->y
, !=, b
->y
);
174 g_assert_cmpfloat (a
->x
, !=, b
->x
);
175 g_assert_cmpfloat (a
->y
, !=, b
->y
);
177 g_rc_box_release_full (a
, (GDestroyNotify
) point_clear_dup_a
);
178 g_assert_null (global_point_a
);
179 g_assert_nonnull (global_point_b
);
181 g_rc_box_release_full (b
, (GDestroyNotify
) point_clear_dup_b
);
182 g_assert_null (global_point_b
);
185 /* test_atomic_rcbox_dup: Verify that g_atomic_rc_box_dup() copies
186 * only the data and does not change the reference count of the original
189 test_atomic_rcbox_dup (void)
193 a
= g_atomic_rc_box_new (Point
);
197 b
= g_atomic_rc_box_dup (sizeof (Point
), a
);
198 g_assert_true (a
!= b
);
199 g_assert_cmpfloat (a
->x
, ==, b
->x
);
200 g_assert_cmpfloat (a
->y
, ==, b
->y
);
207 g_assert_cmpfloat (a
->x
, !=, b
->x
);
208 g_assert_cmpfloat (a
->y
, !=, b
->y
);
212 g_assert_cmpfloat (a
->x
, !=, b
->x
);
213 g_assert_cmpfloat (a
->y
, !=, b
->y
);
215 g_atomic_rc_box_release_full (a
, (GDestroyNotify
) point_clear_dup_a
);
216 g_assert_null (global_point_a
);
217 g_assert_nonnull (global_point_b
);
219 g_atomic_rc_box_release_full (b
, (GDestroyNotify
) point_clear_dup_b
);
220 g_assert_null (global_point_b
);
227 g_test_init (&argc
, &argv
, NULL
);
229 g_test_add_func ("/rcbox/new", test_rcbox_new
);
230 g_test_add_func ("/rcbox/release-full", test_rcbox_release_full
);
231 g_test_add_func ("/rcbox/dup", test_rcbox_dup
);
233 g_test_add_func ("/atomic-rcbox/new", test_atomic_rcbox_new
);
234 g_test_add_func ("/atomic-rcbox/release-full", test_atomic_rcbox_release_full
);
235 g_test_add_func ("/atomic-rcbox/dup", test_atomic_rcbox_dup
);
237 return g_test_run ();