sort.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475
  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_num(const void * a, const void * b)
  1231. {
  1232. unsigned char isnum_a, isnum_b;
  1233. isnum_a = is_number(*(char **) a);
  1234. isnum_b = is_number(*(char **) b);
  1235. if (isnum_a && isnum_b)
  1236. {
  1237. long double num_a = tintoi(*(char **) a);
  1238. long double num_b = tintoi(*(char **) b);
  1239. return num_a < num_b ? -1 : num_a > num_b ? 1 : 0;
  1240. }
  1241. else if (isnum_a)
  1242. {
  1243. return -1;
  1244. }
  1245. else if (isnum_b)
  1246. {
  1247. return 1;
  1248. }
  1249. else
  1250. {
  1251. return strcmp(*(const char **) a, *(const char **) b);
  1252. }
  1253. }