/* Test of stable-sorting of an array using mergesort.
Copyright (C) 2009-2024 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see . */
#include
#include
struct foo { double x; double index; };
#define ELEMENT struct foo
#define COMPARE(a,b) ((a)->x < (b)->x ? -1 : (a)->x > (b)->x ? 1 : 0)
#define STATIC static
#include "array-mergesort.h"
#include
#include "macros.h"
#define NMAX 257
static const struct foo data[NMAX] =
{
{ 2, 0 },
{ 28, 1 },
{ 36, 2 },
{ 43, 3 },
{ 20, 4 },
{ 37, 5 },
{ 19, 6 },
{ 37, 7 },
{ 30, 8 },
{ 18, 9 },
{ 30, 10 },
{ 49, 11 },
{ 16, 12 },
{ 22, 13 },
{ 23, 14 },
{ 3, 15 },
{ 39, 16 },
{ 48, 17 },
{ 18, 18 },
{ 18, 19 },
{ 45, 20 },
{ 39, 21 },
{ 1, 22 },
{ 44, 23 },
{ 24, 24 },
{ 21, 25 },
{ 29, 26 },
{ 3, 27 },
{ 34, 28 },
{ 15, 29 },
{ 39, 30 },
{ 11, 31 },
{ 29, 32 },
{ 27, 33 },
{ 43, 34 },
{ 31, 35 },
{ 28, 36 },
{ 12, 37 },
{ 16, 38 },
{ 34, 39 },
{ 25, 40 },
{ 31, 41 },
{ 29, 42 },
{ 36, 43 },
{ 17, 44 },
{ 18, 45 },
{ 44, 46 },
{ 22, 47 },
{ 23, 48 },
{ 32, 49 },
{ 16, 50 },
{ 47, 51 },
{ 28, 52 },
{ 46, 53 },
{ 49, 54 },
{ 24, 55 },
{ 0, 56 },
{ 20, 57 },
{ 25, 58 },
{ 42, 59 },
{ 48, 60 },
{ 16, 61 },
{ 26, 62 },
{ 32, 63 },
{ 24, 64 },
{ 17, 65 },
{ 47, 66 },
{ 47, 67 },
{ 12, 68 },
{ 33, 69 },
{ 41, 70 },
{ 36, 71 },
{ 8, 72 },
{ 15, 73 },
{ 0, 74 },
{ 32, 75 },
{ 28, 76 },
{ 11, 77 },
{ 46, 78 },
{ 34, 79 },
{ 5, 80 },
{ 20, 81 },
{ 47, 82 },
{ 25, 83 },
{ 7, 84 },
{ 29, 85 },
{ 40, 86 },
{ 5, 87 },
{ 12, 88 },
{ 30, 89 },
{ 1, 90 },
{ 22, 91 },
{ 29, 92 },
{ 42, 93 },
{ 49, 94 },
{ 30, 95 },
{ 40, 96 },
{ 33, 97 },
{ 36, 98 },
{ 12, 99 },
{ 8, 100 },
{ 33, 101 },
{ 5, 102 },
{ 31, 103 },
{ 27, 104 },
{ 19, 105 },
{ 43, 106 },
{ 37, 107 },
{ 9, 108 },
{ 40, 109 },
{ 0, 110 },
{ 35, 111 },
{ 32, 112 },
{ 6, 113 },
{ 27, 114 },
{ 28, 115 },
{ 30, 116 },
{ 37, 117 },
{ 32, 118 },
{ 41, 119 },
{ 14, 120 },
{ 44, 121 },
{ 22, 122 },
{ 26, 123 },
{ 2, 124 },
{ 43, 125 },
{ 20, 126 },
{ 32, 127 },
{ 24, 128 },
{ 33, 129 },
{ 7, 130 },
{ 17, 131 },
{ 10, 132 },
{ 47, 133 },
{ 14, 134 },
{ 29, 135 },
{ 19, 136 },
{ 25, 137 },
{ 25, 138 },
{ 13, 139 },
{ 25, 140 },
{ 32, 141 },
{ 8, 142 },
{ 37, 143 },
{ 31, 144 },
{ 32, 145 },
{ 5, 146 },
{ 45, 147 },
{ 35, 148 },
{ 47, 149 },
{ 3, 150 },
{ 4, 151 },
{ 37, 152 },
{ 43, 153 },
{ 39, 154 },
{ 18, 155 },
{ 13, 156 },
{ 15, 157 },
{ 41, 158 },
{ 34, 159 },
{ 4, 160 },
{ 33, 161 },
{ 20, 162 },
{ 4, 163 },
{ 38, 164 },
{ 47, 165 },
{ 30, 166 },
{ 41, 167 },
{ 23, 168 },
{ 40, 169 },
{ 23, 170 },
{ 35, 171 },
{ 47, 172 },
{ 32, 173 },
{ 15, 174 },
{ 15, 175 },
{ 41, 176 },
{ 35, 177 },
{ 6, 178 },
{ 18, 179 },
{ 35, 180 },
{ 39, 181 },
{ 34, 182 },
{ 6, 183 },
{ 34, 184 },
{ 37, 185 },
{ 15, 186 },
{ 6, 187 },
{ 12, 188 },
{ 39, 189 },
{ 9, 190 },
{ 48, 191 },
{ 37, 192 },
{ 28, 193 },
{ 32, 194 },
{ 1, 195 },
{ 45, 196 },
{ 21, 197 },
{ 11, 198 },
{ 32, 199 },
{ 43, 200 },
{ 35, 201 },
{ 25, 202 },
{ 4, 203 },
{ 20, 204 },
{ 10, 205 },
{ 22, 206 },
{ 44, 207 },
{ 30, 208 },
{ 16, 209 },
{ 42, 210 },
{ 13, 211 },
{ 29, 212 },
{ 23, 213 },
{ 30, 214 },
{ 25, 215 },
{ 49, 216 },
{ 0, 217 },
{ 49, 218 },
{ 29, 219 },
{ 37, 220 },
{ 6, 221 },
{ 27, 222 },
{ 31, 223 },
{ 17, 224 },
{ 45, 225 },
{ 25, 226 },
{ 15, 227 },
{ 34, 228 },
{ 7, 229 },
{ 7, 230 },
{ 4, 231 },
{ 31, 232 },
{ 40, 233 },
{ 17, 234 },
{ 2, 235 },
{ 34, 236 },
{ 17, 237 },
{ 25, 238 },
{ 5, 239 },
{ 48, 240 },
{ 31, 241 },
{ 41, 242 },
{ 45, 243 },
{ 33, 244 },
{ 46, 245 },
{ 19, 246 },
{ 17, 247 },
{ 38, 248 },
{ 43, 249 },
{ 16, 250 },
{ 5, 251 },
{ 21, 252 },
{ 0, 253 },
{ 47, 254 },
{ 40, 255 },
{ 22, 256 }
};
static int
cmp_double (const void *a, const void *b)
{
return (*(const double *)a < *(const double *)b ? -1 :
*(const double *)a > *(const double *)b ? 1 :
0);
}
int
main ()
{
size_t n;
/* Test merge_sort_fromto. */
for (n = 1; n <= NMAX; n++)
{
struct foo *dst;
struct foo *tmp;
double *qsort_result;
size_t i;
dst = (struct foo *) malloc ((n + 1) * sizeof (struct foo));
dst[n].x = 0x4A6A71FE; /* canary */
tmp = (struct foo *) malloc ((n / 2 + 1) * sizeof (struct foo));
tmp[n / 2].x = 0x587EF149; /* canary */
merge_sort_fromto (data, dst, n, tmp);
/* Verify the canaries. */
ASSERT (dst[n].x == 0x4A6A71FE);
ASSERT (tmp[n / 2].x == 0x587EF149);
/* Verify the result. */
qsort_result = (double *) malloc (n * sizeof (double));
for (i = 0; i < n; i++)
qsort_result[i] = data[i].x;
qsort (qsort_result, n, sizeof (double), cmp_double);
for (i = 0; i < n; i++)
ASSERT (dst[i].x == qsort_result[i]);
/* Verify the stability. */
for (i = 0; i < n; i++)
if (i > 0 && dst[i - 1].x == dst[i].x)
ASSERT (dst[i - 1].index < dst[i].index);
free (qsort_result);
free (tmp);
free (dst);
}
/* Test merge_sort_inplace. */
for (n = 1; n <= NMAX; n++)
{
struct foo *src;
struct foo *tmp;
double *qsort_result;
size_t i;
src = (struct foo *) malloc ((n + 1) * sizeof (struct foo));
src[n].x = 0x4A6A71FE; /* canary */
tmp = (struct foo *) malloc ((n + 1) * sizeof (struct foo));
tmp[n].x = 0x587EF149; /* canary */
for (i = 0; i < n; i++)
src[i] = data[i];
merge_sort_inplace (src, n, tmp);
/* Verify the canaries. */
ASSERT (src[n].x == 0x4A6A71FE);
ASSERT (tmp[n].x == 0x587EF149);
/* Verify the result. */
qsort_result = (double *) malloc (n * sizeof (double));
for (i = 0; i < n; i++)
qsort_result[i] = data[i].x;
qsort (qsort_result, n, sizeof (double), cmp_double);
for (i = 0; i < n; i++)
ASSERT (src[i].x == qsort_result[i]);
/* Verify the stability. */
for (i = 0; i < n; i++)
if (i > 0 && src[i - 1].x == src[i].x)
ASSERT (src[i - 1].index < src[i].index);
free (qsort_result);
free (tmp);
free (src);
}
return test_exit_status;
}