d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
[official-gcc.git] / libphobos / libdruntime / core / internal / qsort.d
blobad8307a2523802973ef98305ef2395131e7dd203
1 /**
2 * This is a public domain version of qsort.d. All it does is call C's
3 * qsort().
5 * Copyright: Copyright Digital Mars 2000 - 2010.
6 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
7 * Authors: Walter Bright, Martin Nowak
8 */
9 module core.internal.qsort;
11 //debug=qsort;
13 import core.stdc.stdlib;
15 version (OSX)
16 version = Darwin;
17 else version (iOS)
18 version = Darwin;
19 else version (TVOS)
20 version = Darwin;
21 else version (WatchOS)
22 version = Darwin;
24 // qsort_r was added in glibc in 2.8. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88127
25 version (CRuntime_Glibc)
27 version (GNU)
29 import gcc.config : Have_Qsort_R;
30 enum Glibc_Qsort_R = Have_Qsort_R;
32 else
34 enum Glibc_Qsort_R = true;
37 else
39 enum Glibc_Qsort_R = false;
42 static if (Glibc_Qsort_R)
44 alias extern (C) int function(scope const void *, scope const void *, scope void *) Cmp;
45 extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, Cmp cmp, scope void *arg);
47 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
49 extern (C) int cmp(scope const void* p1, scope const void* p2, scope void* ti)
51 return (cast(TypeInfo)ti).compare(p1, p2);
53 qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);
54 return a;
57 else version (FreeBSD)
59 alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;
60 extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);
62 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
64 extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)
66 return (cast(TypeInfo)ti).compare(p1, p2);
68 qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);
69 return a;
72 else version (DragonFlyBSD)
74 alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;
75 extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);
77 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
79 extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)
81 return (cast(TypeInfo)ti).compare(p1, p2);
83 qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);
84 return a;
87 else version (Darwin)
89 alias extern (C) int function(scope void *, scope const void *, scope const void *) Cmp;
90 extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, scope void *thunk, Cmp cmp);
92 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
94 extern (C) int cmp(scope void* ti, scope const void* p1, scope const void* p2)
96 return (cast(TypeInfo)ti).compare(p1, p2);
98 qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);
99 return a;
102 else version (CRuntime_UClibc)
104 alias extern (C) int function(scope const void *, scope const void *, scope void *) __compar_d_fn_t;
105 extern (C) void qsort_r(scope void *base, size_t nmemb, size_t size, __compar_d_fn_t cmp, scope void *arg);
107 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
109 extern (C) int cmp(scope const void* p1, scope const void* p2, scope void* ti)
111 return (cast(TypeInfo)ti).compare(p1, p2);
113 qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);
114 return a;
117 else
119 private TypeInfo tiglobal;
121 extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
123 extern (C) int cmp(scope const void* p1, scope const void* p2)
125 return tiglobal.compare(p1, p2);
127 tiglobal = ti;
128 qsort(a.ptr, a.length, ti.tsize, &cmp);
129 return a;
133 unittest
135 debug(qsort) printf("array.sort.unittest()\n");
137 int[] a = new int[10];
139 a[0] = 23;
140 a[1] = 1;
141 a[2] = 64;
142 a[3] = 5;
143 a[4] = 6;
144 a[5] = 5;
145 a[6] = 17;
146 a[7] = 3;
147 a[8] = 0;
148 a[9] = -1;
150 _adSort(*cast(void[]*)&a, typeid(a[0]));
152 for (int i = 0; i < a.length - 1; i++)
154 //printf("i = %d", i);
155 //printf(" %d %d\n", a[i], a[i + 1]);
156 assert(a[i] <= a[i + 1]);
160 unittest
162 debug(qsort) printf("struct.sort.unittest()\n");
164 static struct TestStruct
166 int value;
168 int opCmp(const TestStruct rhs) const
170 return value <= rhs.value ?
171 value < rhs.value ? -1 : 0 : 1;
175 TestStruct[] a = new TestStruct[10];
177 a[0] = TestStruct(23);
178 a[1] = TestStruct(1);
179 a[2] = TestStruct(64);
180 a[3] = TestStruct(5);
181 a[4] = TestStruct(6);
182 a[5] = TestStruct(5);
183 a[6] = TestStruct(17);
184 a[7] = TestStruct(3);
185 a[8] = TestStruct(0);
186 a[9] = TestStruct(-1);
188 _adSort(*cast(void[]*)&a, typeid(TestStruct));
190 for (int i = 0; i < a.length - 1; i++)
192 //printf("i = %d", i);
193 //printf(" %d %d\n", a[i], a[i + 1]);
194 assert(a[i] <= a[i + 1]);