P99
p99_for.h
Go to the documentation of this file.
1 /* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2 /* */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the authors and copyright holders for this work are as follows: */
5 /* (C) copyright 2010-2014 Jens Gustedt, INRIA, France */
6 /* (C) copyright 2012 William Morris */
7 /* */
8 /* This file is free software; it is part of the P99 project. */
9 /* */
10 /* Licensed under the Apache License, Version 2.0 (the "License"); */
11 /* you may not use this file except in compliance with the License. */
12 /* You may obtain a copy of the License at */
13 /* */
14 /* http://www.apache.org/licenses/LICENSE-2.0 */
15 /* */
16 /* Unless required by applicable law or agreed to in writing, software */
17 /* distributed under the License is distributed on an "AS IS" BASIS, */
18 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
19 /* See the License for the specific language governing permissions and */
20 /* limitations under the License. */
21 /* */
22 #ifndef P99_FOR_H_
23 # define P99_FOR_H_
24 
32 #include "p99_block.h"
33 
34 
35 
40 #define P00_FOR0(NAME, OP, FUNC, ...)
41 #define P00_FOR1(NAME, OP, FUNC, ...) FUNC(NAME, P00_PRE1(__VA_ARGS__,), 0)
42 
43 #ifdef P00_DOXYGEN
44 
89 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FOR, 0)
90 P00_DOCUMENT_NUMBER_ARGUMENT(P99_FOR, 1)
91 P00_DOCUMENT_MACRO_ARGUMENT(P99_FOR, 3)
92 #define P99_FOR(NAME, N, OP, FUNC, ...)
93 #else
94 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FOR, 0)
95 P00_DOCUMENT_NUMBER_ARGUMENT(P99_FOR, 1)
96 P00_DOCUMENT_MACRO_ARGUMENT(P99_FOR, 3)
97 #define P99_FOR(NAME, N, OP, FUNC, ...) P99_PASTE2(P00_FOR, N)(NAME, OP, FUNC, __VA_ARGS__)
98 #endif
99 
100 #define P00_IGN(NAME, X, I)
101 #define P00_IDT(NAME, X, I) X
102 #define P00_POS(NAME, X, I) I
103 #define P00_NAM(NAME, X, I) NAME
104 #define P00_NAME_I(NAME, X, I) P99_PASTE2(NAME, I)
105 #define P00_STR(NAME, X, I) P99_STRINGIFY(X)
106 #define P00_ISIT(WHAT, X, I) (X) WHAT
107 
108 #define P00_SUM(NAME, I, X, Y) ((X) + (Y))
109 #define P00_PROD(NAME, I, X, Y) ((X) * (Y))
110 #define P00_QUOT(NAME, I, X, Y) ((X) / (Y))
111 #define P00_XOR(NAME, I, X, Y) ((X) ^ (Y))
112 #define P00_BOR(NAME, I, X, Y) ((X) | (Y))
113 #define P00_BAND(NAME, I, X, Y) ((X) & (Y))
114 #define P00_OR(NAME, I, X, Y) ((X) || (Y))
115 #define P00_AND(NAME, I, X, Y) ((X) && (Y))
116 #define P00_TOKJOIN(NAME, I, X, Y) X NAME Y
117 
118 #define P00_SEQ(NAME, I, REC, X) REC, X
119 #define P00_SEP(NAME, I, REC, X) REC; X
120 #define P00_SER(NAME, I, REC, X) REC X
121 #define P00_REV(NAME, I, REC, X) X, REC
122 #define P00_PES(NAME, I, REC, X) X; REC
123 #define P00_RES(NAME, I, REC, X) X REC
124 
128 P00_DOCUMENT_NUMBER_ARGUMENT(P99_NAME, 0)
129 #define P99_NAME(N, NAME) P99_FOR(NAME, N, P00_SEQ, P00_NAME_I, P99_REP(N,))
130 
131 #define P00_FUNC(NAME, I, REC, X) NAME(REC, X)
132 
143 P00_DOCUMENT_NUMBER_ARGUMENT(P99_BIGOP, 1)
144 #define P99_BIGOP(OP, M, ...) P99_FOR( , M, OP, P00_IDT, __VA_ARGS__)
145 
153 P00_DOCUMENT_NUMBER_ARGUMENT(P99_BIGFUNC, 1)
154 #define P99_BIGFUNC(FUNC, M, ...) P99_FOR(FUNC, M, P00_FUNC, P00_IDT, __VA_ARGS__)
155 
156 
157 #define P00_REPEAT(MACRO, X, I) MACRO(I)
158 
187 P00_DOCUMENT_MACRO_ARGUMENT(P99_REPEAT, 0)
188 P00_DOCUMENT_NUMBER_ARGUMENT(P99_REPEAT, 1)
189 #define P99_REPEAT(MACRO, N) P99_FOR(MACRO, N, P00_SEQ, P00_REPEAT, P99_DUPL(N,))
190 
221 P00_DOCUMENT_MACRO_ARGUMENT(P99_UNROLL, 0)
222 P00_DOCUMENT_NUMBER_ARGUMENT(P99_UNROLL, 1)
223 #define P99_UNROLL(MACRO, N) P99_FOR(MACRO, N, P00_SEP, P00_REPEAT, P99_DUPL(N,))
224 
225 #define P00_MAP(MACRO, X, I) MACRO(X)
226 
249 P00_DOCUMENT_MACRO_ARGUMENT(P99_SEQ, 0)
250 #define P99_SEQ(MACRO, ...) P00_MAP_(P99_NARG(__VA_ARGS__), MACRO, (,), __VA_ARGS__)
251 
263 P00_DOCUMENT_MACRO_ARGUMENT(P99_SER, 0)
264 #define P99_SER(MACRO, ...) P00_MAP_(P99_NARG(__VA_ARGS__), MACRO, ( ), __VA_ARGS__)
265 
296 P00_DOCUMENT_MACRO_ARGUMENT(P99_SEP, 0)
297 #define P99_SEP(MACRO, ...) P00_MAP_(P99_NARG(__VA_ARGS__), MACRO, (;), __VA_ARGS__)
298 
310 P00_DOCUMENT_MACRO_ARGUMENT(P99_SEA, 0)
311 #define P99_SEA(MACRO, ...) P00_MAP_(P99_NARG(__VA_ARGS__), MACRO, (+), __VA_ARGS__)
312 
324 P00_DOCUMENT_MACRO_ARGUMENT(P99_SEM, 0)
325 #define P99_SEM(MACRO, ...) P00_MAP_(P99_NARG(__VA_ARGS__), MACRO, (*), __VA_ARGS__)
326 
327 
341 #define P99_SUMS(...) P99_BIGOP(P00_SUM, P99_NARG(__VA_ARGS__),__VA_ARGS__)
342 
345 #define P99_PRODS(...) P99_BIGOP(P00_PROD, P99_NARG(__VA_ARGS__),__VA_ARGS__)
346 
349 #define P99_QUOTS(...) P99_BIGOP(P00_QUOT, P99_NARG(__VA_ARGS__),__VA_ARGS__)
350 
353 #define P99_XORS(...) P99_BIGOP(P00_XOR, P99_NARG(__VA_ARGS__),__VA_ARGS__)
354 
357 #define P99_BORS(...) P99_BIGOP(P00_BOR, P99_NARG(__VA_ARGS__),__VA_ARGS__)
358 
361 #define P99_BANDS(...) P99_BIGOP(P00_BAND, P99_NARG(__VA_ARGS__),__VA_ARGS__)
362 
365 #define P99_ORS(...) P99_BIGOP(P00_OR, P99_NARG(__VA_ARGS__),__VA_ARGS__)
366 
369 #define P99_ANDS(...) P99_BIGOP(P00_AND, P99_NARG(__VA_ARGS__),__VA_ARGS__)
370 
371 
385 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IS_ONE, 0)
386 #define P99_IS_ONE(FIRST, ...) P99_FOR(== (FIRST), P99_NARG(__VA_ARGS__), P00_OR, P00_ISIT, __VA_ARGS__)
387 
400 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ARE_EQ, 0)
401 #define P99_ARE_EQ(FIRST, ...) P99_FOR(== (FIRST), P99_NARG(__VA_ARGS__), P00_AND, P00_ISIT, __VA_ARGS__)
402 
415 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IS_MIN, 0)
416 #define P99_IS_MIN(FIRST, ...) P99_FOR(>= (FIRST), P99_NARG(__VA_ARGS__), P00_AND, P00_ISIT, __VA_ARGS__)
417 
431 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IS_INF, 0)
432 #define P99_IS_INF(FIRST, ...) P99_FOR(> (FIRST), P99_NARG(__VA_ARGS__), P00_AND, P00_ISIT, __VA_ARGS__)
433 
446 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IS_MAX, 0)
447 #define P99_IS_MAX(FIRST, ...) P99_FOR(<= (FIRST), P99_NARG(__VA_ARGS__), P00_AND, P00_ISIT, __VA_ARGS__)
448 
462 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IS_SUP, 0)
463 #define P99_IS_SUP(FIRST, ...) P99_FOR(< (FIRST), P99_NARG(__VA_ARGS__), P00_AND, P00_ISIT, __VA_ARGS__)
464 
478 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ARE_ORDERED, 0)
479 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ARE_ORDERED, 1)
480 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ARE_ORDERED, 2)
481 #define P99_ARE_ORDERED(OP, ...) P00_ARE_ORDERED(OP, P99_NARG(__VA_ARGS__), __VA_ARGS__)
482 
483 #define P00_ARE_ORDERED(OP, N, ...) \
484 P99_IF_LT(N, 3) \
485 (P00_ARE_ORDERED2(OP,__VA_ARGS__)) \
486 (P00_ARE_ORDERED3(OP, P99_PRED(N), __VA_ARGS__))
487 
488 #define P00_ARE_ORDERED2(OP, X, Y) (X) OP (Y)
489 
490 #define P00_ARE_ORDERED3(OP, N, ...) \
491 ((P99_SUB(0, 1, __VA_ARGS__)) \
492  OP P00_ARE_ORDERED_MID(OP, P99_PRED(N), __VA_ARGS__) \
493  OP (P99_SUB(N, 1, __VA_ARGS__)))
494 
495 #define P00_ARE_ORDERED_MID(OP, N, ...) \
496 P99_FOR(OP, N, P00_ARE_ORDERED_OP, P00_ARE_ORDERED_AND, P99_SUB(1, N, __VA_ARGS__))
497 
498 #define P00_ARE_ORDERED_AND(_0, X, _2) (X)) && ((X)
499 #define P00_ARE_ORDERED_OP(OP, _1, X, Y) X OP Y
500 
501 
502 
516 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_TOKJOIN, 0)
517 #define P99_TOKJOIN(TOK, ...) \
518 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
519 (__VA_ARGS__) \
520 (P99_FOR(TOK, P99_NARG(__VA_ARGS__), P00_TOKJOIN, P00_IDT, __VA_ARGS__))
521 
526 #define P99_REVS(...) P00_REVS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
527 
528 #define P00_REVS(N, ...) P99_PASTE2(P00_REVS_, P99_IS_LT(N, 2))(N, __VA_ARGS__)
529 
530 #define P00_REVS_0(N, ...) P00_REVS_(N,__VA_ARGS__)
531 #define P00_REVS_1(N, ...) __VA_ARGS__
532 
533 /* the general case for an argument list of at least two elements */
534 #define P00_REVS_(N, ...) P99_FOR(,N, P00_REV, P00_IDT, __VA_ARGS__)
535 
548 #define P99_DIV(A, B) P99_CHS(A, P99_FOR(B, 32, P00_SEQ, P00_IDI, P00_ALL_ONES()))
549 
550 #define P00_IDI(B, X, I) P99_DUPL(B, I)
551 
552 
553 #define P00_CDIM_OP(NAME, I, REC, X) (X + ((NAME)[I] * REC))
554 #define P00_CDIM_FUNC(NAME, X, I) (X)
555 #define P00_CDIM(N, NAME, ...) P99_FOR(NAME, N, P00_CDIM_OP, P00_CDIM_FUNC, __VA_ARGS__)
556 
579 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_CDIM, 0)
580 #define P99_CDIM(NAME, ...) P00_CDIM(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
581 
582 
588 #define P00_SUBSCRIPT(X) [X]
589 
594 #define P99_SUBSCRIPT(...) P99_SER(P00_SUBSCRIPT, __VA_ARGS__)
595 
596 #define P99_ARRAY(ARR, ...) (ARR)P99_SUBSCRIPT(__VA_ARGS__)
597 #define P99_AREF(T, ARR, ...) T P99_ARRAY(*const ARR, __VA_ARGS__)
598 #define P99_AREF1(T, ARR, ...) T P99_ARRAY(ARR, static const 1, __VA_ARGS__)
599 
600 #define P00_ALEN0(NAME) \
601  ((sizeof(NAME)/sizeof((NAME)[0])) \
602  /sizeof(char[((!(sizeof(NAME) % sizeof((NAME)[0])))<<1)-1]))
603 
604 #define P00_ALEN(NAME, _1, I) P99_IF_EQ_0(I)(P00_ALEN0(NAME))(P00_ALEN0((NAME)P99_REP(I,[0])))
605 #define P00_ALEN2_(NAME, I, ...) P00_ALEN(NAME,,I)
606 #define P00_ALEN2(NAME, ...) P00_ALEN2_(NAME, __VA_ARGS__,)
607 
608 #define P00_ALENS0(NAME, I, REC, _3) REC, P00_ALEN(NAME,,I)
609 
613 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_ALENS, 0)
614 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ALENS, 1)
615 #define P99_ALENS(ARR, N) P99_FOR(ARR, N, P00_ALENS0, P00_ALEN, P99_REP(N,))
616 
617 
622 #define P99_ATYPE(T, A, B, N) P99_AREF(T, A, P99_ALENS(*B, N))
623 
624 
625 #define P00_AALLOC(...) ((__VA_ARGS__)malloc(sizeof *(__VA_ARGS__){ 0 }))
626 
631 P00_DOCUMENT_TYPE_ARGUMENT(P99_AALLOC, 0)
632 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_AALLOC, 1)
633 #define P99_AALLOC(T, VB, N) P00_AALLOC(P99_ATYPE(T, , VB, N))
634 
635 #define P00_ACALL1(ARR) P99_ALENS(*ARR, 1), (ARR)
636 #define P00_ACALL2(ARR, N) P99_ALENS(*ARR, N), (ARR)
637 /* The three argument form asserts that pointers to the elements of
638  the matrix are assignment compatible to pointers of the indicated type.
639  Then we do the cast to the pointer to matrix type that would
640  otherwise be dangerous and could hide incompatibilities. */
641 #define P00_ACALL3(ARR, N, TYPE) P99_ALENS(*ARR, N), ((TYPE (*const)P99_SUBSCRIPT(P99_ALENS(*ARR, N)))(TYPE*const){ &((*ARR)P99_REP(N,[0])) })
642 
643 /* transform a list of names into size_t declarations */
644 #define P00_AARG_DECL(X) size_t const X
645 #define P00_AARG_LIST(N, ...) P99_SEQ(P00_AARG_DECL, __VA_ARGS__)
646 
647 /* generate a list of size_t's and the declaration of the array
648  pointer */
649 #define P00_AARG_0(T, ARR, DIM, ...) P00_AARG_LIST(DIM, __VA_ARGS__), P99_AREF1(T, ARR, __VA_ARGS__)
650 #define P00_AARG(T, ARR, DIM, INAME) P00_AARG_0(T, ARR, DIM, P99_NAME(DIM, INAME))
651 
652 /* capture the special cases do implement default arguments */
653 #define P00_AARG_3(T, ARR, DIM) P00_AARG(T, ARR, DIM, P99_PASTE(p00_aarg_, ARR))
654 #define P00_AARG_2(T, ARR) P00_AARG_3(T, ARR, 1)
655 
656 /* generate a list of size_t's and the declaration of the array
657  pointer */
658 #define P00_ANAME_0(ARR, DIM, ...) __VA_ARGS__, ARR
659 #define P00_ANAME(ARR, DIM, INAME) P00_ANAME_0(ARR, DIM, P99_NAME(DIM, INAME))
660 
661 /* capture the special cases do implement default arguments */
662 #define P00_ANAME_2(ARR, DIM) P00_ANAME(ARR, DIM, P99_PASTE(p00_aarg_, ARR))
663 #define P00_ANAME_1(ARR) P00_ANAME_2(ARR, 1)
664 
665 #ifdef P00_DOXYGEN
666 
676 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_ALEN, 0)
677 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ALEN, 1)
678 #define P99_ALEN(ARR, N)
679 
722 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_ACALL, 0)
723 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACALL, 1)
724 P00_DOCUMENT_TYPE_ARGUMENT(P99_ACALL, 2)
725 #define P99_ACALL(ARR, N, TYPE)
726 
748 P00_DOCUMENT_TYPE_ARGUMENT(P99_AARG, 0)
749 P00_DOCUMENT_NUMBER_ARGUMENT(P99_AARG, 2)
750 #define P99_AARG(TYPE, NAME, DIM, VAR)
751 
762 P00_DOCUMENT_TYPE_ARGUMENT(P99_ANAME, 0)
763 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ANAME, 2)
764 #define P99_ANAME(NAME, DIM, VAR)
765 
766 #else
767 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_ALEN, 0)
768 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ALEN, 1)
769 #define P99_ALEN(...) P99_IF_EQ_1(P99_NARG(__VA_ARGS__))(P00_ALEN(__VA_ARGS__, ,0))(P00_ALEN2(__VA_ARGS__))
770 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_ACALL, 0)
771 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACALL, 1)
772 P00_DOCUMENT_TYPE_ARGUMENT(P99_ACALL, 2)
773 #define P99_ACALL(...) P99_PASTE2(P00_ACALL, P99_NARG(__VA_ARGS__))(__VA_ARGS__)
774 P00_DOCUMENT_TYPE_ARGUMENT(P99_AARG, 0)
775 P00_DOCUMENT_NUMBER_ARGUMENT(P99_AARG, 2)
776 #define P99_AARG(...) P99_IF_GT(P99_NARG(__VA_ARGS__),3)(P00_AARG(__VA_ARGS__))(P99_PASTE2(P00_AARG_, P99_NARG(__VA_ARGS__))(__VA_ARGS__))
777 P00_DOCUMENT_TYPE_ARGUMENT(P99_ANAME, 0)
778 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ANAME, 2)
779 #define P99_ANAME(...) P99_IF_GT(P99_NARG(__VA_ARGS__),2)(P00_ANAME(__VA_ARGS__))(P99_PASTE2(P00_ANAME_, P99_NARG(__VA_ARGS__))(__VA_ARGS__))
780 
781 #endif
782 
817 #define P99_PARALLEL_FOR _Pragma(P99_PARALLEL_PRAGMA) for
818 
819 
820 #define P00_PRAGMA_DO(PRAG, TYPE, VAR, LOW, LEN, INCR) \
821 P00_BLK_START \
822 P00_BLK_BEFORE(const TYPE \
823  P99_PASTE2(p00_start_, VAR) = (LOW), \
824  P99_PASTE2(p00_stop_, VAR) = P99_PASTE2(p00_start_, VAR) + (LEN), \
825  P99_PASTE2(p00_incr_, VAR) = (INCR)) \
826 P99_PRAGMA(PRAG) \
827  for (register TYPE P99_PASTE2(p00_i_, VAR) = P99_PASTE2(p00_start_, VAR); \
828  P99_PASTE2(p00_i_, VAR) < P99_PASTE2(p00_stop_, VAR); \
829  P99_PASTE2(p00_i_, VAR) += P99_PASTE2(p00_incr_, VAR)) \
830  P00_BLK_START \
831  P00_BLK_BEFORE(TYPE const VAR = P99_PASTE2(p00_i_, VAR))
832 
833 #ifdef P00_DOXYGEN
834 
882 #define P99_DO(TYPE, VAR, LOW, LEN, INCR) for(;;)
883 
889 #define P99_PARALLEL_DO(TYPE, VAR, LOW, LEN, INCR) for(;;)
890 
897 #define P99_PRAGMA_DO(PRAG, TYPE, VAR, LOW, LEN, INCR) for(;;)
898 #else
899 P00_DOCUMENT_TYPE_ARGUMENT(P99_DO, 0)
900 #define P99_DO(TYPE, VAR, ...) P99_PRAGMA_DO(, TYPE, VAR, __VA_ARGS__)
901 P00_DOCUMENT_TYPE_ARGUMENT(P99_PARALLEL_DO, 0)
902 #define P99_PARALLEL_DO(TYPE, VAR, ...) P99_PRAGMA_DO(P99_PARALLEL_PRAGMA, TYPE, VAR, __VA_ARGS__)
903 P00_DOCUMENT_TYPE_ARGUMENT(P99_PRAGMA_DO, 1)
904 #define P99_PRAGMA_DO(PRAG, TYPE, VAR, ...) \
905 P99_IF_EQ(P99_NARG(__VA_ARGS__), 2) \
906 (P00_PRAGMA_DO(PRAG, TYPE, VAR, __VA_ARGS__, 1)) \
907 (P00_PRAGMA_DO(PRAG, TYPE, VAR, __VA_ARGS__))
908 #endif
909 
910 #define P00_FORALL_OP(NAME, I, REC, X) REC X
911 
912 #define P00_FORALL_FUNC(NAME, X, I) P99_DO(size_t, X, 0, (NAME)[I])
913 
914 #define P00_FORALL(N, NAME, ...) P99_FOR(NAME, N, P00_FORALL_OP, P00_FORALL_FUNC, __VA_ARGS__)
915 
955 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FORALL, 0)
956 #define P99_FORALL(NAME, ...) P00_FORALL(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
957 
958 #define P00_PARALLEL_FORALL_FUNC(NAME, X, I) P99_PARALLEL_DO(size_t, X, 0, (NAME)[I])
959 #define P00_PARALLEL_FORALL(N, NAME, ...) P99_FOR(NAME, N, P00_FORALL_OP, P00_PARALLEL_FORALL_FUNC, __VA_ARGS__)
960 
977 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_PARALLEL_FORALL, 0)
978 #define P99_PARALLEL_FORALL(NAME, ...) P00_PARALLEL_FORALL(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
979 
980 
981 #define P00_CASERANGE0(NAME, X, I) case ((NAME)+I):
982 #define P00_CASERANGE3(START, LEN, LABEL) \
983 if (0) { \
984  /* Execution will only go here if one of the cases is chosen. */ \
985  P99_FOR(START, LEN, P00_SEP, P00_CASERANGE0, P99_REP(LEN,)) \
986  /* Then it just continues with the else part */ \
987  goto LABEL; \
988  } else \
989  /* execution will just fall through, here, if a previous case \
990  matched */ \
991  LABEL
992 
993 #define P00_CASERANGE1(START, LEN, ...) P00_CASERANGE3(START, LEN, P99_UNIQ(__VA_ARGS__, caselabel))
994 #define P00_CASERANGE2(START, LEN) P00_CASERANGE3(START, LEN, P99_UNIQ(caselabel))
995 
996 
997 #ifdef P00_DOXYGEN
998 
1038 #define P99_CASERANGE(START, LEN, ...)
1039 #else
1040 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_CASERANGE, 0)
1041 P00_DOCUMENT_NUMBER_ARGUMENT(P99_CASERANGE, 1)
1042 #define P99_CASERANGE(START, ...) \
1043 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
1044 (P00_CASERANGE2(START, __VA_ARGS__)) \
1045 (P00_CASERANGE1(START, __VA_ARGS__))
1046 #endif
1047 
1048 
1049 #define P00_STRUCT_TYPENAME(BASE, DECL) P99_PASTE3(DECL, _P99_typedef_of_, BASE)
1050 #define P00_STRUCT_TYPEDEF(BASE, DECL, I) typedef P00_STRUCT_TYPENAME(BASE, DECL)
1051 #define P00_STRUCT_TYPEDEFS(NAME, ...) P99_FOR(NAME, P99_NARG(__VA_ARGS__), P00_SEP, P00_STRUCT_TYPEDEF, __VA_ARGS__)
1052 
1053 
1069 #define P99_DEFINE_STRUCT(NAME, ...) \
1070 struct NAME { \
1071  P99_SEP(P00_IDENT, __VA_ARGS__); \
1072 }; \
1073 P00_STRUCT_TYPEDEFS(NAME, __VA_ARGS__)
1074 
1075 
1076 #define P00_STRUCT_USE3(TYPE, VAR, NAME) P00_STRUCT_TYPENAME(TYPE, NAME) NAME = (VAR)->NAME
1077 #define P00_STRUCT_USE2(PAIR, NAME) P00_STRUCT_USE3(PAIR, NAME)
1078 #define P00_STRUCT_USE(PAIR, NAME, I) P00_STRUCT_USE2(P00_ROBUST PAIR, NAME)
1079 
1089 P00_DOCUMENT_TYPE_IDENTIFIER_ARGUMENT(P99_STRUCT_USE, 0)
1090 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_USE, 1)
1091 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_USE, 2)
1092 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_USE, 3)
1093 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_USE, 4)
1094 #define P99_STRUCT_USE(TYPE, VAR, ...) P99_FOR((TYPE, VAR), P99_NARG(__VA_ARGS__), P00_SEP, P00_STRUCT_USE, __VA_ARGS__)
1095 
1096 #define P00_STRUCT_UNUSE3(TYPE, VAR, NAME) P00_STRUCT_TYPENAME(TYPE, NAME) (VAR)->NAME = NAME
1097 #define P00_STRUCT_UNUSE2(PAIR, NAME) P00_STRUCT_UNUSE3(PAIR, NAME)
1098 #define P00_STRUCT_UNUSE(PAIR, NAME, I) P00_STRUCT_UNUSE2(P00_ROBUST PAIR, NAME)
1099 
1106 P00_DOCUMENT_TYPE_IDENTIFIER_ARGUMENT(P99_STRUCT_UNUSE, 0)
1107 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_UNUSE, 1)
1108 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_UNUSE, 2)
1109 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_UNUSE, 3)
1110 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_UNUSE, 4)
1111 #define P99_STRUCT_UNUSE(TYPE, VAR, ...) P99_FOR((TYPE, VAR), P99_NARG(__VA_ARGS__), P00_SEP, P00_STRUCT_UNUSE, __VA_ARGS__)
1112 
1113 #define P00_LITERAL(NAME) .NAME = NAME
1114 
1121 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_LITERAL, 0)
1122 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_LITERAL, 1)
1123 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_LITERAL, 2)
1124 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_LITERAL, 3)
1125 #define P99_LITERAL(...) P99_SEQ(P00_LITERAL, __VA_ARGS__)
1126 
1127 
1135 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_LITERAL, 0)
1136 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_LITERAL, 1)
1137 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_LITERAL, 2)
1138 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_LITERAL, 3)
1139 #define P99_STRUCT_LITERAL(TYPE, ...) (TYPE){ P99_SEQ(P00_LITERAL, __VA_ARGS__) }
1140 
1141 #define P00_STRUCT_TYPES(TYPE, NAME, I) P00_STRUCT_TYPENAME(TYPE, NAME)
1142 
1150 P00_DOCUMENT_TYPE_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPES, 0)
1151 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPES, 1)
1152 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPES, 2)
1153 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPES, 3)
1154 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPES, 4)
1155 #define P99_STRUCT_TYPES(TYPE, ...) P99_FOR(TYPE, P99_NARG(__VA_ARGS__), P00_SEQ, P00_STRUCT_TYPES, __VA_ARGS__)
1156 
1157 #define P00_STRUCT_TYPE0(TYPE, NAME, I) P99_0(P00_STRUCT_TYPENAME(TYPE, NAME))
1158 
1166 P00_DOCUMENT_TYPE_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPE0, 0)
1167 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPE0, 1)
1168 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPE0, 2)
1169 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPE0, 3)
1170 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_STRUCT_TYPE0, 4)
1171 #define P99_STRUCT_TYPE0(TYPE, ...) P99_FOR(TYPE, P99_NARG(__VA_ARGS__), P00_SEQ, P00_STRUCT_TYPE0, __VA_ARGS__)
1172 
1173 
1174 #define P00_MAC_ARGS_TYPE_(NAME, EXP, QUAL, ...) __typeof__(EXP)
1175 #define P00_MAC_ARGS_EXP_(NAME, EXP, QUAL, ...) (EXP)
1176 #define P00_MAC_ARGS_QUAL_(NAME, EXP, QUAL, ...) QUAL
1177 
1178 #define P00_MAC_ARGS_NAME(NAME, ...) NAME
1179 #define P00_MAC_ARGS_TYPE(...) P00_MAC_ARGS_TYPE_(__VA_ARGS__,)
1180 
1181 #define P00_MAC_ARGS_EXP(...) P00_MAC_ARGS_EXP_(__VA_ARGS__,)
1182 
1183 #define P00_MAC_ARGS_QUAL(...) P00_MAC_ARGS_QUAL_(__VA_ARGS__,)
1184 
1185 #define P00_MAC_ARGS_REAL0(_0, PAIR, I) \
1186 P00_MAC_ARGS_TYPE PAIR \
1187 P00_MAC_ARGS_QUAL PAIR \
1188 P99_PASTE2(p00_mac_arg_, I) \
1189 = P00_MAC_ARGS_EXP PAIR
1190 
1191 #define P00_MAC_ARGS_REAL1(_0, PAIR, I) \
1192 P00_MAC_ARGS_TYPE PAIR \
1193 P00_MAC_ARGS_QUAL PAIR \
1194 P00_MAC_ARGS_NAME PAIR \
1195  = P99_PASTE2(p00_mac_arg_, I)
1196 
1234 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MAC_ARGS, 0)
1235 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MAC_ARGS, 1)
1236 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MAC_ARGS, 2)
1237 #define P99_MAC_ARGS(...) \
1238 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEP, P00_MAC_ARGS_REAL0, __VA_ARGS__); \
1239 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEP, P00_MAC_ARGS_REAL1, __VA_ARGS__)
1240 
1241 #define P00_MACRO_VAR(NAME, EXP, ...) \
1242 __typeof__(EXP) __VA_ARGS__ P99_PASTE2(p00_macro_var_, NAME) = (EXP), \
1243  NAME = P99_PASTE2(p00_macro_var_, NAME)
1244 
1245 #define P00_MACRO_PVAR(NAME, EXP, ...) \
1246 __typeof__(*(EXP)) __VA_ARGS__* P99_PASTE2(p00_macro_var_, NAME) = (EXP), \
1247  * NAME = P99_PASTE2(p00_macro_var_, NAME)
1248 
1249 #ifdef DOXYGEN
1250 
1267 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_MACRO_VAR, 0)
1268 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MACRO_VAR, 1)
1269 # define P99_MACRO_VAR(NAME, EXPR, QUAL)
1270 
1287 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_MACRO_PVAR, 0)
1288 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MACRO_PVAR, 1)
1289 # define P99_MACRO_PVAR(NAME, EXPR, QUAL)
1290 #else
1291 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_MACRO_VAR, 0)
1292 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MACRO_VAR, 1)
1293 # define P99_MACRO_VAR(NAME, ...) \
1294 P99_IF_EQ_1(P99_NARG(__VA_ARGS__)) \
1295 (P00_MACRO_VAR(NAME, __VA_ARGS__,)) \
1296 (P00_MACRO_VAR(NAME, __VA_ARGS__))
1297 
1298 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_MACRO_PVAR, 0)
1299 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MACRO_PVAR, 1)
1300 # define P99_MACRO_PVAR(NAME, ...) \
1301 P99_IF_EQ_1(P99_NARG(__VA_ARGS__)) \
1302 (P00_MACRO_PVAR(NAME, __VA_ARGS__,)) \
1303 (P00_MACRO_PVAR(NAME, __VA_ARGS__))
1304 #endif
1305 
1306 #endif /* !P99_FOR_H_ */
P99_MAC_ARGS
#define P99_MAC_ARGS(...)
Declare macro parameters as local variables as if the macro were declared as a type generic inline fu...
Definition: p99_for.h:1236
P99_ARE_EQ
#define P99_ARE_EQ(FIRST,...)
Check if the arguments in the list are all equal.
Definition: p99_for.h:401
P99_MACRO_VAR
#define P99_MACRO_VAR(NAME, EXPR, QUAL)
Define a variable with NAME that has the type and value of EXPR.
Definition: p99_for.h:1268
P99_LITERAL
#define P99_LITERAL(...)
Copy local variables back to the fields of same name inside a literal.
Definition: p99_for.h:1124
P99_NAME
#define P99_NAME(N, NAME)
generate lists of names of the form NAME0, NAME1, ...
Definition: p99_for.h:129
P99_TOKJOIN
#define P99_TOKJOIN(TOK,...)
join a list with a specific token given as the first argument
Definition: p99_for.h:517
P99_STRUCT_UNUSE
#define P99_STRUCT_UNUSE(TYPE, VAR,...)
Copy local variables back to the fields of variable VAR.
Definition: p99_for.h:1110
P99_STRUCT_TYPE0
#define P99_STRUCT_TYPE0(TYPE,...)
Transform the argument list into a list of lvalue for the fields of type TYPE.
Definition: p99_for.h:1170
P99_FORALL
#define P99_FORALL(NAME,...)
A multi-index for loop.
Definition: p99_for.h:956
p99_block.h
Macros that implement controlling blocks.
P99_SER
#define P99_SER(MACRO,...)
Apply the macro MACRO to the rest of the argument list.
Definition: p99_for.h:264
P99_SEP
#define P99_SEP(MACRO,...)
Apply the macro MACRO to the rest of the argument list.
Definition: p99_for.h:297
P99_SEM
#define P99_SEM(MACRO,...)
Apply the macro MACRO to the rest of the argument list.
Definition: p99_for.h:325
P99_ALEN
#define P99_ALEN(ARR, N)
Produce the length of the argument array ARR in terms of number of elements.
Definition: p99_for.h:678
P99_IS_MIN
#define P99_IS_MIN(FIRST,...)
Check if argument FIRST is less than the other elements in the list.
Definition: p99_for.h:416
P99_CDIM
#define P99_CDIM(NAME,...)
Compute an absolute index in a multidimensional array in the same way as C.
Definition: p99_for.h:580
P99_REPEAT
#define P99_REPEAT(MACRO, N)
Apply the macro MACRO N times.
Definition: p99_for.h:189
P99_AARG
#define P99_AARG(TYPE, NAME, DIM, VAR)
Declare a pointer to array function argument of basetype TYPE, with name NAME, dimension DIM and nami...
Definition: p99_for.h:750
P99_PARALLEL_FORALL
#define P99_PARALLEL_FORALL(NAME,...)
A multi-index for loop who's dependent statement or block may be executed out of order.
Definition: p99_for.h:978
P99_CASERANGE
#define P99_CASERANGE(START, LEN,...)
implement a range syntax for case labels.
Definition: p99_for.h:1037
P99_IS_MAX
#define P99_IS_MAX(FIRST,...)
Check if argument FIRST is strictly greater than the other elements in the list.
Definition: p99_for.h:447
P99_STRUCT_TYPES
#define P99_STRUCT_TYPES(TYPE,...)
Transform the argument list into a list of field types for type TYPE.
Definition: p99_for.h:1154
P99_IS_SUP
#define P99_IS_SUP(FIRST,...)
Check if argument FIRST is greater than or equal to the other elements in the list.
Definition: p99_for.h:463
P99_PRAGMA_DO
#define P99_PRAGMA_DO(PRAG, TYPE, VAR, LOW, LEN, INCR)
as P99_DO but allows you to additionally place a pragma directive in front of the generated for loop
Definition: p99_for.h:897
P99_IS_ONE
#define P99_IS_ONE(FIRST,...)
Check if argument FIRST is equal to one of the other elements in the list.
Definition: p99_for.h:386
P99_IS_INF
#define P99_IS_INF(FIRST,...)
Check if argument FIRST is less than or equal to the other elements in the list.
Definition: p99_for.h:432
P99_ACALL
#define P99_ACALL(ARR, N, TYPE)
Pass a pointer to an N dimensional array ARR to a function.
Definition: p99_for.h:725
P99_SEQ
#define P99_SEQ(MACRO,...)
Apply the macro MACRO to the rest of the argument list.
Definition: p99_for.h:250
P99_MACRO_PVAR
#define P99_MACRO_PVAR(NAME, EXPR, QUAL)
Define a variable with NAME that has the type and value of EXPR, where EXPR is of a pointer type.
Definition: p99_for.h:1288
P99_SEA
#define P99_SEA(MACRO,...)
Apply the macro MACRO to the rest of the argument list.
Definition: p99_for.h:311
P99_ARE_ORDERED
#define P99_ARE_ORDERED(OP,...)
Check if the arguments in the list are ordered according to the operation OP.
Definition: p99_for.h:481
P99_DO
#define P99_DO(TYPE, VAR, LOW, LEN, INCR)
A fortran like do-loop with bounds that are fixed at the beginning.
Definition: p99_for.h:882
P99_STRUCT_USE
#define P99_STRUCT_USE(TYPE, VAR,...)
Use the fields of variable VAR of type TYPE.
Definition: p99_for.h:1093
P99_STRUCT_LITERAL
#define P99_STRUCT_LITERAL(TYPE,...)
Copy local variables back to the fields of same name inside a compound literal of type TYPE.
Definition: p99_for.h:1138
P99_ALENS
#define P99_ALENS(ARR, N)
Produce a list of the lengths of the argument array ARR in terms of the number of elements in the fir...
Definition: p99_for.h:615
P99_BIGFUNC
#define P99_BIGFUNC(FUNC, M,...)
Realize the right associative call of binary function FUNC of all the arguments.
Definition: p99_for.h:154
P99_UNROLL
#define P99_UNROLL(MACRO, N)
Apply the macro MACRO N times.
Definition: p99_for.h:223
P99_ANAME
#define P99_ANAME(NAME, DIM, VAR)
Declare list of variable names as produced by P99_AARG.
Definition: p99_for.h:764
P99_BIGOP
#define P99_BIGOP(OP, M,...)
Realize the right associative operation OP of all the arguments.
Definition: p99_for.h:144
P99_FOR
#define P99_FOR(NAME, N, OP, FUNC,...)
A preprocessor pseudo iterator.
Definition: p99_for.h:92
P99_PARALLEL_DO
#define P99_PARALLEL_DO(TYPE, VAR, LOW, LEN, INCR)
as P99_DO but performs the iterations out of order
Definition: p99_for.h:889
P99_AALLOC
#define P99_AALLOC(T, VB, N)
Allocate a new matrix of base type T and with N dimensions as given by VB.
Definition: p99_for.h:633