sort.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright (C) 2004-2020 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  18. ******************************************************************************/
  19. /******************************************************************************
  20. * T I N T I N + + *
  21. * *
  22. * coded by Igor van den Hoven 2020 *
  23. ******************************************************************************/
  24. #include "tintin.h"
  25. #include <assert.h>
  26. //typedef int CMPFUNC (const void *a, const void *b);
  27. void quad_sort32(int *array, int *swap, size_t nmemb, size_t block, CMPFUNC *cmp);
  28. void quad_swap32(int *array, int *swap, size_t nmemb, CMPFUNC *cmp)
  29. {
  30. size_t offset;
  31. register unsigned char loop;
  32. register int *pta, *pts, *ptt, tmp;
  33. pta = array;
  34. for (offset = 0 ; offset + 4 <= nmemb ; offset += 4)
  35. {
  36. if (cmp(&pta[0], &pta[1]) > 0)
  37. {
  38. tmp = pta[0];
  39. pta[0] = pta[1];
  40. pta[1] = tmp;
  41. }
  42. if (cmp(&pta[2], &pta[3]) > 0)
  43. {
  44. tmp = pta[2];
  45. pta[2] = pta[3];
  46. pta[3] = tmp;
  47. }
  48. if (cmp(&pta[1], &pta[2]) > 0)
  49. {
  50. if (cmp(&pta[0], &pta[3]) > 0)
  51. {
  52. tmp = pta[0];
  53. pta[0] = pta[2];
  54. pta[2] = tmp;
  55. tmp = pta[1];
  56. pta[1] = pta[3];
  57. pta[3] = tmp;
  58. }
  59. else if (cmp(&pta[0], &pta[2]) <= 0)
  60. {
  61. if (cmp(&pta[1], &pta[3]) <= 0)
  62. {
  63. tmp = pta[1];
  64. pta[1] = pta[2];
  65. pta[2] = tmp;
  66. }
  67. else
  68. {
  69. tmp = pta[1];
  70. pta[1] = pta[2];
  71. pta[2] = pta[3];
  72. pta[3] = tmp;
  73. }
  74. }
  75. else
  76. {
  77. if (cmp(&pta[1], &pta[3]) <= 0)
  78. {
  79. tmp = pta[0];
  80. pta[0] = pta[2];
  81. pta[2] = pta[1];
  82. pta[1] = tmp;
  83. }
  84. else
  85. {
  86. tmp = pta[0];
  87. pta[0] = pta[2];
  88. pta[2] = pta[3];
  89. pta[3] = pta[1];
  90. pta[1] = tmp;
  91. }
  92. }
  93. }
  94. pta += 4;
  95. }
  96. switch (nmemb - offset)
  97. {
  98. case 0:
  99. case 1:
  100. break;
  101. case 2:
  102. if (cmp(&pta[0], &pta[1]) > 0)
  103. {
  104. tmp = pta[0];
  105. pta[0] = pta[1];
  106. pta[1] = tmp;
  107. }
  108. break;
  109. case 3:
  110. if (cmp(&pta[0], &pta[1]) > 0)
  111. {
  112. tmp = pta[0];
  113. pta[0] = pta[1];
  114. pta[1] = tmp;
  115. }
  116. if (cmp(&pta[1], &pta[2]) > 0)
  117. {
  118. tmp = pta[1];
  119. pta[1] = pta[2];
  120. pta[2] = tmp;
  121. }
  122. if (cmp(&pta[0], &pta[1]) > 0)
  123. {
  124. tmp = pta[0];
  125. pta[0] = pta[1];
  126. pta[1] = tmp;
  127. }
  128. break;
  129. default:
  130. assert(nmemb - offset > 3);
  131. }
  132. pta = array;
  133. for (offset = 0 ; offset + 16 <= nmemb ; offset += 16)
  134. {
  135. if (cmp(&pta[3], &pta[4]) <= 0)
  136. {
  137. if (cmp(&pta[11], &pta[12]) <= 0)
  138. {
  139. if (cmp(&pta[7], &pta[8]) <= 0)
  140. {
  141. pta += 16;
  142. continue;
  143. }
  144. pts = swap;
  145. for (loop = 0 ; loop < 16 ; loop++)
  146. *pts++ = *pta++;
  147. goto step3;
  148. }
  149. pts = swap;
  150. for (loop = 0 ; loop < 8 ; loop++)
  151. *pts++ = *pta++;
  152. goto step2;
  153. }
  154. // step1:
  155. pts = swap;
  156. if (cmp(&pta[3], &pta[7]) <= 0)
  157. {
  158. ptt = pta + 4;
  159. for (loop = 0 ; loop < 5 ; loop++)
  160. if (cmp(pta, ptt) > 0)
  161. *pts++ = *ptt++;
  162. else
  163. *pts++ = *pta++;
  164. while (pta < array + offset + 4)
  165. {
  166. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  167. }
  168. while (ptt < array + offset + 8)
  169. {
  170. *pts++ = *ptt++;
  171. }
  172. pta = ptt;
  173. }
  174. else if (cmp(&pta[0], &pta[7]) > 0)
  175. {
  176. if (cmp(&pta[8], &pta[15]) > 0)
  177. {
  178. if (cmp(&pta[4], &pta[11]) > 0)
  179. {
  180. tmp = pta[0]; pta[0] = pta[12]; pta[12] = tmp;
  181. tmp = pta[1]; pta[1] = pta[13]; pta[13] = tmp;
  182. tmp = pta[2]; pta[2] = pta[14]; pta[14] = tmp;
  183. tmp = pta[3]; pta[3] = pta[15]; pta[15] = tmp;
  184. tmp = pta[4]; pta[4] = pta[8]; pta[8] = tmp;
  185. tmp = pta[5]; pta[5] = pta[9]; pta[9] = tmp;
  186. tmp = pta[6]; pta[6] = pta[10]; pta[10] = tmp;
  187. tmp = pta[7]; pta[7] = pta[11]; pta[11] = tmp;
  188. pta += 16;
  189. continue;
  190. }
  191. pta += 4;
  192. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  193. pta -= 8;
  194. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  195. pta += 8;
  196. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  197. pta -= 8;
  198. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  199. pta += 4;
  200. goto step3;
  201. }
  202. pta += 4;
  203. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  204. pta -= 8;
  205. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  206. pta += 4;
  207. }
  208. else
  209. {
  210. ptt = pta + 4;
  211. for (loop = 0 ; loop < 5 ; loop++)
  212. if (cmp(pta, ptt) > 0)
  213. *pts++ = *ptt++;
  214. else
  215. *pts++ = *pta++;
  216. while (ptt < array + offset + 8)
  217. {
  218. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  219. }
  220. while (pta < array + offset + 4)
  221. {
  222. *pts++ = *pta++;
  223. }
  224. pta = ptt;
  225. }
  226. step2:
  227. if (cmp(&pta[3], &pta[7]) <= 0)
  228. {
  229. ptt = pta + 4;
  230. for (loop = 0 ; loop < 4 ; loop++)
  231. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  232. while (pta < array + offset + 12)
  233. {
  234. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  235. }
  236. while (ptt < array + offset + 16)
  237. {
  238. *pts++ = *ptt++;
  239. }
  240. }
  241. else if (cmp(&pta[0], &pta[7]) > 0)
  242. {
  243. pta += 4;
  244. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  245. pta -= 8;
  246. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  247. }
  248. else
  249. {
  250. ptt = pta + 4;
  251. for (loop = 0 ; loop < 5 ; loop++)
  252. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  253. while (ptt < array + offset + 16)
  254. {
  255. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  256. }
  257. while (pta < array + offset + 12)
  258. {
  259. *pts++ = *pta++;
  260. }
  261. }
  262. step3:
  263. pta = array + offset;
  264. pts = swap;
  265. if (cmp(&pts[7], &pts[15]) <= 0)
  266. {
  267. ptt = pts + 8;
  268. for (loop = 0 ; loop < 8 ; loop++)
  269. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  270. while (pts < swap + 8)
  271. {
  272. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  273. }
  274. while (ptt < swap + 16)
  275. {
  276. *pta++ = *ptt++;
  277. }
  278. }
  279. else if (cmp(&pts[0], &pts[15]) > 0)
  280. {
  281. pts += 8;
  282. for (loop = 0 ; loop < 8 ; loop++)
  283. *pta++ = *pts++;
  284. pts -= 16;
  285. for (loop = 0 ; loop < 8 ; loop++)
  286. *pta++ = *pts++;
  287. }
  288. else
  289. {
  290. ptt = pts + 8;
  291. for (loop = 0 ; loop < 9 ; loop++)
  292. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  293. while (ptt < swap + 16)
  294. {
  295. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  296. }
  297. while (pts < swap + 8)
  298. {
  299. *pta++ = *pts++;
  300. }
  301. }
  302. }
  303. switch (nmemb - offset)
  304. {
  305. case 0:
  306. case 1:
  307. case 2:
  308. case 3:
  309. case 4:
  310. return;
  311. default:
  312. quad_sort32(pta, swap, nmemb - offset, 4, cmp);
  313. }
  314. }
  315. void quad_sort64(long long *array, long long *swap, size_t nmemb, size_t block, CMPFUNC *cmp);
  316. void quad_swap64(long long *array, long long *swap, size_t nmemb, CMPFUNC *cmp)
  317. {
  318. size_t offset;
  319. register long long *pta, *pts, *ptt, tmp;
  320. pta = array;
  321. for (offset = 0 ; offset + 4 <= nmemb ; offset += 4)
  322. {
  323. if (cmp(&pta[0], &pta[1]) > 0)
  324. {
  325. tmp = pta[0];
  326. pta[0] = pta[1];
  327. pta[1] = tmp;
  328. }
  329. if (cmp(&pta[2], &pta[3]) > 0)
  330. {
  331. tmp = pta[2];
  332. pta[2] = pta[3];
  333. pta[3] = tmp;
  334. }
  335. if (cmp(&pta[1], &pta[2]) > 0)
  336. {
  337. if (cmp(&pta[0], &pta[3]) > 0)
  338. {
  339. tmp = pta[0];
  340. pta[0] = pta[2];
  341. pta[2] = tmp;
  342. tmp = pta[1];
  343. pta[1] = pta[3];
  344. pta[3] = tmp;
  345. }
  346. else if (cmp(&pta[0], &pta[2]) <= 0)
  347. {
  348. if (cmp(&pta[1], &pta[3]) <= 0)
  349. {
  350. tmp = pta[1];
  351. pta[1] = pta[2];
  352. pta[2] = tmp;
  353. }
  354. else
  355. {
  356. tmp = pta[1];
  357. pta[1] = pta[2];
  358. pta[2] = pta[3];
  359. pta[3] = tmp;
  360. }
  361. }
  362. else
  363. {
  364. if (cmp(&pta[1], &pta[3]) <= 0)
  365. {
  366. tmp = pta[0];
  367. pta[0] = pta[2];
  368. pta[2] = pta[1];
  369. pta[1] = tmp;
  370. }
  371. else
  372. {
  373. tmp = pta[0];
  374. pta[0] = pta[2];
  375. pta[2] = pta[3];
  376. pta[3] = pta[1];
  377. pta[1] = tmp;
  378. }
  379. }
  380. }
  381. pta += 4;
  382. }
  383. switch (nmemb - offset)
  384. {
  385. case 0:
  386. case 1:
  387. break;
  388. case 2:
  389. if (cmp(&pta[0], &pta[1]) > 0)
  390. {
  391. tmp = pta[0];
  392. pta[0] = pta[1];
  393. pta[1] = tmp;
  394. }
  395. break;
  396. case 3:
  397. if (cmp(&pta[0], &pta[1]) > 0)
  398. {
  399. tmp = pta[0];
  400. pta[0] = pta[1];
  401. pta[1] = tmp;
  402. }
  403. if (cmp(&pta[1], &pta[2]) > 0)
  404. {
  405. tmp = pta[1];
  406. pta[1] = pta[2];
  407. pta[2] = tmp;
  408. }
  409. if (cmp(&pta[0], &pta[1]) > 0)
  410. {
  411. tmp = pta[0];
  412. pta[0] = pta[1];
  413. pta[1] = tmp;
  414. }
  415. break;
  416. default:
  417. assert(nmemb - offset > 3);
  418. }
  419. pta = array;
  420. for (offset = 0 ; offset + 16 <= nmemb ; offset += 16)
  421. {
  422. if (cmp(&pta[3], &pta[4]) <= 0)
  423. {
  424. if (cmp(&pta[11], &pta[12]) <= 0)
  425. {
  426. if (cmp(&pta[7], &pta[8]) <= 0)
  427. {
  428. pta += 16;
  429. continue;
  430. }
  431. pts = swap;
  432. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  433. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  434. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  435. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  436. goto step3;
  437. }
  438. pts = swap;
  439. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  440. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  441. goto step2;
  442. }
  443. // step1:
  444. pts = swap;
  445. if (cmp(&pta[3], &pta[7]) <= 0)
  446. {
  447. ptt = pta + 4;
  448. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  449. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  450. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  451. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  452. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  453. while (pta < array + offset + 4)
  454. {
  455. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  456. }
  457. while (ptt < array + offset + 8)
  458. {
  459. *pts++ = *ptt++;
  460. }
  461. pta = ptt;
  462. }
  463. else if (cmp(&pta[0], &pta[7]) > 0)
  464. {
  465. if (cmp(&pta[8], &pta[15]) > 0)
  466. {
  467. if (cmp(&pta[4], &pta[11]) > 0)
  468. {
  469. tmp = pta[0]; pta[0] = pta[12]; pta[12] = tmp;
  470. tmp = pta[1]; pta[1] = pta[13]; pta[13] = tmp;
  471. tmp = pta[2]; pta[2] = pta[14]; pta[14] = tmp;
  472. tmp = pta[3]; pta[3] = pta[15]; pta[15] = tmp;
  473. tmp = pta[4]; pta[4] = pta[8]; pta[8] = tmp;
  474. tmp = pta[5]; pta[5] = pta[9]; pta[9] = tmp;
  475. tmp = pta[6]; pta[6] = pta[10]; pta[10] = tmp;
  476. tmp = pta[7]; pta[7] = pta[11]; pta[11] = tmp;
  477. pta += 16;
  478. continue;
  479. }
  480. pta += 4;
  481. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  482. pta -= 8;
  483. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  484. pta += 8;
  485. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  486. pta -= 8;
  487. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  488. pta += 4;
  489. goto step3;
  490. }
  491. pta += 4;
  492. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  493. pta -= 8;
  494. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  495. pta += 4;
  496. }
  497. else
  498. {
  499. ptt = pta + 4;
  500. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  501. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  502. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  503. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  504. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  505. while (ptt < array + offset + 8)
  506. {
  507. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  508. }
  509. while (pta < array + offset + 4)
  510. {
  511. *pts++ = *pta++;
  512. }
  513. pta = ptt;
  514. }
  515. step2:
  516. if (cmp(&pta[3], &pta[7]) <= 0)
  517. {
  518. ptt = pta + 4;
  519. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  520. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  521. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  522. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  523. // *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  524. while (pta < array + offset + 12)
  525. {
  526. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  527. }
  528. while (ptt < array + offset + 16)
  529. {
  530. *pts++ = *ptt++;
  531. }
  532. }
  533. else if (cmp(&pta[0], &pta[7]) > 0)
  534. {
  535. pta += 4;
  536. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  537. pta -= 8;
  538. *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++; *pts++ = *pta++;
  539. }
  540. else
  541. {
  542. ptt = pta + 4;
  543. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  544. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  545. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  546. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  547. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  548. while (ptt < array + offset + 16)
  549. {
  550. *pts++ = cmp(pta, ptt) > 0 ? *ptt++ : *pta++;
  551. }
  552. while (pta < array + offset + 12)
  553. {
  554. *pts++ = *pta++;
  555. }
  556. }
  557. step3:
  558. pta = array + offset;
  559. pts = swap;
  560. if (cmp(&pts[7], &pts[15]) <= 0)
  561. {
  562. ptt = pts + 8;
  563. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  564. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  565. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  566. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  567. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  568. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  569. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  570. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  571. // *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  572. while (pts < swap + 8)
  573. {
  574. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  575. }
  576. while (ptt < swap + 16)
  577. {
  578. *pta++ = *ptt++;
  579. }
  580. }
  581. else if (cmp(&pts[0], &pts[15]) > 0)
  582. {
  583. pts += 8;
  584. *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++;
  585. *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++;
  586. pts -= 16;
  587. *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++;
  588. *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++; *pta++ = *pts++;
  589. }
  590. else
  591. {
  592. ptt = pts + 8;
  593. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  594. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  595. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  596. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  597. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  598. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  599. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  600. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  601. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  602. while (ptt < swap + 16)
  603. {
  604. *pta++ = cmp(pts, ptt) > 0 ? *ptt++ : *pts++;
  605. }
  606. while (pts < swap + 8)
  607. {
  608. *pta++ = *pts++;
  609. }
  610. }
  611. }
  612. switch (nmemb - offset)
  613. {
  614. case 0:
  615. case 1:
  616. case 2:
  617. case 3:
  618. case 4:
  619. return;
  620. default:
  621. quad_sort64(pta, swap, nmemb - offset, 4, cmp);
  622. }
  623. }
  624. void quad_sort32(int *array, int *swap, size_t nmemb, size_t block, CMPFUNC *cmp)
  625. {
  626. size_t offset;
  627. register int *pta, *pts, *c, *c_max, *d, *d_max;
  628. while (block < nmemb)
  629. {
  630. offset = 0;
  631. while (offset + block < nmemb)
  632. {
  633. pta = array;
  634. pta += offset;
  635. c_max = pta + block;
  636. if (cmp(c_max - 1, c_max) <= 0)
  637. {
  638. if (offset + block * 3 < nmemb)
  639. {
  640. c_max = pta + block * 3;
  641. if (cmp(c_max - 1, c_max) <= 0)
  642. {
  643. c_max = pta + block * 2;
  644. if (cmp(c_max - 1, c_max) <= 0)
  645. {
  646. offset += block * 4;
  647. continue;
  648. }
  649. pts = swap;
  650. c = pta;
  651. while (c < c_max - 8)
  652. {
  653. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  654. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  655. }
  656. while (c < c_max)
  657. *pts++ = *c++;
  658. c = c_max;
  659. c_max = offset + block * 4 <= nmemb ? c + block * 2 : array + nmemb;
  660. while (c < c_max - 8)
  661. {
  662. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  663. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  664. }
  665. while (c < c_max)
  666. *pts++ = *c++;
  667. goto step3;
  668. }
  669. pts = swap;
  670. c = pta;
  671. c_max = pta + block * 2;
  672. while (c < c_max)
  673. *pts++ = *c++;
  674. goto step2;
  675. }
  676. else if (offset + block * 2 < nmemb)
  677. {
  678. c_max = pta + block * 2;
  679. if (cmp(c_max - 1, c_max) <= 0)
  680. {
  681. offset += block * 4;
  682. continue;
  683. }
  684. pts = swap;
  685. c = pta;
  686. while (c < c_max - 8)
  687. {
  688. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  689. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  690. }
  691. while (c < c_max)
  692. *pts++ = *c++;
  693. goto step2;
  694. }
  695. else
  696. {
  697. offset += block * 4;
  698. continue;
  699. }
  700. }
  701. // step1:
  702. pts = swap;
  703. c = pta;
  704. d = c_max;
  705. d_max = offset + block * 2 <= nmemb ? d + block : array + nmemb;
  706. if (cmp(c_max - 1, d_max - 1) <= 0)
  707. {
  708. while (c < c_max)
  709. {
  710. while (cmp(c, d) > 0)
  711. {
  712. *pts++ = *d++;
  713. }
  714. *pts++ = *c++;
  715. }
  716. while (d < d_max)
  717. *pts++ = *d++;
  718. }
  719. else if (cmp(c, d_max - 1) > 0)
  720. {
  721. if (offset + block * 4 <= nmemb)
  722. {
  723. int *e, *e_max, *f, *f_max, tmp;
  724. e = pta + block * 2;
  725. e_max = e + block;
  726. f = e_max;
  727. f_max = f + block;
  728. if (cmp(e, f_max - 1) > 0)
  729. {
  730. if (cmp(d, f_max - 1) > 0)
  731. {
  732. while (c < c_max)
  733. {
  734. tmp = *c;
  735. *c++ = *f;
  736. *f++ = tmp;
  737. }
  738. while (d < d_max)
  739. {
  740. tmp = *d;
  741. *d++ = *e;
  742. *e++ = tmp;
  743. }
  744. offset += block * 4;
  745. continue;
  746. }
  747. }
  748. }
  749. while (d < d_max - 8)
  750. {
  751. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  752. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  753. }
  754. while (d < d_max)
  755. *pts++ = *d++;
  756. while (c < c_max - 8)
  757. {
  758. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  759. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  760. }
  761. while (c < c_max)
  762. *pts++ = *c++;
  763. }
  764. else
  765. {
  766. while (d < d_max)
  767. {
  768. while (cmp(c, d) <= 0)
  769. {
  770. *pts++ = *c++;
  771. }
  772. *pts++ = *d++;
  773. }
  774. while (c < c_max)
  775. *pts++ = *c++;
  776. }
  777. step2:
  778. if (offset + block * 2 < nmemb)
  779. {
  780. c = pta + block * 2;
  781. if (offset + block * 3 < nmemb)
  782. {
  783. c_max = c + block;
  784. d = c_max;
  785. d_max = offset + block * 4 <= nmemb ? d + block : array + nmemb;
  786. if (cmp(c_max - 1, d_max - 1) <= 0)
  787. {
  788. while (c < c_max)
  789. {
  790. while (cmp(c, d) > 0)
  791. {
  792. *pts++ = *d++;
  793. }
  794. *pts++ = *c++;
  795. }
  796. while (d < d_max)
  797. *pts++ = *d++;
  798. }
  799. else if (cmp(c, d_max - 1) > 0)
  800. {
  801. while (d < d_max - 8)
  802. {
  803. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  804. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  805. }
  806. while (d < d_max)
  807. *pts++ = *d++;
  808. while (c < c_max - 8)
  809. {
  810. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  811. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  812. }
  813. while (c < c_max)
  814. *pts++ = *c++;
  815. }
  816. else
  817. {
  818. while (d < d_max)
  819. {
  820. while (cmp(c, d) <= 0)
  821. {
  822. *pts++ = *c++;
  823. }
  824. *pts++ = *d++;
  825. }
  826. while (c < c_max)
  827. *pts++ = *c++;
  828. }
  829. }
  830. else
  831. {
  832. d = c;
  833. d_max = array + nmemb;
  834. pts = swap;
  835. c = pts;
  836. c_max = c + block * 2;
  837. goto quickstep;
  838. }
  839. }
  840. step3:
  841. pts = swap;
  842. c = pts;
  843. if (offset + block * 2 < nmemb)
  844. {
  845. c_max = c + block * 2;
  846. d = c_max;
  847. d_max = offset + block * 4 <= nmemb ? d + block * 2 : pts + nmemb - offset;
  848. quickstep:
  849. if (cmp(c_max - 1, d_max - 1) <= 0)
  850. {
  851. while (c < c_max)
  852. {
  853. while (cmp(c, d) > 0)
  854. {
  855. *pta++ = *d++;
  856. }
  857. *pta++ = *c++;
  858. }
  859. while (d < d_max)
  860. *pta++ = *d++;
  861. }
  862. else if (cmp(c, d_max - 1) > 0)
  863. {
  864. while (d < d_max - 16)
  865. {
  866. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  867. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  868. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  869. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  870. }
  871. while (d < d_max)
  872. *pta++ = *d++;
  873. while (c < c_max - 16)
  874. {
  875. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  876. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  877. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  878. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  879. }
  880. while (c < c_max)
  881. *pta++ = *c++;
  882. }
  883. else
  884. {
  885. while (d < d_max)
  886. {
  887. while (cmp(d, c) > 0)
  888. {
  889. *pta++ = *c++;
  890. }
  891. *pta++ = *d++;
  892. }
  893. while (c < c_max)
  894. *pta++ = *c++;
  895. }
  896. }
  897. else
  898. {
  899. d_max = pts + nmemb - offset;
  900. while (c < d_max - 8)
  901. {
  902. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  903. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  904. }
  905. while (c < d_max)
  906. *pta++ = *c++;
  907. }
  908. offset += block * 4;
  909. }
  910. block *= 4;
  911. }
  912. }
  913. void quad_sort64(long long *array, long long *swap, size_t nmemb, size_t block, CMPFUNC *cmp)
  914. {
  915. size_t offset;
  916. register long long *pta, *pts, *c, *c_max, *d, *d_max;
  917. while (block < nmemb)
  918. {
  919. offset = 0;
  920. while (offset + block < nmemb)
  921. {
  922. pta = array;
  923. pta += offset;
  924. c_max = pta + block;
  925. if (cmp(c_max - 1, c_max) <= 0)
  926. {
  927. if (offset + block * 3 < nmemb)
  928. {
  929. c_max = pta + block * 3;
  930. if (cmp(c_max - 1, c_max) <= 0)
  931. {
  932. c_max = pta + block * 2;
  933. if (cmp(c_max - 1, c_max) <= 0)
  934. {
  935. offset += block * 4;
  936. continue;
  937. }
  938. pts = swap;
  939. c = pta;
  940. while (c < c_max - 8)
  941. {
  942. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  943. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  944. }
  945. while (c < c_max)
  946. *pts++ = *c++;
  947. c = c_max;
  948. c_max = offset + block * 4 <= nmemb ? c + block * 2 : array + nmemb;
  949. while (c < c_max - 8)
  950. {
  951. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  952. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  953. }
  954. while (c < c_max)
  955. *pts++ = *c++;
  956. goto step3;
  957. }
  958. pts = swap;
  959. c = pta;
  960. c_max = pta + block * 2;
  961. while (c < c_max)
  962. *pts++ = *c++;
  963. goto step2;
  964. }
  965. else if (offset + block * 2 < nmemb)
  966. {
  967. c_max = pta + block * 2;
  968. if (cmp(c_max - 1, c_max) <= 0)
  969. {
  970. offset += block * 4;
  971. continue;
  972. }
  973. pts = swap;
  974. c = pta;
  975. while (c < c_max - 8)
  976. {
  977. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  978. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  979. }
  980. while (c < c_max)
  981. *pts++ = *c++;
  982. goto step2;
  983. }
  984. else
  985. {
  986. offset += block * 4;
  987. continue;
  988. }
  989. }
  990. // step1:
  991. pts = swap;
  992. c = pta;
  993. d = c_max;
  994. d_max = offset + block * 2 <= nmemb ? d + block : array + nmemb;
  995. if (cmp(c_max - 1, d_max - 1) <= 0)
  996. {
  997. while (c < c_max)
  998. {
  999. while (cmp(c, d) > 0)
  1000. {
  1001. *pts++ = *d++;
  1002. }
  1003. *pts++ = *c++;
  1004. }
  1005. while (d < d_max)
  1006. *pts++ = *d++;
  1007. }
  1008. else if (cmp(c, d_max - 1) > 0)
  1009. {
  1010. if (offset + block * 4 <= nmemb)
  1011. {
  1012. long long *e, *e_max, *f, *f_max, tmp;
  1013. e = pta + block * 2;
  1014. e_max = e + block;
  1015. f = e_max;
  1016. f_max = f + block;
  1017. if (cmp(e, f_max - 1) > 0)
  1018. {
  1019. if (cmp(d, f_max - 1) > 0)
  1020. {
  1021. while (c < c_max)
  1022. {
  1023. tmp = *c;
  1024. *c++ = *f;
  1025. *f++ = tmp;
  1026. }
  1027. while (d < d_max)
  1028. {
  1029. tmp = *d;
  1030. *d++ = *e;
  1031. *e++ = tmp;
  1032. }
  1033. offset += block * 4;
  1034. continue;
  1035. }
  1036. }
  1037. }
  1038. while (d < d_max - 8)
  1039. {
  1040. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  1041. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  1042. }
  1043. while (d < d_max)
  1044. *pts++ = *d++;
  1045. while (c < c_max - 8)
  1046. {
  1047. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  1048. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  1049. }
  1050. while (c < c_max)
  1051. *pts++ = *c++;
  1052. }
  1053. else
  1054. {
  1055. while (d < d_max)
  1056. {
  1057. while (cmp(c, d) <= 0)
  1058. {
  1059. *pts++ = *c++;
  1060. }
  1061. *pts++ = *d++;
  1062. }
  1063. while (c < c_max)
  1064. *pts++ = *c++;
  1065. }
  1066. step2:
  1067. if (offset + block * 2 < nmemb)
  1068. {
  1069. c = pta + block * 2;
  1070. if (offset + block * 3 < nmemb)
  1071. {
  1072. c_max = c + block;
  1073. d = c_max;
  1074. d_max = offset + block * 4 <= nmemb ? d + block : array + nmemb;
  1075. if (cmp(c_max - 1, d_max - 1) <= 0)
  1076. {
  1077. while (c < c_max)
  1078. {
  1079. while (cmp(c, d) > 0)
  1080. {
  1081. *pts++ = *d++;
  1082. }
  1083. *pts++ = *c++;
  1084. }
  1085. while (d < d_max)
  1086. *pts++ = *d++;
  1087. }
  1088. else if (cmp(c, d_max - 1) > 0)
  1089. {
  1090. while (d < d_max - 8)
  1091. {
  1092. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  1093. *pts++ = *d++; *pts++ = *d++; *pts++ = *d++; *pts++ = *d++;
  1094. }
  1095. while (d < d_max)
  1096. *pts++ = *d++;
  1097. while (c < c_max - 8)
  1098. {
  1099. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  1100. *pts++ = *c++; *pts++ = *c++; *pts++ = *c++; *pts++ = *c++;
  1101. }
  1102. while (c < c_max)
  1103. *pts++ = *c++;
  1104. }
  1105. else
  1106. {
  1107. while (d < d_max)
  1108. {
  1109. while (cmp(c, d) <= 0)
  1110. {
  1111. *pts++ = *c++;
  1112. }
  1113. *pts++ = *d++;
  1114. }
  1115. while (c < c_max)
  1116. *pts++ = *c++;
  1117. }
  1118. }
  1119. else
  1120. {
  1121. d = c;
  1122. d_max = array + nmemb;
  1123. pts = swap;
  1124. c = pts;
  1125. c_max = c + block * 2;
  1126. goto quickstep;
  1127. }
  1128. }
  1129. step3:
  1130. pts = swap;
  1131. c = pts;
  1132. if (offset + block * 2 < nmemb)
  1133. {
  1134. c_max = c + block * 2;
  1135. d = c_max;
  1136. d_max = offset + block * 4 <= nmemb ? d + block * 2 : pts + nmemb - offset;
  1137. quickstep:
  1138. if (cmp(c_max - 1, d_max - 1) <= 0)
  1139. {
  1140. while (c < c_max)
  1141. {
  1142. while (cmp(c, d) > 0)
  1143. {
  1144. *pta++ = *d++;
  1145. }
  1146. *pta++ = *c++;
  1147. }
  1148. while (d < d_max)
  1149. *pta++ = *d++;
  1150. }
  1151. else if (cmp(c, d_max - 1) > 0)
  1152. {
  1153. while (d < d_max - 16)
  1154. {
  1155. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  1156. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  1157. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  1158. *pta++ = *d++; *pta++ = *d++; *pta++ = *d++; *pta++ = *d++;
  1159. }
  1160. while (d < d_max)
  1161. *pta++ = *d++;
  1162. while (c < c_max - 16)
  1163. {
  1164. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1165. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1166. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1167. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1168. }
  1169. while (c < c_max)
  1170. *pta++ = *c++;
  1171. }
  1172. else
  1173. {
  1174. while (d < d_max)
  1175. {
  1176. while (cmp(d, c) > 0)
  1177. {
  1178. *pta++ = *c++;
  1179. }
  1180. *pta++ = *d++;
  1181. }
  1182. while (c < c_max)
  1183. *pta++ = *c++;
  1184. }
  1185. }
  1186. else
  1187. {
  1188. d_max = pts + nmemb - offset;
  1189. while (c < d_max - 8)
  1190. {
  1191. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1192. *pta++ = *c++; *pta++ = *c++; *pta++ = *c++; *pta++ = *c++;
  1193. }
  1194. while (c < d_max)
  1195. *pta++ = *c++;
  1196. }
  1197. offset += block * 4;
  1198. }
  1199. block *= 4;
  1200. }
  1201. }
  1202. void quadsort(void *array, size_t nmemb, size_t size, CMPFUNC *cmp)
  1203. {
  1204. void *swap;
  1205. swap = malloc(nmemb * size);
  1206. if (size == sizeof(int))
  1207. {
  1208. quad_swap32(array, swap, nmemb, cmp);
  1209. quad_sort32(array, swap, nmemb, 16, cmp);
  1210. }
  1211. else if (size == sizeof(long long))
  1212. {
  1213. quad_swap64(array, swap, nmemb, cmp);
  1214. quad_sort64(array, swap, nmemb, 16, cmp);
  1215. }
  1216. else
  1217. {
  1218. assert(size == 4 || size == 8);
  1219. }
  1220. free(swap);
  1221. }
  1222. int cmp_int(const void * a, const void * b)
  1223. {
  1224. return *(int *) a - *(int *) b;
  1225. }
  1226. int cmp_str(const void * a, const void * b)
  1227. {
  1228. return strcmp(*(const char **) a, *(const char **) b);
  1229. }
  1230. int cmp_float(const void * a, const void * b)
  1231. {
  1232. return *(float *) a - *(float *) b;
  1233. }
  1234. int cmp_num(const void * a, const void * b)
  1235. {
  1236. if (is_number(*(char **) a) && is_number(*(char **) b))
  1237. {
  1238. long double num_a = is_number(*(char **) a) ? tintoi(*(char **) a) : 0;
  1239. long double num_b = is_number(*(char **) b) ? tintoi(*(char **) b) : 0;
  1240. if (num_a < num_b)
  1241. {
  1242. return -1;
  1243. }
  1244. if (num_a > num_b)
  1245. {
  1246. return 1;
  1247. }
  1248. return 0;
  1249. }
  1250. else if (is_number(*(char **) a))
  1251. {
  1252. return -1;
  1253. }
  1254. else if (is_number(*(char **) b))
  1255. {
  1256. return 1;
  1257. }
  1258. else
  1259. {
  1260. return strcmp(*(const char **) a, *(const char **) b);
  1261. }
  1262. }