eĿlipsis
a language independent preprocessor
 
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Loading...
Searching...
No Matches
Fibonacci.h
Go to the documentation of this file.
1
28# ifndef FIBONACCI
29/*
30 * This the initial execution that sets up all the macros. They are
31 * created with @ref bind so they will cease to exist, once this upper
32 * level of recursion is terminated.
33 */
34
35# bind FIB0() 0U
36# bind FIB1() 1U
37# bind FIB2()
38
39/*
40 * This macro collects all the values by means of @ref gather,
41 * later. There are special comments, that help to indent (the ones
42 * with a >) and to skip to the next line (the one with the ^).
43 */
44# bind FIBONACCI() /*>*/0U, /*^*//*>*/1U
45
46/*
47 * And then the top level recursive call. We only want to expand the
48 * directives, so we use @ref include_directives, but we also want to
49 * expand the name of the file to this same file so we prefix this
50 * directive with @ref expand.
51 */
52# expand include_directives __FILE__
53
54/*
55 * @brief An array with the first __NARGS__(FIBONACCI()) Fibonacci numbers
56 *
57 * It calls @ref FIBONACCI twice, once for the number of elements
58 * (counted with @ref __NARGS__) and then for the initializer. Most
59 * probably you will see that the integers here are 64 bit wide and
60 * that there are 94 Fibonacci numbers that fit into 64 bit.
61 *
62 * But what do we know about your platform? So we compute the value of
63 * the biggest unsigned number and ask C23's `typeof` to give us the
64 * correct type where all these Fibonacci numbers fit.
65 */
66constexpr typeof(__EXPAND_DEC_U__(-1U)) Fibonacci[__NARGS__(FIBONACCI())] = {
67FIBONACCI()
68};
69/*
70 * Check for possible overflow. We check if the sum of the two current
71 * values would be greater than the biggest unsigned value that the
72 * preprocessor can handle.
73 */
74# elif FIB1() <= ((-1U)-FIB0())
75/*
76 * Set FIB2() to that new value which is the sum of the two current
77 * values. This sum is evaluated and expanded before being assigned to
78 * FIB2().
79 */
80# undef FIB2
81# expand bind FIB2() __EXPAND_DEC_U__(FIB0() + FIB1())
82/* collect the contents of the expansion of FIB2() to the end of
83 FIBONACCI. Here the macro @ref ELLIPSIS_MARK_LINE is either empty
84 (normal operation of `ellipsis`) or adds the line number operation
85 (when using ellipsis-gnuc.sh) */
86# expand gather FIBONACCI ,/*^*/ELLIPSIS_MARK_LINE/*>*/FIB2()
87/* shift of FIB2 → FIB1 → FIB0. Here these macros are not expanded, it
88 is their definitions that are shifted around. */
89# move FIB0 FIB1
90# move FIB1 FIB2
91/*
92 * And then next recursive call. The ideas are the same as for the
93 * first.
94 */
95# expand include_directives __FILE__
96/*
97 * There is no else clause, so recursion stops as soon as the @ref
98 * elif condition is not fulfilled any more.
99 */
100# endif
#define __NARGS__(…)
expand all the arguments and count the number of items in the resulting list
Definition ellipsis-predefined.dirs:86
#define __EXPAND_DEC_U__(…)
expand all the arguments, evaluate the resulting integer expression and produce a decimal literal
Definition ellipsis-predefined.dirs:51