#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
struct MyStruct {
int x; int y;
};
int mycomp(const struct MyStruct* a, const struct MyStruct* b) {
long da = a->x*a->x + a->y*a->y;
long db = b->x*b->x + b->y*b->y;
return da < db ? -1 : da == db ? a->x - b->x : 1;
}
/* This struct avoids the issue of casting a function pointer to
* a void*, which is not guaranteed to work.
*/
typedef struct CompContainer {
int (*const comp_func)(const struct MyStruct *, const struct MyStruct *);
} CompContainer;
int delegatingComp(const void *a, const void *b, void* comp) {
return ((CompContainer*)comp)->comp_func((const struct MyStruct *)a,
(const struct MyStruct *)b);
}
void myStructSort(
struct MyStruct *arr,
int size,
int (*comp_func)(const struct MyStruct *,
const struct MyStruct *)) {
const CompContainer comp = {comp_func};
qsort_r(arr, size, sizeof(struct MyStruct), delegatingComp, &comp);
}
int main(void) {
struct MyStruct v[] = {{1,4},{2,3},{3,2},{4,1}};
myStructSort(v, 4, mycomp);
for (int i
= 0; i
< 4; ++i
) printf("{%d,%d} ", v
[i
].
x, v
[i
].
y); return 0;
}
I2RlZmluZSBfR05VX1NPVVJDRQojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKc3RydWN0IE15U3RydWN0IHsKCWludCB4OyBpbnQgeTsKfTsKaW50IG15Y29tcChjb25zdCBzdHJ1Y3QgTXlTdHJ1Y3QqIGEsIGNvbnN0IHN0cnVjdCBNeVN0cnVjdCogYikgewoJbG9uZyBkYSA9IGEtPngqYS0+eCArIGEtPnkqYS0+eTsKCWxvbmcgZGIgPSBiLT54KmItPnggKyBiLT55KmItPnk7CglyZXR1cm4gZGEgPCBkYiA/IC0xIDogZGEgPT0gZGIgPyBhLT54IC0gYi0+eCA6IDE7Cn0KCiAgICAvKiBUaGlzIHN0cnVjdCBhdm9pZHMgdGhlIGlzc3VlIG9mIGNhc3RpbmcgYSBmdW5jdGlvbiBwb2ludGVyIHRvCiAgICAgKiBhIHZvaWQqLCB3aGljaCBpcyBub3QgZ3VhcmFudGVlZCB0byB3b3JrLgogICAgICovCiAgICB0eXBlZGVmIHN0cnVjdCBDb21wQ29udGFpbmVyIHsKICAgICAgIGludCAoKmNvbnN0IGNvbXBfZnVuYykoY29uc3Qgc3RydWN0IE15U3RydWN0ICosIGNvbnN0IHN0cnVjdCBNeVN0cnVjdCAqKTsKICAgIH0gQ29tcENvbnRhaW5lcjsKCiAgICBpbnQgZGVsZWdhdGluZ0NvbXAoY29uc3Qgdm9pZCAqYSwgY29uc3Qgdm9pZCAqYiwgdm9pZCogY29tcCkgewogICAgICByZXR1cm4gKChDb21wQ29udGFpbmVyKiljb21wKS0+Y29tcF9mdW5jKChjb25zdCBzdHJ1Y3QgTXlTdHJ1Y3QgKilhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBzdHJ1Y3QgTXlTdHJ1Y3QgKiliKTsKICAgIH0KICAgIAogICAgdm9pZCBteVN0cnVjdFNvcnQoCiAgICAgICAgICAgICAgICAgIHN0cnVjdCBNeVN0cnVjdCAqYXJyLAogICAgICAgICAgICAgICAgICBpbnQgc2l6ZSwKICAgICAgICAgICAgICAgICAgaW50ICgqY29tcF9mdW5jKShjb25zdCBzdHJ1Y3QgTXlTdHJ1Y3QgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IE15U3RydWN0ICopKSB7CiAgICAgIGNvbnN0IENvbXBDb250YWluZXIgY29tcCA9IHtjb21wX2Z1bmN9OwogICAgICBxc29ydF9yKGFyciwgc2l6ZSwgc2l6ZW9mKHN0cnVjdCBNeVN0cnVjdCksIGRlbGVnYXRpbmdDb21wLCAmY29tcCk7CiAgICB9CgppbnQgbWFpbih2b2lkKSB7CiAgICBzdHJ1Y3QgTXlTdHJ1Y3QgdltdID0ge3sxLDR9LHsyLDN9LHszLDJ9LHs0LDF9fTsKICAgIG15U3RydWN0U29ydCh2LCA0LCBteWNvbXApOwoJZm9yIChpbnQgaSA9IDA7IGkgPCA0OyArK2kpIHByaW50ZigieyVkLCVkfSAiLCB2W2ldLngsIHZbaV0ueSk7CglwdXRjaGFyKCdcbicpOwoJcmV0dXJuIDA7Cn0K