Imported Upstream version 2.74.3
[platform/upstream/glib.git] / glib / grefcount.h
1 /* grefcount.h: Reference counting
2  *
3  * Copyright 2018  Emmanuele Bassi
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifndef __GREFCOUNT_H__
22 #define __GREFCOUNT_H__
23
24 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
25 #error "Only <glib.h> can be included directly."
26 #endif
27
28 #include <glib/gatomic.h>
29 #include <glib/gtypes.h>
30
31 G_BEGIN_DECLS
32
33 GLIB_AVAILABLE_IN_2_58
34 void            g_ref_count_init                (grefcount       *rc);
35 GLIB_AVAILABLE_IN_2_58
36 void            g_ref_count_inc                 (grefcount       *rc);
37 GLIB_AVAILABLE_IN_2_58
38 gboolean        g_ref_count_dec                 (grefcount       *rc);
39 GLIB_AVAILABLE_IN_2_58
40 gboolean        g_ref_count_compare             (grefcount       *rc,
41                                                  gint             val);
42
43 GLIB_AVAILABLE_IN_2_58
44 void            g_atomic_ref_count_init         (gatomicrefcount *arc);
45 GLIB_AVAILABLE_IN_2_58
46 void            g_atomic_ref_count_inc          (gatomicrefcount *arc);
47 GLIB_AVAILABLE_IN_2_58
48 gboolean        g_atomic_ref_count_dec          (gatomicrefcount *arc);
49 GLIB_AVAILABLE_IN_2_58
50 gboolean        g_atomic_ref_count_compare      (gatomicrefcount *arc,
51                                                  gint             val);
52
53 /* On GCC we can use __extension__ to inline the API without using
54  * ancillary functions; we only do this when disabling checks, as
55  * it disables warnings when saturating the reference counters
56  */
57 #if defined(__GNUC__) && defined(G_DISABLE_CHECKS)
58
59 # define g_ref_count_init(rc) \
60   (G_GNUC_EXTENSION ({ \
61     G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
62     (void) (0 ? *(rc) ^ *(rc) : 1); \
63     *(rc) = -1; \
64   }))
65
66 # define g_ref_count_inc(rc) \
67   (G_GNUC_EXTENSION ({ \
68     G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
69     (void) (0 ? *(rc) ^ *(rc) : 1); \
70     if (*(rc) == G_MININT) ; else { \
71       *(rc) -= 1; \
72     } \
73   }))
74
75 # define g_ref_count_dec(rc) \
76   (G_GNUC_EXTENSION ({ \
77     G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
78     grefcount __rc = *(rc); \
79     __rc += 1; \
80     if (__rc == 0) ; else { \
81       *(rc) = __rc; \
82     } \
83     (gboolean) (__rc == 0); \
84   }))
85
86 # define g_ref_count_compare(rc,val) \
87   (G_GNUC_EXTENSION ({ \
88     G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
89     (void) (0 ? *(rc) ^ (val) : 1); \
90     (gboolean) (*(rc) == -(val)); \
91   }))
92
93 # define g_atomic_ref_count_init(rc) \
94   (G_GNUC_EXTENSION ({ \
95     G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
96     (void) (0 ? *(rc) ^ *(rc) : 1); \
97     *(rc) = 1; \
98   }))
99
100 # define g_atomic_ref_count_inc(rc) \
101   (G_GNUC_EXTENSION ({ \
102     G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
103     (void) (0 ? *(rc) ^ *(rc) : 1); \
104     (void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
105   }))
106
107 # define g_atomic_ref_count_dec(rc) \
108   (G_GNUC_EXTENSION ({ \
109     G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
110     (void) (0 ? *(rc) ^ *(rc) : 1); \
111     g_atomic_int_dec_and_test ((rc)); \
112   }))
113
114 # define g_atomic_ref_count_compare(rc,val) \
115   (G_GNUC_EXTENSION ({ \
116     G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
117     (void) (0 ? *(rc) ^ (val) : 1); \
118     (gboolean) (g_atomic_int_get (rc) == (val)); \
119   }))
120
121 #endif /* __GNUC__ && G_DISABLE_CHECKS */
122
123 G_END_DECLS
124
125 #endif /* __GREFCOUNT_H__ */