Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jens Gustedt
P99 - macros and functions for C99
Commits
c08faeb6
Commit
c08faeb6
authored
Dec 03, 2012
by
(no author)
Committed by
Jens Gustedt
Dec 03, 2012
Browse files
code indentation
Signed-off-by:
Jens Gustedt
<
Jens.Gustedt@loria.fr
>
parent
78e653f8
Changes
2
Hide whitespace changes
Inline
Side-by-side
p99/p99_qsort.h
View file @
c08faeb6
...
...
@@ -31,47 +31,47 @@ struct p00_qsort {
size_t
top
;
};
#define P00_QSWAP_MEMPCP(P, A, B, S) \
do { \
void * p00Ma = (P)+(A); \
void * p00Mb = (P)+(B); \
size_t p00Ms = (S); \
/* if (p00Ma != p00Mb) */
{ \
memcpy(&p00_tmp, p00Ma, p00Ms); \
memcpy(p00Ma, p00Mb, p00Ms); \
memcpy(p00Mb, &p00_tmp, p00Ms); \
} \
#define P00_QSWAP_MEMPCP(P, A, B, S)
\
do {
\
void * p00Ma = (P)+(A);
\
void * p00Mb = (P)+(B);
\
size_t p00Ms = (S);
\
/* if (p00Ma != p00Mb) */
{
\
memcpy(&p00_tmp, p00Ma, p00Ms);
\
memcpy(p00Ma, p00Mb, p00Ms);
\
memcpy(p00Mb, &p00_tmp, p00Ms);
\
}
\
} while (false)
#define P00_QSWAP_ASSIGN(P, A, B, S) \
do { \
p00_tmp = (P)[A]; \
(P)[A] = (P)[B]; \
(P)[B] = p00_tmp; \
#define P00_QSWAP_ASSIGN(P, A, B, S)
\
do {
\
p00_tmp = (P)[A];
\
(P)[A] = (P)[B];
\
(P)[B] = p00_tmp;
\
} while (false)
#define P00_QCOMP(A, B) p00_comp(&p00_B[A], &p00_B[B], p00_ctx)
#define P00_QPUSH(P, B, T) \
do { \
register p00_qsort *const p00Mp = ++(P); \
p00Mp->bot = (B); \
p00Mp->top = (T); \
#define P00_QPUSH(P, B, T)
\
do {
\
register p00_qsort *const p00Mp = ++(P);
\
p00Mp->bot = (B);
\
p00Mp->top = (T);
\
} while (false)
#define P00_QTOP(P, B, T) \
register size_t const B = (P)->bot; \
#define P00_QTOP(P, B, T)
\
register size_t const B = (P)->bot;
\
register size_t const T = (P)->top
#define P00_QEMPTY(S, P) ((S) == (P))
#define P00_ILOG2_INNER(_0, XI, _2) \
{ \
P99_CONSTANT(int, p00_r, (1 << (XI))); \
if (p00_i >= (UINTMAX_C(1) << p00_r)) { \
p00_n += p00_r; \
p00_i >>= p00_r; \
} \
#define P00_ILOG2_INNER(_0, XI, _2)
\
{
\
P99_CONSTANT(int, p00_r, (1 << (XI)));
\
if (p00_i >= (UINTMAX_C(1) << p00_r)) {
\
p00_n += p00_r;
\
p00_i >>= p00_r;
\
}
\
}
p99_inline
...
...
@@ -87,101 +87,101 @@ signed p99_ilog2(uintmax_t p00_i) {
}
#define P00_QSORT_BODY(SWAP)
\
if (p00_n > RSIZE_MAX || p00_s > RSIZE_MAX) return ERANGE;
\
if (p00_n && (!p00_base || !p00_comp)) return EINVAL;
\
do {
\
register p99_seed *const seed = p99_seed_get();
\
/* Initialize a stack of states */
\
P99_CONSTANT(int, p00_tail, 20);
\
/* provide a reasonable stack of states */
\
p00_qsort p00_a[(p99_ilog2(p00_n) + 1)*p00_tail];
\
p00_qsort* p00_p = p00_a;
\
P00_QPUSH(p00_p, 0, p00_n);
\
while(!P00_QEMPTY(p00_a, p00_p)) {
\
/* read the values from the stack */
\
P00_QTOP(p00_p, p00_bot, p00_top);
\
register size_t const p00_len = p00_top - p00_bot;
\
\
switch (p00_len) {
\
/* special cases all fall through. */
\
case 2:
\
if (P00_QCOMP(p00_bot, p00_bot + 1) > 0)
\
SWAP(p00_B, p00_bot, p00_bot + 1, p00_s);
\
case 1: ;
\
case 0:
\
--p00_p;
\
break;
\
default:
\
/* move the pivot to the bottom element */
\
{
\
size_t p00_c = p99_rand(seed) % p00_len;
\
if (p00_c) SWAP(p00_B, p00_bot, p00_bot + p00_c, p00_s);
\
}
\
\
/* The running variables. The fact that p00_b is > p00_bot,
\
guarantees progress. */
\
register size_t p00_b = p00_bot + 1;
\
register size_t p00_t = p00_top;
\
\
while (P99_LIKELY(p00_b < p00_t)) {
\
/* Try to find two misplaced elements. */
\
while (!(P00_QCOMP(p00_bot, p00_b) < 0)) {
\
++p00_b;
\
if (P99_UNLIKELY(p00_b == p00_t)) goto P00_RECURSE;
\
}
\
while (P00_QCOMP(p00_bot, p00_t - 1) < 0){
\
--p00_t;
\
if (P99_UNLIKELY(p00_b == p00_t)) goto P00_RECURSE;
\
}
\
\
/* Two distinct misplaced elements are found. */
\
--p00_t;
\
SWAP(p00_B, p00_b, p00_t, p00_s);
\
++p00_b;
\
}
\
P00_RECURSE:
\
if ((p00_b - p00_bot) > 1) {
\
/* The pivot is always a maximal element in the lower part */
\
--p00_b;
\
SWAP(p00_B, p00_bot, p00_b, p00_s);
\
/* Move all elements that compare equal adjacent */
\
register size_t const p00_bb = p00_b;
\
for (register size_t p00_c = p00_bot;
\
p00_c < p00_b;) {
\
if (P00_QCOMP(p00_bb, p00_c) <= 0) {
\
--p00_b;
\
if (p00_c == p00_b) break;
\
SWAP(p00_B, p00_c, p00_b, p00_s);
\
} else ++p00_c;
\
}
\
}
\
/* Register the "recursive" calls into the two halfs. Most */
\
/* recursive calls are actually close to the bottom, so we */
\
/* rarely have to do the check if they are small enough. */
\
if (P99_UNLIKELY(p00_len >= p00_tail)) {
\
size_t p00Mmax = p00_len*0.99;
\
/* If the split isn't good enough we just try again */
\
if (P99_UNLIKELY(((p00_b - p00_bot) >= p00Mmax)
\
||
\
((p00_top - p00_t) >= p00Mmax)))
\
continue;
\
}
\
--p00_p;
\
if ((p00_b - p00_bot) > 1) P00_QPUSH(p00_p, p00_bot, p00_b);
\
if ((p00_top - p00_t) > 1) P00_QPUSH(p00_p, p00_t, p00_top);
\
}
\
}
\
return 0;
\
#define P00_QSORT_BODY(SWAP) \
if (p00_n > RSIZE_MAX || p00_s > RSIZE_MAX) return ERANGE; \
if (p00_n && (!p00_base || !p00_comp)) return EINVAL; \
do { \
register p99_seed *const seed = p99_seed_get(); \
/* Initialize a stack of states */
\
P99_CONSTANT(int, p00_tail, 20); \
/* provide a reasonable stack of states */
\
p00_qsort p00_a[(p99_ilog2(p00_n) + 1)*p00_tail]; \
p00_qsort* p00_p = p00_a; \
P00_QPUSH(p00_p, 0, p00_n); \
while(!P00_QEMPTY(p00_a, p00_p)) { \
/* read the values from the stack */
\
P00_QTOP(p00_p, p00_bot, p00_top); \
register size_t const p00_len = p00_top - p00_bot; \
\
switch (p00_len) { \
/* special cases all fall through. */
\
case 2: \
if (P00_QCOMP(p00_bot, p00_bot + 1) > 0) \
SWAP(p00_B, p00_bot, p00_bot + 1, p00_s); \
case 1: ; \
case 0: \
--p00_p; \
break; \
default: \
/* move the pivot to the bottom element */
\
{ \
size_t p00_c = p99_rand(seed) % p00_len; \
if (p00_c) SWAP(p00_B, p00_bot, p00_bot + p00_c, p00_s); \
} \
\
/* The running variables. The fact that p00_b is > p00_bot, \
guarantees progress. */
\
register size_t p00_b = p00_bot + 1; \
register size_t p00_t = p00_top; \
\
while (P99_LIKELY(p00_b < p00_t)) { \
/* Try to find two misplaced elements. */
\
while (!(P00_QCOMP(p00_bot, p00_b) < 0)) { \
++p00_b; \
if (P99_UNLIKELY(p00_b == p00_t)) goto P00_RECURSE; \
} \
while (P00_QCOMP(p00_bot, p00_t - 1) < 0){ \
--p00_t; \
if (P99_UNLIKELY(p00_b == p00_t)) goto P00_RECURSE; \
} \
\
/* Two distinct misplaced elements are found. */
\
--p00_t; \
SWAP(p00_B, p00_b, p00_t, p00_s); \
++p00_b; \
} \
P00_RECURSE: \
if ((p00_b - p00_bot) > 1) { \
/* The pivot is always a maximal element in the lower part */
\
--p00_b; \
SWAP(p00_B, p00_bot, p00_b, p00_s); \
/* Move all elements that compare equal adjacent */
\
register size_t const p00_bb = p00_b; \
for (register size_t p00_c = p00_bot; \
p00_c < p00_b;) { \
if (P00_QCOMP(p00_bb, p00_c) <= 0) { \
--p00_b; \
if (p00_c == p00_b) break; \
SWAP(p00_B, p00_c, p00_b, p00_s); \
} else ++p00_c; \
} \
} \
/* Register the "recursive" calls into the two halfs. Most */
\
/* recursive calls are actually close to the bottom, so we */
\
/* rarely have to do the check if they are small enough. */
\
if (P99_UNLIKELY(p00_len >= p00_tail)) { \
size_t p00Mmax = p00_len*0.99; \
/* If the split isn't good enough we just try again */
\
if (P99_UNLIKELY(((p00_b - p00_bot) >= p00Mmax) \
|| \
((p00_top - p00_t) >= p00Mmax))) \
continue; \
} \
--p00_p; \
if ((p00_b - p00_bot) > 1) P00_QPUSH(p00_p, p00_bot, p00_b); \
if ((p00_top - p00_t) > 1) P00_QPUSH(p00_p, p00_t, p00_top); \
} \
} \
return 0; \
} while(false)
P99_WEAK
(
p99_qsort_generic
)
errno_t
p99_qsort_generic
(
void
*
p00_base
,
rsize_t
p00_n
,
rsize_t
p00_s
,
int
(
*
p00_comp
)(
const
void
*
,
const
void
*
,
void
*
),
void
*
p00_ctx
)
{
rsize_t
p00_n
,
rsize_t
p00_s
,
int
(
*
p00_comp
)(
const
void
*
,
const
void
*
,
void
*
),
void
*
p00_ctx
)
{
typedef
unsigned
char
p00_el
[
p00_s
];
register
p00_el
*
const
p00_B
=
p00_base
;
p00_el
p00_tmp
;
...
...
@@ -189,17 +189,17 @@ errno_t p99_qsort_generic(void *p00_base,
}
#define P00_QSORT_DECLARE(T) \
p99_inline \
errno_t P99_PASTE2(p99_qsort_, T)(void *p00_base, \
rsize_t p00_n, \
rsize_t p00_s, \
#define P00_QSORT_DECLARE(T)
\
p99_inline
\
errno_t P99_PASTE2(p99_qsort_, T)(void *p00_base,
\
rsize_t p00_n,
\
rsize_t p00_s,
\
int (*p00_comp)(const void *, const void *, void *), \
void *p00_ctx) { \
register T *const p00_B = p00_base; \
_Alignas(sizeof(max_align_t)) T p00_tmp; \
P00_QSORT_BODY(P00_QSWAP_ASSIGN); \
} \
void *p00_ctx) {
\
register T *const p00_B = p00_base;
\
_Alignas(sizeof(max_align_t)) T p00_tmp;
\
P00_QSORT_BODY(P00_QSWAP_ASSIGN);
\
}
\
P99_MACRO_END(p99_qsort_, T)
P00_QSORT_DECLARE
(
_Bool
);
...
...
@@ -281,66 +281,66 @@ errno_t p99_qsort_s(void *p00_base,
}
#ifdef __STDC_NO_COMPLEX__
#define qsort_s(B, N, S, CMP, CTX)
\
P99_CONSTRAINT_TRIGGER(
\
P99_GENERIC(&((B)[0]),
\
p99_qsort_s,
\
(void_ptr*, p99_qsort_void_ptr),
\
/* */
\
(float*, p99_qsort_float),
\
(double*, p99_qsort_double),
\
(double*, p99_qsort_cdouble),
\
/* */
\
(_Bool*, p99_qsort__Bool),
\
(char*, p99_qsort_char),
\
(uchar*, p99_qsort_uchar),
\
(schar*, p99_qsort_schar),
\
/* */
\
(ushort*, p99_qsort_ushort),
\
(short*, p99_qsort_short),
\
/* */
\
(unsigned*, p99_qsort_unsigned),
\
(signed*, p99_qsort_signed),
\
/* */
\
(long*, p99_qsort_long),
\
(ulong*, p99_qsort_ulong),
\
/* */
\
(llong*, p99_qsort_llong),
\
(ullong*, p99_qsort_ullong)
\
)((B), (N), (S), (CMP), (CTX)),
\
#define qsort_s(B, N, S, CMP, CTX) \
P99_CONSTRAINT_TRIGGER( \
P99_GENERIC(&((B)[0]), \
p99_qsort_s, \
(void_ptr*, p99_qsort_void_ptr), \
/* */
\
(float*, p99_qsort_float), \
(double*, p99_qsort_double), \
(double*, p99_qsort_cdouble), \
/* */
\
(_Bool*, p99_qsort__Bool), \
(char*, p99_qsort_char), \
(uchar*, p99_qsort_uchar), \
(schar*, p99_qsort_schar), \
/* */
\
(ushort*, p99_qsort_ushort), \
(short*, p99_qsort_short), \
/* */
\
(unsigned*, p99_qsort_unsigned), \
(signed*, p99_qsort_signed), \
/* */
\
(long*, p99_qsort_long), \
(ulong*, p99_qsort_ulong), \
/* */
\
(llong*, p99_qsort_llong), \
(ullong*, p99_qsort_ullong) \
)((B), (N), (S), (CMP), (CTX)), \
"qsort_s runtime constraint violation")
#else
#define qsort_s(B, N, S, CMP, CTX)
\
P99_CONSTRAINT_TRIGGER(
\
P99_GENERIC(&((B)[0]),
\
p99_qsort_s,
\
(void_ptr*, p99_qsort_void_ptr),
\
/* */
\
(float*, p99_qsort_float),
\
(double*, p99_qsort_double),
\
(ldouble*, p99_qsort_ldouble),
\
/* */
\
(cfloat*, p99_qsort_cfloat),
\
(cdouble*, p99_qsort_cdouble),
\
(cldouble*, p99_qsort_cldouble),
\
/* */
\
(_Bool*, p99_qsort__Bool),
\
(char*, p99_qsort_char),
\
(uchar*, p99_qsort_uchar),
\
(schar*, p99_qsort_schar),
\
/* */
\
(ushort*, p99_qsort_ushort),
\
(short*, p99_qsort_short),
\
/* */
\
(unsigned*, p99_qsort_unsigned),
\
(signed*, p99_qsort_signed),
\
/* */
\
(long*, p99_qsort_long),
\
(ulong*, p99_qsort_ulong),
\
/* */
\
(llong*, p99_qsort_llong),
\
(ullong*, p99_qsort_ullong)
\
)((B), (N), (S), (CMP), (CTX)),
\
#define qsort_s(B, N, S, CMP, CTX) \
P99_CONSTRAINT_TRIGGER( \
P99_GENERIC(&((B)[0]), \
p99_qsort_s, \
(void_ptr*, p99_qsort_void_ptr), \
/* */
\
(float*, p99_qsort_float), \
(double*, p99_qsort_double), \
(ldouble*, p99_qsort_ldouble), \
/* */
\
(cfloat*, p99_qsort_cfloat), \
(cdouble*, p99_qsort_cdouble), \
(cldouble*, p99_qsort_cldouble), \
/* */
\
(_Bool*, p99_qsort__Bool), \
(char*, p99_qsort_char), \
(uchar*, p99_qsort_uchar), \
(schar*, p99_qsort_schar), \
/* */
\
(ushort*, p99_qsort_ushort), \
(short*, p99_qsort_short), \
/* */
\
(unsigned*, p99_qsort_unsigned), \
(signed*, p99_qsort_signed), \
/* */
\
(long*, p99_qsort_long), \
(ulong*, p99_qsort_ulong), \
/* */
\
(llong*, p99_qsort_llong), \
(ullong*, p99_qsort_ullong) \
)((B), (N), (S), (CMP), (CTX)), \
"qsort_s runtime constraint violation")
#endif
...
...
@@ -361,10 +361,10 @@ rsize_t p99_mismatch(void *p00_base,
p99_inline
bool
p99_is_sorted
(
void
*
p00_base
,
rsize_t
p00_n
,
rsize_t
p00_s
,
int
(
*
p00_comp
)(
const
void
*
,
const
void
*
,
void
*
),
void
*
p00_ctx
)
{
rsize_t
p00_n
,
rsize_t
p00_s
,
int
(
*
p00_comp
)(
const
void
*
,
const
void
*
,
void
*
),
void
*
p00_ctx
)
{
return
!
(
p99_mismatch
(
p00_base
,
p00_n
,
p00_s
,
p00_comp
,
p00_ctx
)
<
p00_n
);
}
...
...
p99/p99_swap.h
View file @
c08faeb6
...
...
@@ -165,15 +165,15 @@ P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SWAP, 1)
P00_DOCUMENT_PERMITTED_ARGUMENT
(
P99_QSORT
,
0
)
#define P99_QSORT(TAB, NB, ...) \
P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
(qsort((TAB), (NB), sizeof (TAB)[0], __VA_ARGS__)) \
#define P99_QSORT(TAB, NB, ...)
\
P99_IF_LT(P99_NARG(__VA_ARGS__), 2)
\
(qsort((TAB), (NB), sizeof (TAB)[0], __VA_ARGS__))
\
(qsort_s((TAB), (NB), sizeof (TAB)[0], __VA_ARGS__))
P00_DOCUMENT_PERMITTED_ARGUMENT
(
P99_ASORT
,
0
)
#define P99_ASORT(TAB, ...)
\
P99_IF_LT(P99_NARG(__VA_ARGS__), 2)
\
(qsort((TAB), P99_ALEN(TAB), sizeof (TAB)[0], __VA_ARGS__))
\
#define P99_ASORT(TAB, ...) \
P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
(qsort((TAB), P99_ALEN(TAB), sizeof (TAB)[0], __VA_ARGS__)) \
(qsort_s((TAB), P99_ALEN(TAB), sizeof (TAB)[0], __VA_ARGS__))
#endif
/* !P99_SWAP_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment