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 }