4 * Part of the D programming language runtime library.
5 * Dynamic array property support routines
9 * Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
10 * Written by Walter Bright
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, in both source and binary form, subject to the following
21 * o The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * o Altered source versions must be plainly marked as such, and must not
26 * be misrepresented as being the original software.
27 * o This notice may not be removed or altered from any source
32 * Modified by Sean Kelly for use with the D Runtime Project
37 //debug=adi; // uncomment to turn on debugging printf's
41 debug(adi) import core.stdc.stdio;
42 import core.stdc.string;
43 import core.stdc.stdlib;
48 FINALIZE = 0b0000_0001,
49 NO_SCAN = 0b0000_0010,
50 NO_MOVE = 0b0000_0100,
51 ALL_BITS = 0b1111_1111
54 extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
55 extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
56 extern (C) void gc_free( void* p );
66 /**********************************************
67 * Reverse array of chars.
68 * Handled separately because embedded multibyte encodings should not be
72 extern (C) long _adReverseChar(char[] a)
79 char* hi = &a[length - 1];
85 debug(adi) printf("lo = %d, hi = %d\n", lo, hi);
86 if (clo <= 0x7F && chi <= 0x7F)
88 debug(adi) printf("\tascii\n");
96 uint stridelo = UTF8stride[clo];
99 while ((chi & 0xC0) == 0x80)
108 debug(adi) printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
109 if (stridelo == stridehi)
112 memcpy(tmp.ptr, lo, stridelo);
113 memcpy(lo, hi, stridelo);
114 memcpy(hi, tmp.ptr, stridelo);
120 /* Shift the whole array. This is woefully inefficient
122 memcpy(tmp.ptr, hi, stridehi);
123 memcpy(tmplo.ptr, lo, stridelo);
124 memmove(lo + stridehi, lo + stridelo , (hi - lo) - stridelo);
125 memcpy(lo, tmp.ptr, stridehi);
126 memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
129 hi = hi - 1 + (stridehi - stridelo);
132 return *cast(long*)(&a);
139 auto r = a.dup.reverse;
143 a = "a\u1235\u1234c";
147 assert(r == "c\u1234\u1235a");
153 assert(r == "c\u1234ba");
155 a = "\u3026\u2021\u3061\n";
157 assert(r == "\n\u3061\u2021\u3026");
161 /**********************************************
162 * Reverse array of wchars.
163 * Handled separately because embedded multiword encodings should not be
167 extern (C) long _adReverseWchar(wchar[] a)
173 wchar* hi = &a[length - 1];
179 if ((clo < 0xD800 || clo > 0xDFFF) &&
180 (chi < 0xD800 || chi > 0xDFFF))
189 int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
192 if (chi >= 0xDC00 && chi <= 0xDFFF)
201 if (stridelo == stridehi)
204 assert(stridelo == 2);
205 assert(stmp.sizeof == 2 * (*lo).sizeof);
206 stmp = *cast(int*)lo;
207 *cast(int*)lo = *cast(int*)hi;
208 *cast(int*)hi = stmp;
214 /* Shift the whole array. This is woefully inefficient
216 memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
217 memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
218 memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
219 memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
222 hi = hi - 1 + (stridehi - stridelo);
225 return *cast(long*)(&a);
232 auto r = a.dup.reverse;
235 a = "a\U00012356\U00012346c";
237 assert(r == "c\U00012346\U00012356a");
241 assert(r == "c\U00012345ba");
245 /**********************************************
246 * Support for array.reverse property.
249 extern (C) long _adReverse(Array a, size_t szelem)
252 assert(result is *cast(long*)(&a));
262 void* hi = a.ptr + (a.length - 1) * szelem;
268 tmp = cast(byte*) alloca(szelem);
270 //tmp = gc_malloc(szelem);
273 for (; lo < hi; lo += szelem, hi -= szelem)
275 memcpy(tmp, lo, szelem);
276 memcpy(lo, hi, szelem);
277 memcpy(hi, tmp, szelem);
286 // BUG: bad code is generate for delete pointer, tries
291 return *cast(long*)(&a);
296 debug(adi) printf("array.reverse.unittest\n");
298 int[] a = new int[5];
302 for (i = 0; i < 5; i++)
306 for (i = 0; i < 5; i++)
307 assert(a[i] == 4 - i);
310 { // More than 16 bytes in size
315 X20[] c = new X20[5];
318 for (i = 0; i < 5; i++)
324 for (i = 0; i < 5; i++)
326 assert(c[i].a == 4 - i);
327 assert(c[i].e == 10);
331 /**********************************************
332 * Sort array of chars.
335 extern (C) long _adSortChar(char[] a)
339 dstring da = toUTF32(a);
342 foreach (dchar d; da)
344 auto t = toUTF8(buf, d);
345 a[i .. i + t.length] = t[];
350 return *cast(long*)(&a);
353 /**********************************************
354 * Sort array of wchars.
357 extern (C) long _adSortWchar(wchar[] a)
361 dstring da = toUTF32(a);
364 foreach (dchar d; da)
366 auto t = toUTF16(buf, d);
367 a[i .. i + t.length] = t[];
372 return *cast(long*)(&a);
375 /***************************************
376 * Support for array equality test.
382 extern (C) int _adEq(Array a1, Array a2, TypeInfo ti)
384 debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
385 if (a1.length != a2.length)
386 return 0; // not equal
387 auto sz = ti.tsize();
392 // We should really have a ti.isPOD() check for this
393 return (memcmp(p1, p2, a1.length) == 0);
395 for (size_t i = 0; i < a1.length; i++)
397 if (!ti.equals(p1 + i * sz, p2 + i * sz))
398 return 0; // not equal
403 extern (C) int _adEq2(Array a1, Array a2, TypeInfo ti)
405 debug(adi) printf("_adEq2(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
406 if (a1.length != a2.length)
407 return 0; // not equal
408 if (!ti.equals(&a1, &a2))
414 debug(adi) printf("array.Eq unittest\n");
419 assert(a != "helloo");
420 assert(a != "betty");
421 assert(a == "hello");
422 assert(a != "hxxxx");
425 /***************************************
426 * Support for array compare test.
429 extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti)
431 debug(adi) printf("adCmp()\n");
432 auto len = a1.length;
435 auto sz = ti.tsize();
440 { // We should really have a ti.isPOD() check for this
441 auto c = memcmp(p1, p2, len);
447 for (size_t i = 0; i < len; i++)
449 auto c = ti.compare(p1 + i * sz, p2 + i * sz);
454 if (a1.length == a2.length)
456 return (a1.length > a2.length) ? 1 : -1;
459 extern (C) int _adCmp2(Array a1, Array a2, TypeInfo ti)
461 debug(adi) printf("_adCmp2(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
462 return ti.compare(&a1, &a2);
466 debug(adi) printf("array.Cmp unittest\n");
472 assert(a < "helloo");
473 assert(a <= "helloo");
475 assert(a >= "betty");
476 assert(a == "hello");
477 assert(a <= "hello");
478 assert(a >= "hello");
481 /***************************************
482 * Support for array compare test.
485 extern (C) int _adCmpChar(Array a1, Array a2)
495 mov ESI,a1+4[4+ESP] ;
496 mov EDI,a2+4[4+ESP] ;
510 // Do alignment if neither is dword aligned
517 mov AL,[ESI] ; //align ESI to dword bounds
533 // do multiple of 4 bytes at a time
546 // if still equal and not end of string, do up to 3 bytes slightly
599 debug(adi) printf("adCmpChar()\n");
603 c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
605 c = cast(int)a1.length - cast(int)a2.length;
612 debug(adi) printf("array.CmpChar unittest\n");
618 assert(a < "helloo");
619 assert(a <= "helloo");
621 assert(a >= "betty");
622 assert(a == "hello");
623 assert(a <= "hello");
624 assert(a >= "hello");