Further cleanup of sizeof
[framework/uifw/harfbuzz.git] / src / hb-object-private.h
1 /*
2  * Copyright (C) 2007 Chris Wilson
3  * Copyright (C) 2009,2010  Red Hat, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Contributor(s):
26  *      Chris Wilson <chris@chris-wilson.co.uk>
27  * Red Hat Author(s): Behdad Esfahbod
28  */
29
30 #ifndef HB_REFCOUNT_PRIVATE_H
31 #define HB_REFCOUNT_PRIVATE_H
32
33 #include "hb-private.h"
34
35
36
37 /* Encapsulate operations on the object's reference count */
38 typedef struct {
39   hb_atomic_int_t ref_count;
40 } hb_reference_count_t;
41
42 #define hb_reference_count_inc(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, 1)
43 #define hb_reference_count_dec(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, -1)
44
45 #define HB_REFERENCE_COUNT_INIT(RC, VALUE) ((RC).ref_count = (VALUE))
46
47 #define HB_REFERENCE_COUNT_GET_VALUE(RC) hb_atomic_int_get ((RC).ref_count)
48 #define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) hb_atomic_int_set ((RC).ref_count, (VALUE))
49
50 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
51 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
52
53 #define HB_REFERENCE_COUNT_IS_INVALID(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) == HB_REFERENCE_COUNT_INVALID_VALUE)
54
55 #define HB_REFERENCE_COUNT_HAS_REFERENCE(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) > 0)
56
57
58
59 /* Debug */
60
61 #ifndef HB_DEBUG_OBJECT
62 #define HB_DEBUG_OBJECT HB_DEBUG+0
63 #endif
64
65 static inline hb_bool_t /* always returns TRUE */
66 _hb_object_debug_out (const void *obj,
67                       hb_reference_count_t *ref_count,
68                       const char *function)
69 {
70   if (HB_DEBUG_OBJECT)
71     fprintf (stderr, "%p refcount=%d %s\n",
72              obj,
73              HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
74              function);
75   return TRUE;
76 }
77
78 #define HB_OBJECT_DEBUG_OUT(obj) _hb_object_debug_out ((void *) obj, &obj->ref_count, __FUNCTION__)
79
80
81
82 /* Object allocation and lifecycle manamgement macros */
83
84 #define HB_OBJECT_IS_INERT(obj) \
85     (unlikely (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count)))
86
87 #define HB_OBJECT_DO_INIT_EXPR(obj) \
88     HB_REFERENCE_COUNT_INIT (obj->ref_count, 1)
89
90 #define HB_OBJECT_DO_INIT(obj) \
91   HB_STMT_START { \
92     HB_OBJECT_DO_INIT_EXPR (obj); \
93   } HB_STMT_END
94
95 #define HB_OBJECT_DO_CREATE(Type, obj) \
96   likely (( \
97                (void) ( \
98                  ((obj) = (Type *) calloc (1, sizeof (Type))) && \
99                  HB_OBJECT_DO_INIT_EXPR (obj) && \
100                  HB_OBJECT_DEBUG_OUT (obj) \
101                ), \
102                (obj) \
103              ))
104
105 #define HB_OBJECT_DO_REFERENCE(obj) \
106   HB_STMT_START { \
107     int old_count; \
108     if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
109       return obj; \
110     HB_OBJECT_DEBUG_OUT (obj); \
111     old_count = hb_reference_count_inc (obj->ref_count); \
112     assert (old_count > 0); \
113     return obj; \
114   } HB_STMT_END
115
116 #define HB_OBJECT_DO_GET_REFERENCE_COUNT(obj) \
117   HB_STMT_START { \
118     if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
119       return 0; \
120     return HB_REFERENCE_COUNT_GET_VALUE (obj->ref_count); \
121   } HB_STMT_END
122
123 #define HB_OBJECT_DO_DESTROY(obj) \
124   HB_STMT_START { \
125     int old_count; \
126     if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
127       return; \
128     HB_OBJECT_DEBUG_OUT (obj); \
129     old_count = hb_reference_count_dec (obj->ref_count); \
130     assert (old_count > 0); \
131     if (old_count != 1) \
132       return; \
133   } HB_STMT_END
134
135
136
137 #endif /* HB_REFCOUNT_PRIVATE_H */