Squashed 'third_party/boostorg/preprocessor/' content from commit 56090c5

Change-Id: I8c0a13225778c3751a35945439d5304bd9e639ef
git-subtree-dir: third_party/boostorg/preprocessor
git-subtree-split: 56090c56b5c78418b6dbe8c3c2ba576395152f83
diff --git a/doc/examples/array_arithmetic.c b/doc/examples/array_arithmetic.c
new file mode 100644
index 0000000..ba1efc6
--- /dev/null
+++ b/doc/examples/array_arithmetic.c
@@ -0,0 +1,196 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* This example implements over 2200 functions for 1-dimensional arithmetic
+#  * array manipulation in C.  The idea is to use preprocessor data structures,
+#  * lists, and tuples for storing metainformation to be used for generating
+#  * the actual C code.
+#  *
+#  * Who needs templates anyway? :)
+#  * 
+#  * Compile with any C compiler with a standards conforming preprocessor.
+#  */
+#
+# include <boost/preprocessor/comparison/less.hpp>
+# include <boost/preprocessor/control/if.hpp>
+# include <boost/preprocessor/list/at.hpp>
+# include <boost/preprocessor/list/cat.hpp>
+# include <boost/preprocessor/list/for_each_product.hpp>
+# include <boost/preprocessor/logical/or.hpp>
+# include <boost/preprocessor/tuple/to_list.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# /* Information about C operators */
+#
+# /* Accessors for the operator datatype. */
+# define OP_SYMBOL(O)      BOOST_PP_TUPLE_ELEM(5, 0, O)
+# define OP_NAME(O)        BOOST_PP_TUPLE_ELEM(5, 1, O)
+# define OP_IS_FLOATING(O) BOOST_PP_TUPLE_ELEM(5, 2, O)
+# define OP_IS_LOGICAL(O)  BOOST_PP_TUPLE_ELEM(5, 3, O)
+# define OP_IS_SHIFT(O)    BOOST_PP_TUPLE_ELEM(5, 4, O)
+#
+# /* List of applicative unary operators. */
+# define APPLICATIVE_UNARY_OPS \
+   BOOST_PP_TUPLE_TO_LIST( \
+      3, \
+      ( \
+         ( ! , logical_not, 1, 1, 0), \
+         ( ~ , bitwise_not, 0, 0, 0), \
+         ( - , neg,         1, 0, 0) \
+      ) \
+   ) \
+   /**/
+#
+# /* List of applicative binary operators. */
+# define APPLICATIVE_BINARY_OPS \
+   BOOST_PP_TUPLE_TO_LIST( \
+      18, \
+      ( \
+         ( *  , mul           ,1 ,0 ,0), \
+         ( /  , div           ,1 ,0 ,0), \
+         ( %  , mod           ,0 ,0 ,0), \
+         ( +  , add           ,1 ,0 ,0), \
+         ( -  , sub           ,1 ,0 ,0), \
+         ( << , shift_left    ,0 ,0 ,1), \
+         ( >> , shift_right   ,0 ,0 ,1), \
+         ( <  , less          ,1 ,1 ,0), \
+         ( <= , less_equal    ,1 ,1 ,0), \
+         ( >= , greater_equal ,1 ,1 ,0), \
+         ( >  , greater       ,1 ,1 ,0), \
+         ( == , equal         ,1 ,1 ,0), \
+         ( != , not_equal     ,1 ,1 ,0), \
+         ( &  , bitwise_and   ,0 ,0 ,0), \
+         ( |  , bitwise_or    ,0 ,0 ,0), \
+         ( ^  , bitwise_xor   ,0 ,0 ,0), \
+         ( && , logical_and   ,1 ,1 ,0), \
+         ( || , logical_or    ,1 ,1 ,0) \
+      ) \
+   ) \
+   /**/
+#
+# /* Information about C built-in types. */
+#
+# /* Accessors for the type datatype. */
+# define TYPE_NAME(T)         BOOST_PP_TUPLE_ELEM(4, 0, T)
+# define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE_ELEM(4, 1, T)
+# define TYPE_IS_FLOATING(T)  BOOST_PP_TUPLE_ELEM(4, 2, T)
+# define TYPE_RANK(T)         BOOST_PP_TUPLE_ELEM(4, 3, T)
+#
+# /* List of C built-in types. */
+# define BUILTIN_TYPES \
+   BOOST_PP_TUPLE_TO_LIST( \
+      12, \
+      ( \
+         ( signed char    ,sc, 0, 1), \
+         ( char           ,ch, 0, 1), \
+         ( unsigned char  ,uc, 0, 1), \
+         ( short          ,ss, 0, 2), \
+         ( unsigned short ,us, 0, 2), \
+         TYPE_INT, \
+         ( unsigned       ,ui, 0, 4), \
+         ( long           ,sl, 0, 5), \
+         ( unsigned long  ,ul, 0, 6), \
+         ( float          ,fl, 1, 7), \
+         ( double         ,db, 1, 8), \
+         ( long double    ,ld, 1, 9) \
+      ) \
+   ) \
+   /**/
+#
+# /* Type int is needed in some type computations. */
+# define TYPE_INT (int, si, 0, 3)
+#
+# /* Type computation macros. */
+# define TYPE_OF_INTEGER_PROMOTION(T) \
+   BOOST_PP_IF( \
+      BOOST_PP_LESS(TYPE_RANK(T), TYPE_RANK(TYPE_INT)), \
+      TYPE_INT, T \
+   ) \
+   /**/
+# define TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L, R) \
+   TYPE_OF_INTEGER_PROMOTION( \
+      BOOST_PP_IF( \
+         BOOST_PP_LESS(TYPE_RANK(L), TYPE_RANK(R)), \
+         R, L \
+      ) \
+   ) \
+   /**/
+# define TYPE_OF_UNARY_OP(O, T) \
+   BOOST_PP_IF( \
+      OP_IS_LOGICAL(O), \
+      TYPE_INT, TYPE_OF_INTEGER_PROMOTION(T) \
+   ) \
+   /**/
+# define TYPE_OF_BINARY_OP(O, L, R) \
+   BOOST_PP_IF( \
+      OP_IS_LOGICAL(O), TYPE_INT, \
+      BOOST_PP_IF( \
+         OP_IS_SHIFT(O), \
+         TYPE_OF_INTEGER_PROMOTION(L), \
+         TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L,R) \
+      ) \
+   ) \
+   /**/
+# define IS_VALID_UNARY_OP_AND_TYPE_COMBINATION(O, T) \
+   BOOST_PP_IF( \
+      TYPE_IS_FLOATING(T), \
+      OP_IS_FLOATING(O), 1 \
+   ) \
+   /**/
+# define IS_VALID_BINARY_OP_AND_TYPE_COMBINATION(O, L, R) \
+   BOOST_PP_IF( \
+      BOOST_PP_OR(TYPE_IS_FLOATING(L), TYPE_IS_FLOATING(R)), \
+      OP_IS_FLOATING(O), 1 \
+   ) \
+   /**/
+#
+# /* Generates code for all unary operators and integral types. */
+# define UNARY_ARRAY_OP(_, OT) \
+   BOOST_PP_IF( \
+      IS_VALID_UNARY_OP_AND_TYPE_COMBINATION OT, \
+      UNARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(2) \
+   ) OT \
+   /**/
+# define UNARY_ARRAY_OP_CODE(O, T) \
+   void BOOST_PP_LIST_CAT(BOOST_PP_TUPLE_TO_LIST(4, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(T)))) \
+   (const TYPE_NAME(T)* in, TYPE_NAME(TYPE_OF_UNARY_OP(O, T))* out, unsigned n) { \
+      do { \
+         *out++ = OP_SYMBOL(O) *in++; \
+      } while (--n); \
+   } \
+   /**/
+
+BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP, 2, (APPLICATIVE_UNARY_OPS, BUILTIN_TYPES))
+
+# /* Generates code for all binary operators and integral type pairs. */
+# define BINARY_ARRAY_OP(_, OLR) \
+   BOOST_PP_IF( \
+      IS_VALID_BINARY_OP_AND_TYPE_COMBINATION OLR, \
+      BINARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(3) \
+   ) OLR \
+   /**/
+# define BINARY_ARRAY_OP_CODE(O, L, R) \
+   void BOOST_PP_LIST_CAT( \
+      BOOST_PP_TUPLE_TO_LIST( \
+         6, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(L), _, TYPE_ABBREVIATION(R)) \
+      ) \
+   )(const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(TYPE_OF_BINARY_OP(O, L, R))* out, unsigned n) { \
+      do { \
+         *out++ = *lhs_in OP_SYMBOL(O) *rhs_in; \
+         ++lhs_in; \
+         ++rhs_in; \
+      } while (--n); \
+   } \
+   /**/
+
+BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP, 3, (APPLICATIVE_BINARY_OPS, BUILTIN_TYPES, BUILTIN_TYPES))
diff --git a/doc/examples/catch_builtin.cpp b/doc/examples/catch_builtin.cpp
new file mode 100644
index 0000000..27a27a0
--- /dev/null
+++ b/doc/examples/catch_builtin.cpp
@@ -0,0 +1,51 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* This example demonstrates the usage of lists and BOOST_PP_LIST_FOR_EACH(). */
+#
+# include <iostream>
+# include <typeinfo>
+#
+# include <boost/preprocessor/list/for_each.hpp>
+# include <boost/preprocessor/tuple/to_list.hpp>
+#
+# /* List of built-in types.  (Strictly speaking wchar_t should be on the list.) */
+#
+# define BUILTIN_TYPES \
+   BOOST_PP_TUPLE_TO_LIST( \
+      13, \
+      ( \
+         bool, \
+         char, signed char, unsigned char, \
+         unsigned short, short, \
+         int, unsigned, \
+         long, unsigned long, \
+         float, \
+         double, long double \
+      ) \
+   ) \
+   /**/
+#
+# define CATCH(R, _, T) \
+   catch (T t) { \
+      std::cerr << "Caught an " << typeid(t).name() << " = " << t; \
+   } \
+   /**/
+
+int main() {
+   try {
+      throw 10;
+   }
+   BOOST_PP_LIST_FOR_EACH(CATCH, _, BUILTIN_TYPES)
+   return 0;
+}
diff --git a/doc/examples/delay.c b/doc/examples/delay.c
new file mode 100644
index 0000000..9010d76
--- /dev/null
+++ b/doc/examples/delay.c
@@ -0,0 +1,95 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* The time complexity of DELAY(N) is O(2^N).
+#  *
+#  * Handy when recompiles are too fast to take a coffee break. :)
+#  *
+#  * Template metaprogramming can be used for implementing similar
+#  * delays. Unfortunately template instantiation consumes memory,
+#  * therefore compilers usually fail to fully compile long template
+#  * based delays, because they run out of memory.
+#  *
+#  * On many compilers (e.g. g++, MSVC++), this macro takes only a
+#  * small amount of memory to preprocess. On some compilers (e.g.
+#  * MWCW), however, this macro seems to consume huge amounts of
+#  * memory.
+#  */
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# ifndef DELAY_MAX
+# define DELAY_MAX 14
+# endif
+#
+# define DELAY(N) BOOST_PP_TUPLE_ELEM(2, 0, (BOOST_PP_EMPTY, BOOST_PP_WHILE(DELAY_C, BOOST_PP_CAT(DELAY_F, N), BOOST_PP_DEC(N))))()
+#
+# define DELAY_C(D, N) N
+#
+# define DELAY_F0(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F1(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F2(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F3(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F4(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F5(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F6(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F7(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F8(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F9(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F10(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F11(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F12(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F13(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F14(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F15(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F16(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F17(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F18(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F19(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F20(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F21(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F22(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F23(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F24(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F25(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F26(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F27(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F28(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F29(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F30(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F31(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F32(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F33(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F34(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F35(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F36(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F37(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F38(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F39(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F40(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F41(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F42(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F43(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F44(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F45(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F46(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F47(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F48(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F49(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+# define DELAY_F50(D, N) BOOST_PP_IF(1, BOOST_PP_DEC(N), BOOST_PP_WHILE_ ## D(DELAY_C, DELAY_F ## N, BOOST_PP_DEC(N)))
+
+DELAY(DELAY_MAX)
diff --git a/doc/examples/duffs_device.c b/doc/examples/duffs_device.c
new file mode 100644
index 0000000..a457ec4
--- /dev/null
+++ b/doc/examples/duffs_device.c
@@ -0,0 +1,61 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* This example uses the preprocessor library to implement a generalized
+#  * macro for implementing Duff's Device.
+#  *
+#  * This example was inspired by an original generalized macro for
+#  * for implementing Duff's Device written by Joerg Walter.
+#  */
+#
+# include <assert.h>
+#
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* Expands to a Duff's Device. */
+# define DUFFS_DEVICE(UNROLLING_FACTOR, COUNTER_TYPE, N, STATEMENT) \
+   do { \
+      COUNTER_TYPE duffs_device_initial_cnt = (N); \
+      if (duffs_device_initial_cnt > 0) { \
+         COUNTER_TYPE duffs_device_running_cnt = (duffs_device_initial_cnt + (UNROLLING_FACTOR - 1)) / UNROLLING_FACTOR; \
+         switch (duffs_device_initial_cnt % UNROLLING_FACTOR) { \
+            do { \
+               BOOST_PP_REPEAT(UNROLLING_FACTOR, DUFFS_DEVICE_C, (UNROLLING_FACTOR, { STATEMENT })) \
+            } while (--duffs_device_running_cnt); \
+         } \
+      } \
+   } while (0) \
+   /**/
+#
+# define DUFFS_DEVICE_C(Z, I, UNROLLING_FACTOR_STATEMENT) \
+   case (I ? BOOST_PP_TUPLE_ELEM(2, 0, UNROLLING_FACTOR_STATEMENT) - I : 0): \
+      BOOST_PP_TUPLE_ELEM(2, 1, UNROLLING_FACTOR_STATEMENT); \
+   /**/
+#
+# ifndef UNROLLING_FACTOR
+# define UNROLLING_FACTOR 16
+# endif
+#
+# ifndef N
+# define N 1000
+# endif
+
+int main(void) {
+   int i = 0;
+   DUFFS_DEVICE(UNROLLING_FACTOR, int, 0, ++i;);
+   assert(i == 0);
+   DUFFS_DEVICE(UNROLLING_FACTOR, int, N, ++i;);
+   assert(i == N);
+   return 0;
+}
diff --git a/doc/examples/is_integral.cpp b/doc/examples/is_integral.cpp
new file mode 100644
index 0000000..d98be3f
--- /dev/null
+++ b/doc/examples/is_integral.cpp
@@ -0,0 +1,49 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* This example demonstrates the usage of preprocessor lists for generating C++ code. */
+#
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/list/at.hpp>
+# include <boost/preprocessor/list/for_each_product.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/to_list.hpp>
+#
+# /* List of integral types.  (Strictly speaking, wchar_t should be on the list.) */
+# define INTEGRAL_TYPES \
+   BOOST_PP_TUPLE_TO_LIST( \
+      9, (char, signed char, unsigned char, short, unsigned short, int, unsigned, long, unsigned long) \
+   ) \
+   /**/
+#
+# /* List of invokeable cv-qualifiers */
+# define CV_QUALIFIERS \
+   BOOST_PP_TUPLE_TO_LIST( \
+      4, (BOOST_PP_EMPTY, const BOOST_PP_EMPTY, volatile BOOST_PP_EMPTY, const volatile BOOST_PP_EMPTY) \
+   ) \
+   /**/
+#
+# /* Template for testing whether a type is an integral type. */
+
+template<class T> struct is_integral {
+   enum { value = false };
+};
+
+# /* Macro for defining a specialization of is_integral<> template. */
+# define IS_INTEGRAL_SPECIALIZATION(R, L) \
+   template<> struct is_integral<BOOST_PP_TUPLE_ELEM(2, 0, L)() BOOST_PP_TUPLE_ELEM(2, 1, L)> { \
+      enum { value = true }; \
+   }; \
+   /**/
+
+BOOST_PP_LIST_FOR_EACH_PRODUCT(IS_INTEGRAL_SPECIALIZATION, 2, (CV_QUALIFIERS, INTEGRAL_TYPES))
diff --git a/doc/examples/linear_fib.c b/doc/examples/linear_fib.c
new file mode 100644
index 0000000..2778003
--- /dev/null
+++ b/doc/examples/linear_fib.c
@@ -0,0 +1,91 @@
+# /* Copyright (C) 2002
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# /* This example shows how BOOST_PP_WHILE() can be used for implementing macros. */
+#
+# include <stdio.h>
+#
+# include <boost/preprocessor/arithmetic/add.hpp>
+# include <boost/preprocessor/arithmetic/sub.hpp>
+# include <boost/preprocessor/comparison/less_equal.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/list/adt.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* First consider the following C implementation of Fibonacci. */
+
+typedef struct linear_fib_state {
+   int a0, a1, n;
+} linear_fib_state;
+
+static int linear_fib_c(linear_fib_state p) {
+   return p.n;
+}
+
+static linear_fib_state linear_fib_f(linear_fib_state p) {
+   linear_fib_state r = { p.a1, p.a0 + p.a1, p.n - 1 };
+   return r;
+}
+
+static int linear_fib(int n) {
+   linear_fib_state p = { 0, 1, n };
+   while (linear_fib_c(p)) {
+      p = linear_fib_f(p);
+   }
+   return p.a0;
+}
+
+# /* Then consider the following preprocessor implementation of Fibonacci. */
+#
+# define LINEAR_FIB(n) LINEAR_FIB_D(1, n)
+# /* Since the macro is implemented using BOOST_PP_WHILE, the actual
+#  * implementation takes a depth as a parameters so that it can be called
+#  * inside a BOOST_PP_WHILE.  The above easy-to-use version simply uses 1
+#  * as the depth and cannot be called inside a BOOST_PP_WHILE.
+#  */
+#
+# define LINEAR_FIB_D(d, n) \
+   BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_WHILE_ ## d(LINEAR_FIB_C, LINEAR_FIB_F, (0, 1, n)))
+# /*                   ^^^^                 ^^^^^           ^^            ^^   ^^^^^^^
+#  *                    #1                   #2             #3            #3     #4
+#  *
+#  * 1) The state is a 3-element tuple.  After the iteration is finished, the first
+#  *    element of the tuple is the result.
+#  *
+#  * 2) The WHILE primitive is "invoked" directly.  BOOST_PP_WHILE(D, ...)
+#  *    can't be used because it would not be expanded by the preprocessor.
+#  *
+#  * 3) ???_C is the condition and ???_F is the iteration macro.
+#  */
+#
+# define LINEAR_FIB_C(d, p) \
+   /* p.n */ BOOST_PP_TUPLE_ELEM(3, 2, p) \
+   /**/
+#
+# define LINEAR_FIB_F(d, p) \
+   ( \
+      /* p.a1 */ BOOST_PP_TUPLE_ELEM(3, 1, p), \
+      /* p.a0 + p.a1 */ BOOST_PP_ADD_D(d, BOOST_PP_TUPLE_ELEM(3, 0, p), BOOST_PP_TUPLE_ELEM(3, 1, p)), \
+                        /*          ^^ ^ \
+                         * BOOST_PP_ADD() uses BOOST_PP_WHILE().  Therefore we \
+                         * pass the recursion depth explicitly to BOOST_PP_ADD_D(). \
+                         */ \
+      /* p.n - 1 */ BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3, 2, p)) \
+   ) \
+   /**/
+
+int main() {
+   printf("linear_fib(10) = %d\n", linear_fib(10));
+   printf("LINEAR_FIB(10) = %d\n", LINEAR_FIB(10));
+   return 0;
+}