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), ...] ) */
|
TUPLE_DEF2(name, [(field1, type1, oplist1), (field2, type2, oplist2), ...] ) */
|
||||||
#define TUPLE_DEF2(name, ...) \
|
#define TUPLE_DEF2(name, ...) \
|
||||||
TUPLE_DEFINE_TYPE(name, __VA_ARGS__) \
|
TUPLE_DEFINE_TYPE(name, __VA_ARGS__) \
|
||||||
|
TUPLE_DEFINE_ENUM(name, __VA_ARGS__) \
|
||||||
TUPLE_DEFINE_INIT(name, __VA_ARGS__) \
|
TUPLE_DEFINE_INIT(name, __VA_ARGS__) \
|
||||||
TUPLE_DEFINE_INIT_SET(name, __VA_ARGS__) \
|
TUPLE_DEFINE_INIT_SET(name, __VA_ARGS__) \
|
||||||
TUPLE_DEFINE_INIT_SET2(name, __VA_ARGS__) \
|
TUPLE_DEFINE_INIT_SET2(name, __VA_ARGS__) \
|
||||||
@@ -42,6 +43,8 @@
|
|||||||
TUPLE_DEFINE_SETTER(name, __VA_ARGS__) \
|
TUPLE_DEFINE_SETTER(name, __VA_ARGS__) \
|
||||||
M_IF(TUPLE_ALL_CMP(__VA_ARGS__)) \
|
M_IF(TUPLE_ALL_CMP(__VA_ARGS__)) \
|
||||||
(TUPLE_DEFINE_CMP(name, __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__) \
|
TUPLE_DEFINE_CMP_FIELD(name, __VA_ARGS__) \
|
||||||
M_IF(TUPLE_ALL_HASH(__VA_ARGS__)) \
|
M_IF(TUPLE_ALL_HASH(__VA_ARGS__)) \
|
||||||
(TUPLE_DEFINE_HASH(name, __VA_ARGS__),) \
|
(TUPLE_DEFINE_HASH(name, __VA_ARGS__),) \
|
||||||
@@ -69,9 +72,17 @@
|
|||||||
(TUPLEI_OPLIST(__VA_ARGS__, () ), \
|
(TUPLEI_OPLIST(__VA_ARGS__, () ), \
|
||||||
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 ************************************/
|
/********************************** 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_FIELD(f,t,o) f
|
||||||
#define TUPLE_GET_TYPE(f,t,o) t
|
#define TUPLE_GET_TYPE(f,t,o) t
|
||||||
#define TUPLE_GET_OPLIST(f,t,o) o
|
#define TUPLE_GET_OPLIST(f,t,o) o
|
||||||
@@ -101,6 +112,15 @@
|
|||||||
TUPLE_GET_TYPE a TUPLE_GET_FIELD a ;
|
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, ...) \
|
#define TUPLE_DEFINE_INIT(name, ...) \
|
||||||
static inline void M_C(name, _init)(M_C(name,_t) my) { \
|
static inline void M_C(name, _init)(M_C(name,_t) my) { \
|
||||||
M_MAP(TUPLE_DEFINE_INIT_FUNC , __VA_ARGS__) \
|
M_MAP(TUPLE_DEFINE_INIT_FUNC , __VA_ARGS__) \
|
||||||
@@ -186,7 +206,28 @@
|
|||||||
if (i != 0) return i;
|
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__)
|
M_MAP2(TUPLE_MAP_CMP_FIELD, name, __VA_ARGS__)
|
||||||
#define TUPLE_MAP_CMP_FIELD(name, a) \
|
#define TUPLE_MAP_CMP_FIELD(name, a) \
|
||||||
M_IF_METHOD(CMP, TUPLE_GET_OPLIST 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;
|
pair_t p1, p2;
|
||||||
|
|
||||||
@@ -137,11 +137,29 @@ int main(void)
|
|||||||
pair3_set_key(p4, s);
|
pair3_set_key(p4, s);
|
||||||
i = pair3_cmp (p3, p4);
|
i = pair3_cmp (p3, p4);
|
||||||
assert (i > 0);
|
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(p3);
|
||||||
pair3_clear(p4);
|
pair3_clear(p4);
|
||||||
string_clear(s);
|
string_clear(s);
|
||||||
testobj_clear(z);
|
testobj_clear(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
check_io();
|
check_io();
|
||||||
check_swap();
|
check_swap();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|||||||
Reference in new issue
Block a user