
Hello, yesterday I spent the day with my first application of the Boost Preprocessor library: Given two sequences A and B (according to the Boost Preprocessor datastructure definition), I want to create a nested switch statement, the outer switch running through the constants in A, the inner loops running through B. Piece of cake: Just apply BOOST_PP_SEQ_FOR_EACH two times. Didn't work, because the preprocessor when evaluating a macro M will suspend the definition of M during the evaluation (thus "no recursion"). Unfortunately, I didn't know this, so I had to find it out the hard way. First of all I think here the documentation of the library doesn't reach its full potential yet: I tried first to read through "Topics", but found all examples contrived and complicated (couldn't find a single plain example), and thus I skipped that and went to Reference, where I found BOOST_PP_SEQ_FOR_EACH, making some still mysterious remarks about "The next available BOOST_PP_FOR repetition." etc. But at various places it somehow says that "reentry problems" whatever this means are solved now. Only when looking it up in the rationale of C99 I found a clear statement about the issue (while the C++ standard somehow supposes you know already the issue). So a clear statement about the limitations of the looping constructions *at each place* would help I would guess quite a few people trying to use this library. (I believe documentation must be written so that it can be entered in many ways, and not assuming you are reading it from the start to the end --- redundancy is needed.) Second of all it seems the current facilities in the library should be enhanced (though I don't understand how FOR and FOR_r is supposed to be used): BOOST_PP_SEQ_FOR_EACH is such a natural and easy thing, the use of it should be promoted, while FOR and its derivates look ugly. But it seems that the library favours FOR, and seems to envisage a main loop using FOR, and only at the second level using FOR_EACH. My solution was to convert the second sequence B into a list, and use BOOST_PP_LIST_FOR_EACH for the inner loop. But it seems to me that this works is pure chance, and with any change in the implementation of BOOST_PP_SEQ_FOR_EACH or BOOST_PP_LIST_FOR_EACH (introducing a common macro) this solution will break. According to what I understand from the documentation, the natural solution, offering for example BOOST_PP_SEQ_FOR_EACH_2, which uses macros guaranteed not to occur in BOOST_PP_SEQ_FOR_EACH, has been deprecated in favour of a more complicated solution. But it seems this more complicated solution works only for one kind of loop, and not for others, and the documentation seems so arcane that I don't have a clue how it could work (the typical phenomenon, that the documentation wants to show off by presenting only complicated examples, which show all sorts of templates, etc., and this without saying what actually should by achieved --- good code solves one problem at a time, and good documentation discusses one problem at a time). So if the library offers a natural way of nesting BOOST_PP_SEQ_FOR_EACH, then documenting this (directly, without solving other problems) would be good, or otherwise adding BOOST_PP_SEQ_FOR_EACH_2 would help some users (actually, just the presence of this second form would announce the underlying problem). Sometimes less general but simpler solutions are preferable over more general but complicated solutions. Oliver P.S. The situation with the preprocessor is complicated by the general silence on this issue in the books. And quite amazing, how the library achieves to squeeze out nearly a general purpose machine (but not with an infinite tape :-)) from the preprocessor machinery, which seems to have been castrated by the designers on purpose.