I met in boost define
# define BOOST_PP_ENUM BOOST_PP_CAT(BOOST_PP_ENUM_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
BOOST_PP_AUTO_REC help deduces the recursion level used in Automatic Recursion, by performing a binary search using a predicate. The first argument is the predicate and the second is the size to be searched. The predicate will be called as
pred is the predicate and
n is the value.
The search must be ordered, so all values for which the predicate returns 0 must come before all values for which the predicate returns 1.
Since, the macro is used for Automatic Recursion, the predicate can not use any macro which employ automatic recursion.
For example, the predicate for repeat is defined like this:
# define BOOST_PP_REPEAT_P(n) BOOST_PP_CAT(BOOST_PP_REPEAT_CHECK_, BOOST_PP_REPEAT_ ## n(1, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3, BOOST_PP_NIL)) # # define BOOST_PP_REPEAT_CHECK_BOOST_PP_NIL 1 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_1(c, m, d) 0 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_2(c, m, d) 0 # define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_3(c, m, d) 0
BOOST_PP_REPEAT_1 is called recursively, it won't expand. Thus when it concats with
BOOST_PP_REPEAT_CHECK_ it will expand to
BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_1, which will expand to
0. However if
BOOST_PP_REPEAT_1 is not being called recursively, then it will expand to
BOOST_PP_NIL, which is then concated with
BOOST_PP_REPEAT_CHECK_ to produce
So the predicate is setup to detect if one of the
BOOST_PP_REPEAT_n macros can expand. Then
BOOST_PP_AUTO_REC will perform a binary search to find the first one that can expand. In the case of
BOOST_PP_REPEAT, it will only search across 4 recursion levels, but other macros such as
BOOST_PP_WHILE has a recursion depth up to 256.