Add experimental support for cmp function with user define order.

This commit is contained in:
Patrick Pelissier committed 2018-05-16 22:36:26 +02:00
1 parent 2fbea43a5c
commit 1a3cd2f626
2 files changed
+61 -2

No files matched your search

+42 -1
View File
@@ -32,6 +32,7 @@
TUPLE_DEF2(name, [(field1, type1, oplist1), (field2, type2, oplist2), ...] ) */
#define TUPLE_DEF2(name, ...) \
TUPLE_DEFINE_TYPE(name, __VA_ARGS__) \
TUPLE_DEFINE_ENUM(name, __VA_ARGS__) \
TUPLE_DEFINE_INIT(name, __VA_ARGS__) \
TUPLE_DEFINE_INIT_SET(name, __VA_ARGS__) \
TUPLE_DEFINE_INIT_SET2(name, __VA_ARGS__) \
@@ -42,6 +43,8 @@
TUPLE_DEFINE_SETTER(name, __VA_ARGS__) \
M_IF(TUPLE_ALL_CMP(__VA_ARGS__)) \
(TUPLE_DEFINE_CMP(name, __VA_ARGS__),) \
M_IF(TUPLE_ALL_CMP(__VA_ARGS__)) \
(TUPLE_DEFINE_CMP_ORDER(name, __VA_ARGS__),) \
TUPLE_DEFINE_CMP_FIELD(name, __VA_ARGS__) \
M_IF(TUPLE_ALL_HASH(__VA_ARGS__)) \
(TUPLE_DEFINE_HASH(name, __VA_ARGS__),) \
@@ -69,9 +72,17 @@
(TUPLEI_OPLIST(__VA_ARGS__, () ), \
TUPLEI_OPLIST(__VA_ARGS__ ))
/* Return an array suitable for the _cmp_order function */
#define TUPLE_ORDER(name, ...) \
( (int[]) {M_MAP2_C(TUPLE_ORDER_CONVERT, name, __VA_ARGS__), 0})
/********************************** INTERNAL ************************************/
#define TUPLE_ORDER_CONVERT(name, x) M_C(name, M_C(TUPLE_ORDER_CONVERT_, x))
#define TUPLE_ORDER_CONVERT_ASC(x) M_C3(_,x,_value)
#define TUPLE_ORDER_CONVERT_DSC(x) M_C3(_,x,_value)*-1
#define TUPLE_GET_FIELD(f,t,o) f
#define TUPLE_GET_TYPE(f,t,o) t
#define TUPLE_GET_OPLIST(f,t,o) o
@@ -101,6 +112,15 @@
TUPLE_GET_TYPE a TUPLE_GET_FIELD a ;
#define TUPLE_DEFINE_ENUM(name, ...) \
typedef enum { \
M_C(name, _first_one_val), \
M_MAP2_C(TUPLE_DEFINE_ENUM_ELE , name, __VA_ARGS__) \
} M_C(name,_field_e);
#define TUPLE_DEFINE_ENUM_ELE(name, a) \
M_C4(name, _, TUPLE_GET_FIELD a, _value)
#define TUPLE_DEFINE_INIT(name, ...) \
static inline void M_C(name, _init)(M_C(name,_t) my) { \
M_MAP(TUPLE_DEFINE_INIT_FUNC , __VA_ARGS__) \
@@ -186,7 +206,28 @@
if (i != 0) return i;
#define TUPLE_DEFINE_CMP_FIELD(name, ...) \
#define TUPLE_DEFINE_CMP_ORDER(name, ...) \
static inline int M_C(name, _cmp_order)(M_C(name,_t) const e1 , \
M_C(name,_t) const e2, \
const int order[]) { \
int i, r; \
while ((i=*order++) != 0) { \
switch (i) { \
M_MAP2(TUPLE_DEFINE_CMP_ORDER_FUNC , name, __VA_ARGS__) \
default: assert(0); \
} \
} \
return 0; \
}
#define TUPLE_DEFINE_CMP_ORDER_FUNC(name, a) \
case M_C4(name, _, TUPLE_GET_FIELD a, _value): \
case -M_C4(name, _, TUPLE_GET_FIELD a, _value): \
r = TUPLE_GET_CMP a ( e1 -> TUPLE_GET_FIELD a , e2 -> TUPLE_GET_FIELD a ); \
if (r != 0) return i < 0 ? -r : r; \
break;
#define TUPLE_DEFINE_CMP_FIELD(name, ...) \
M_MAP2(TUPLE_MAP_CMP_FIELD, name, __VA_ARGS__)
#define TUPLE_MAP_CMP_FIELD(name, a) \
M_IF_METHOD(CMP, TUPLE_GET_OPLIST a)( \
+19 -1
View File
@@ -97,7 +97,7 @@ static void check_io(void)
}
}
int main(void)
static void test1(void)
{
pair_t p1, p2;
@@ -137,11 +137,29 @@ int main(void)
pair3_set_key(p4, s);
i = pair3_cmp (p3, p4);
assert (i > 0);
// p3 = HELLO, 1442
// p4 = HELLN, 1443
i = pair3_cmp_order(p3, p3, TUPLE_ORDER(pair3, ASC(value), DSC(key)));
assert (i == 0);
i = pair3_cmp_order(p3, p4, TUPLE_ORDER(pair3, ASC(key), ASC(value)));
assert (i > 0);
i = pair3_cmp_order(p3, p4, TUPLE_ORDER(pair3, ASC(value), ASC(key)));
assert (i < 0);
i = pair3_cmp_order(p3, p4, TUPLE_ORDER(pair3, DSC(key), ASC(value)));
assert (i < 0);
i = pair3_cmp_order(p3, p4, TUPLE_ORDER(pair3, DSC(value), ASC(key)));
assert (i > 0);
pair3_clear(p3);
pair3_clear(p4);
string_clear(s);
testobj_clear(z);
}
int main(void)
{
test1();
check_io();
check_swap();
exit(0);