Add experimental support for cmp function with user define order.
This commit is contained in:
1 parent
2fbea43a5c
commit
1a3cd2f626
2 files changed
+61
-2
No files matched your search
@@ -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
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user