blob: e8cef216fd6446f7f60c2e65d9a72278b8bc21c3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/**
* A collection of helper functions used in DMagick.
*
* Copyright: Mike Wey 2011
* License: To be determined
* Authors: Mike Wey
*/
module dmagick.Utils;
import std.math;
import dmagick.c.memory;
import dmagick.c.magickString;
import dmagick.c.magickType;
/**
* Copy a string into a static array used
* by ImageMagick for some atributes.
*/
private void copyString(ref char[MaxTextExtent] dest, string source)
{
if ( source.length < MaxTextExtent )
throw new Exception("text is to long"); //TODO: a proper exception.
dest[0 .. source.length] = source;
dest[source.length] = '\0';
}
/**
* Our implementation of ImageMagick's CloneString.
*
* We use this since using CloneString forces us to
* append a \0 to the end of the string, and the realocation
* whould be wastefull if we are just going to copy it
*/
private void copyString(ref char* dest, string source)
{
if ( source is null )
{
if ( dest !is null )
DestroyString(dest);
return;
}
if ( ~source.length < MaxTextExtent )
throw new Exception("UnableToAcquireString"); //TODO: a proper exception.
if ( dest is null )
dest = cast(char*)AcquireQuantumMemory(source.length+MaxTextExtent, dest.sizeof);
else
dest = cast(char*)ResizeQuantumMemory(dest, source.length+MaxTextExtent, dest.sizeof);
if ( dest is null )
throw new Exception("UnableToAcquireString"); //TODO: a proper exception.
if ( source.length > 0 )
dest[0 .. source.length] = source;
dest[source.length] = '\0';
}
real degreesToRadians(real deg)
{
return deg*PI/180;
}
struct RefCounted(alias pred, T)
if ( !is(T == class) && is(typeof(pred(cast(T*)null)) == T*) )
{
T* payload;
private bool isInitialized;
private size_t* refcount;
alias payload this;
this(T* payload)
{
this.payload = payload;
refcount = new size_t;
*refcount = 1;
isInitialized = true;
}
this(this)
{
if ( isInitialized )
(*refcount)++;
}
~this()
{
(*refcount)--;
if ( *refcount == 0 )
payload = pred(payload);
}
@property size_t refCount()
{
return *refcount;
}
}
unittest
{
int x = 10;
int y = 20;
alias RefCounted!( (int* t){ x = 20; return t; }, int ) IntRef;
auto a = IntRef(&x);
assert( a.refCount == 1 );
auto b = a;
assert( a.refCount == 2 );
b = IntRef(&y);
assert( a.refCount == 1 );
assert( b.refCount == 1 );
a = b;
assert( b.refCount == 2 );
assert( x == 20 );
}
|