On 9/14/2014 6:49 PM, Paul Mensonides wrote:
On 9/14/2014 3:12 PM, Edward Diener wrote:
On 9/14/2014 5:10 PM, pfultz2 wrote:
I am not sure what you mean by namespaces ? Do you mean the type of the token parsed ?
I believe he means macro prefixes such as BOOST_PP_, BOOST_VMD_, or BOOST_VMD_NAMESPACE_.
Perhaps Paul can explain it better than me.
The BOOST_PP_AUTO_REC macro is not documented so maybe you can understand my being puzzled by it and what it is used for. Other undocumented macros in Boost PP are generally easier for me to follow.
The BOOST_PP_AUTO_REC macro is used to find the first macro of a set of macros which has not been painted (i.e. will expand). It requires a set of macros which are a power of 2 which are used in order.
Here is my understanding of what BOOST_PP_AUTO_REC does from your example. It takes a function-like macro name and a parameter which is a Boost PP number which is a power of 2, from a minimum of 2 to a maximum of 256. It then calls the function-like macro name passing a number starting with 1 through the number passed to it. If the function-like macro returns 1 it stops and returns the current number else it continues with the next number. I won't ask what BOOST_PP_AUTO_REC returns if its function-like macro never returns 1 before it finishes cycling through its numbers <g>. I assume the "painted" part is because it is usually used with BOOST_PP_NULLARY as in your example below.
For example:
#include
#include #define CAT_1(a, b) PRIMITIVE_CAT_1(a, b) #define CAT_2(a, b) PRIMITIVE_CAT_2(a, b) #define CAT_3(a, b) PRIMITIVE_CAT_3(a, b) #define CAT_4(a, b) PRIMITIVE_CAT_4(a, b)
#define PRIMITIVE_CAT_1(a, b) a ## b #define PRIMITIVE_CAT_2(a, b) a ## b #define PRIMITIVE_CAT_3(a, b) a ## b #define PRIMITIVE_CAT_4(a, b) a ## b
#define CAT \ BOOST_PP_CAT( \ CAT_, \ BOOST_PP_AUTO_REC(PRIMITIVE_CAT_P, 4) \ ) /**/ #define PRIMITIVE_CAT \ BOOST_PP_CAT( \ PRIMITIVE_CAT_, \ BOOST_PP_AUTO_REC(PRIMITIVE_CAT_P, 4) \ ) \ /**/ #define PRIMITIVE_CAT_P(n) \ BOOST_PP_IS_NULLARY(PRIMITIVE_CAT_ ## n(,)()) \ /**/
Here the CAT and PRIMITIVE_CAT macros are defined as object-like macros which expand to the next available CAT_n and PRIMITIVE_CAT_n macros which are found via the the BOOST_PP_AUTO_REC macro--which does a binary search from 1 to 4 in this case finding the first index for which the passed predicate PRIMITIVE_CAT_P expands to 1.
Essentially, it makes it look like CAT can be invoked recursively, but CAT itself is not really even a function-like macro. E.g.
#define A1 CAT(B, 1) // here CAT expands to CAT_2 #define B1 CAT(C, 1) // here CAT expands to CAT_3 #define C1 CAT(D, 1) // here CAT expands to CAT_4
CAT(A, 1) // here CAT expands to CAT_1
Thanks for the explanation.
You could actually do something similar with VMD now but you would have to try each v-type separately to see if it begins the v-sequence. But after Paul Mensonides provided a better solution to identifying v-identifiers and v-numbers I can improve the parsing of VMD v-sequences greatly.
In fact with VMD a v-sequence becomes another preprocessor "data type" similar to the high level Boost PP data types of array, list, seq, and tuple. I should really work to produce whatever operations with a v-sequence I can that would mimic some of those Boost PP data types. Its challenging to think about but it will be fun work except for the usual VC++isms.
The alternate registration mechanism (excluding the comma in the registration itself) that you guys realized is good and is obvious is retrospect. That would make the registration much cleaner.
I agree. Your proposal is obvious in retrospect but it is like the legendary story of Christopher Columbus and the egg. I am now very glad I can make a v-sequence much easier with better functionality. Why I didn't think of your solution to being with ... <g>.