Mercurial > projects > ldc
comparison druntime/src/compiler/dmd/arrayassign.d @ 759:d3eb054172f9
Added copy of druntime from DMD 2.020 modified for LDC.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 11 Nov 2008 01:52:37 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
758:f04dde6e882c | 759:d3eb054172f9 |
---|---|
1 /** | |
2 * Part of the D programming language runtime library. | |
3 * http://www.digitalmars.com | |
4 * Written by Walter Bright | |
5 * Placed in the Public Domain | |
6 */ | |
7 module rt.arrayassign; | |
8 | |
9 private | |
10 { | |
11 import util.string; | |
12 import stdc.string; | |
13 import stdc.stdlib; | |
14 debug(PRINTF) import stdc.stdio; | |
15 } | |
16 | |
17 /** | |
18 * Does array assignment (not construction) from another | |
19 * array of the same element type. | |
20 * ti is the element type. | |
21 * Handles overlapping copies. | |
22 */ | |
23 extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) | |
24 { | |
25 debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); | |
26 | |
27 if (to.length != from.length) | |
28 { | |
29 char[10] tmp = void; | |
30 string msg = "lengths don't match for array copy,"c; | |
31 msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); | |
32 throw new Exception(msg); | |
33 } | |
34 | |
35 auto element_size = ti.tsize(); | |
36 | |
37 /* Need a temporary buffer tmp[] big enough to hold one element | |
38 */ | |
39 void[16] buf = void; | |
40 void[] tmp; | |
41 if (element_size > buf.sizeof) | |
42 tmp = alloca(element_size)[0 .. element_size]; | |
43 else | |
44 tmp = buf; | |
45 | |
46 | |
47 if (to.ptr <= from.ptr) | |
48 { | |
49 foreach (i; 0 .. to.length) | |
50 { | |
51 void* pto = to.ptr + i * element_size; | |
52 void* pfrom = from.ptr + i * element_size; | |
53 memcpy(tmp.ptr, pto, element_size); | |
54 memcpy(pto, pfrom, element_size); | |
55 ti.postblit(pto); | |
56 ti.destroy(tmp.ptr); | |
57 } | |
58 } | |
59 else | |
60 { | |
61 for (int i = to.length; i--; ) | |
62 { | |
63 void* pto = to.ptr + i * element_size; | |
64 void* pfrom = from.ptr + i * element_size; | |
65 memcpy(tmp.ptr, pto, element_size); | |
66 memcpy(pto, pfrom, element_size); | |
67 ti.postblit(pto); | |
68 ti.destroy(tmp.ptr); | |
69 } | |
70 } | |
71 return to; | |
72 } | |
73 | |
74 /** | |
75 * Does array initialization (not assignment) from another | |
76 * array of the same element type. | |
77 * ti is the element type. | |
78 */ | |
79 extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) | |
80 { | |
81 debug(PRINTF) printf("_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); | |
82 | |
83 if (to.length != from.length) | |
84 { | |
85 char[10] tmp = void; | |
86 string msg = "lengths don't match for array initialization,"c; | |
87 msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); | |
88 throw new Exception(msg); | |
89 } | |
90 | |
91 auto element_size = ti.tsize(); | |
92 | |
93 int i; | |
94 try | |
95 { | |
96 for (i = 0; i < to.length; i++) | |
97 { | |
98 // Copy construction is defined as bit copy followed by postblit. | |
99 memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size); | |
100 ti.postblit(to.ptr + i * element_size); | |
101 } | |
102 } | |
103 catch (Object o) | |
104 { | |
105 /* Destroy, in reverse order, what we've constructed so far | |
106 */ | |
107 while (i--) | |
108 { | |
109 ti.destroy(to.ptr + i * element_size); | |
110 } | |
111 | |
112 throw o; | |
113 } | |
114 return to; | |
115 } | |
116 | |
117 | |
118 /** | |
119 * Do assignment to an array. | |
120 * p[0 .. count] = value; | |
121 */ | |
122 extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti) | |
123 { | |
124 void* pstart = p; | |
125 | |
126 auto element_size = ti.tsize(); | |
127 | |
128 //Need a temporary buffer tmp[] big enough to hold one element | |
129 void[16] buf = void; | |
130 void[] tmp; | |
131 if (element_size > buf.sizeof) | |
132 { | |
133 tmp = alloca(element_size)[0 .. element_size]; | |
134 } | |
135 else | |
136 tmp = buf; | |
137 | |
138 foreach (i; 0 .. count) | |
139 { | |
140 memcpy(tmp.ptr, p, element_size); | |
141 memcpy(p, value, element_size); | |
142 ti.postblit(p); | |
143 ti.destroy(tmp.ptr); | |
144 p += element_size; | |
145 } | |
146 return pstart; | |
147 } | |
148 | |
149 /** | |
150 * Do construction of an array. | |
151 * ti[count] p = value; | |
152 */ | |
153 extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti) | |
154 { | |
155 void* pstart = p; | |
156 auto element_size = ti.tsize(); | |
157 | |
158 try | |
159 { | |
160 foreach (i; 0 .. count) | |
161 { | |
162 // Copy construction is defined as bit copy followed by postblit. | |
163 memcpy(p, value, element_size); | |
164 ti.postblit(p); | |
165 p += element_size; | |
166 } | |
167 } | |
168 catch (Object o) | |
169 { | |
170 // Destroy, in reverse order, what we've constructed so far | |
171 while (p > pstart) | |
172 { | |
173 p -= element_size; | |
174 ti.destroy(p); | |
175 } | |
176 | |
177 throw o; | |
178 } | |
179 return pstart; | |
180 } |