3030extern (C++ ) struct Array (T)
3131{
3232 size_t length;
33+ alias opSlice this ;
3334
3435private :
3536 T[] data;
@@ -51,7 +52,11 @@ public:
5152
5253 ~this () pure nothrow
5354 {
54- debug (stomp) memset(data.ptr, 0xFF , data.length);
55+ debug (stomp)
56+ {
57+ if (data.ptr)
58+ memset(data.ptr, 0xFF , data.length * T.sizeof);
59+ }
5560 if (data.ptr && data.ptr != &smallarray[0 ])
5661 mem.xfree(data.ptr);
5762 }
@@ -60,10 +65,11 @@ public:
6065 // int, and c++ header generation doesn't accept wrapping this in static if
6166 extern (D ) this ()(T[] elems ... ) pure nothrow if (is (T == struct ) || is (T == class ))
6267 {
63- this (elems.length);
68+ this .reserve (elems.length);
69+ this .length = elems.length;
6470 foreach (i; 0 .. elems.length)
6571 {
66- this [i] = elems[i];
72+ this .data [i] = elems[i];
6773 }
6874 }
6975
@@ -72,50 +78,61 @@ public:
7278 {
7379 static const (char )[] toStringImpl (alias toStringFunc, Array)(Array* a, bool quoted = false )
7480 {
75- const (char )[][] buf = (cast (const (char )[]* )mem.xcalloc((char []).sizeof, a.length))[0 .. a.length];
76- size_t len = 2 ; // [ and ]
77- const seplen = quoted ? 3 : 1 ; // ',' or null terminator and optionally '"'
78- if (a.length == 0 )
79- len += 1 ; // null terminator
80- else
81+ const size_t n = a.length;
82+ if (n == 0 ) return " []" ;
83+
84+ const (char )[] nullStr = " null" ;
85+ const (char )[][] buf = (cast (const (char )[]* )mem.xcalloc((char []).sizeof, n))[0 .. n];
86+ size_t len = 2 ;
87+ foreach (u; 0 .. n)
8188 {
82- foreach (u; 0 .. a.length )
89+ static if ( is ( typeof (a.data[u] is null )) )
8390 {
84- static if (is ( typeof ( a.data[u] is null )) )
91+ if (a.data[u] is null )
8592 {
86- if (a.data[u] is null )
87- buf[u] = " null" ;
88- else
89- buf[u] = toStringFunc(a.data[u]);
93+ buf[u] = nullStr;
9094 }
9195 else
9296 {
9397 buf[u] = toStringFunc(a.data[u]);
9498 }
95-
96- len += buf[u].length + seplen;
9799 }
100+ else
101+ {
102+ buf[u] = toStringFunc(a.data[u]);
103+ }
104+
105+ len += buf[u].length;
106+ if (u > 0 ) len += 1 ;
107+ if (quoted) len += 2 ;
98108 }
99- char [] str = (cast (char * )mem.xmalloc_noscan(len))[0 .. len];
100109
101- str[0 ] = ' [' ;
102- char * p = str.ptr + 1 ;
103- foreach (u; 0 .. a.length)
110+ char * str = cast (char * )mem.xmalloc_noscan(len + 1 );
111+ char * p = str;
112+
113+ * p++ = ' [' ;
114+ foreach (u; 0 .. n)
104115 {
105- if (u)
116+ if (u > 0 )
106117 * p++ = ' ,' ;
118+
107119 if (quoted)
108120 * p++ = ' "' ;
109- memcpy(p, buf[u].ptr, buf[u].length);
110- p += buf[u].length;
121+
122+ if (buf[u].length)
123+ {
124+ memcpy(p, buf[u].ptr, buf[u].length);
125+ p += buf[u].length;
126+ }
127+
111128 if (quoted)
112129 * p++ = ' "' ;
113130 }
114131 * p++ = ' ]' ;
115132 * p = 0 ;
116- assert (p - str.ptr == str.length - 1 ); // null terminator
133+ assert (cast ( size_t )( p - str) == len);
117134 mem.xfree(buf.ptr);
118- return str[0 .. $ - 1 ];
135+ return str[0 .. len ];
119136 }
120137
121138 static if (is (typeof (T.init.toString())))
@@ -131,6 +148,7 @@ public:
131148 assert (0 );
132149 }
133150 }
151+
134152 // /ditto
135153 const (char )* toChars () const
136154 {
@@ -196,28 +214,38 @@ public:
196214 const allocdim = length + increment;
197215 debug (stomp)
198216 {
199- // always move using allocate-copy-stomp-free
200217 auto p = cast (T* )mem.xmalloc(allocdim * T.sizeof);
201218 memcpy(p, data.ptr, length * T.sizeof);
202219 memset(data.ptr, 0xFF , data.length * T.sizeof);
203220 mem.xfree(data.ptr);
221+ data = p[0 .. allocdim];
204222 }
205223 else
224+ {
206225 auto p = cast (T* )mem.xrealloc(data.ptr, allocdim * T.sizeof);
207- data = p[0 .. allocdim];
226+ data = p[0 .. allocdim];
227+ }
208228 }
209229
210230 debug (stomp)
211231 {
212- if (length < data.length)
213- memset(data.ptr + length, 0xFF , (data.length - length) * T.sizeof);
232+ if (data.ptr && data.ptr != &smallarray[0 ])
233+ {
234+ if (length < data.length)
235+ memset(data.ptr + length, 0xFF ,
236+ (data.length - length) * T.sizeof);
237+ }
214238 }
215- else
239+ else if (mem.isGCEnabled)
216240 {
217- if (mem.isGCEnabled)
241+ if (data.ptr && data.ptr != &smallarray[0 ])
242+ {
218243 if (length < data.length)
219- memset(data.ptr + length, 0xFF , (data.length - length) * T.sizeof);
244+ memset(data.ptr + length, 0xFF ,
245+ (data.length - length) * T.sizeof);
246+ }
220247 }
248+
221249 }
222250
223251 if (data.length - length < nentries) // false means hot path
0 commit comments