1 /**
2  * License:
3  * $(TABLE
4  *   $(TR $(TD cairoD wrapper/bindings)
5  *     $(TD $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)))
6  *   $(TR $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING, _cairo))
7  *     $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING-LGPL-2.1, LGPL 2.1) /
8  *     $(LINK2 http://cgit.freedesktop.org/cairo/plain/COPYING-MPL-1.1, MPL 1.1)))
9  * )
10  * Authors:
11  * $(TABLE
12  *   $(TR $(TD Johannes Pfau) $(TD cairoD))
13  *   $(TR $(TD $(LINK2 http://cairographics.org, _cairo team)) $(TD _cairo))
14  * )
15  */
16 /*
17  * Distributed under the Boost Software License, Version 1.0.
18  *    (See accompanying file LICENSE_1_0.txt or copy at
19  *          http://www.boost.org/LICENSE_1_0.txt)
20  */
21 module cairo.util;
22 
23 /**
24  * Mixin used by cairoD classes which wrap a reference counted
25  * cairo handle.
26  */
27 mixin template CairoCountedClass(T, string prefix)
28 {
29     protected:
30         /**
31          * Reference count. For use in child classes
32          */
33         @property uint _count()
34         {
35             mixin("return " ~ prefix ~ "get_reference_count(this.nativePointer);");
36         }
37 
38         /**
39          * Increase reference count. For use in child classes
40          */
41         void _reference()
42         {
43             mixin(prefix ~ "reference(this.nativePointer);");
44         }
45 
46         /**
47          * Decrease reference count. For use in child classes
48          */
49         void _dereference()
50         {
51             mixin(prefix ~ "destroy(this.nativePointer);");
52         }
53     
54     public:
55         /**
56          * The underlying $(T) handle
57          */
58         T nativePointer;
59         version(D_Ddoc)
60         {
61             /**
62              * Enable / disable memory management debugging for this
63              * instance. Only available if both cairoD and the cairoD user
64              * code were compiled with "debug=RefCounted"
65              *
66              * Output is written to stdout, see 
67              * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging)
68              * for more information
69              */
70             bool debugging;
71         }
72         else debug(RefCounted)
73         {
74             bool debugging;
75         }
76 
77         /**
78          * Explicitly drecrease the reference count.
79          *
80          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#3-RC-class)
81          * for more information.
82          */
83         void dispose()
84         {
85             debug(RefCounted)
86             {
87                 if(this.debugging && this.nativePointer is null)
88                     writeln(typeof(this).stringof,
89                     "@", cast(void*)this, ": dispose() Already disposed");
90             }
91             if(this.nativePointer !is null)
92             {
93                 debug(RefCounted)
94                 {
95                     if(this.debugging)
96                         writeln(typeof(this).stringof,
97                         "@", cast(void*)this, ": dispose() Cairo reference count is: ",
98                         this._count);
99                 }
100                 mixin(prefix ~ "destroy(this.nativePointer);");
101                 this.nativePointer = null;
102             }
103         }
104 
105         /**
106          * Destructor. Call $(D dispose()) if it hasn't been called manually.
107          */
108         ~this()
109         {
110             debug(RefCounted)
111             {
112                 if(this.debugging)
113                     writeln(typeof(this).stringof,
114                     "@", cast(void*)this, ": Destructor called");
115             }
116             dispose();
117         }
118 }
119 
120 /**
121  * Checks whether TargetType matches any subsequent types.
122  * Use as: isOneOf!(TargetType, Type1, Type2..);
123  */
124 template isOneOf(X, T...)
125 {
126 	static if (!T.length)
127 		enum bool isOneOf = false;
128 	else static if (is (X == T[0]))
129 		enum bool isOneOf = true;
130 	else
131 		enum bool isOneOf = isOneOf!(X, T[1..$]);
132 }