]> git.llucax.com Git - software/druntime.git/blob - src/compiler/dmd/arrayassign.d
Added "invariant" module to fix link issues because DMD generates references to an...
[software/druntime.git] / src / compiler / dmd / arrayassign.d
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 }