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