
On 5/8/2012 5:24 AM, Daniel Santos wrote:
I came up with some macros the other day trying to solve a kernel problem and I haven't seen them anywhere else and if I found one, I sure would have stolen it. :) I used this to have a single function-like macro service different numbers of parameters, essentially adding "optional parameter" support so I didn't have to have different version of the macro.
IF_NONEMPTY(test, result) expands to result if test is non-empty, empty otherwise. IS_NONEMPTY(arg) expands to 0 if arg is empty, 0x1 if it isn't. OPT_OFFSETOF(type, member) isn't very useful in C++, but it is an example of how the above can be used. It expands to a compiler-time constant that is the offset of the member in the struct or union type, unless member isn't specified, in which case it's zero.
#define __JUNK junk, #define _if_nonempty(arg1_or_junk, result) __if_nonempty(arg1_or_junk, result) #define __if_nonempty(__ignored, result, ...) result #define CONCAT_TOKEN(a, b) _concat_token(a, b) #define _concat_token(a, b) a ## b
#define IF_NONEMPTY(test, result) _if_nonempty(__JUNK##test, result)
If the 'test' token is not concatenable you will get a compiler error. This is the major weakness of your implementation and extends to the 'arg' token in your next macro. For another IS_EMPTY implementation, almost entirely based on code Paul Mensonides posted on the Internet for use with variadic macros, see the BOOST_VMD_IS_EMPTY macro in my own variadic macro library in the Boost sandbox. It still has a flaw, although a different ( and IMO a lesser ) one than your implementation. As Paul Mensonides has stated, there is no version of IS_EMPTY which can be created which is perfect for a 100% conformant C++ preprocesor. Eddie Diener
#define IS_NONEMPTY(arg) CONCAT_TOKEN(0, IF_NONEMPTY(arg, x1)) #define OPT_OFFSETOF(type, m) ((size_t)&((*((type *)0)) IF_NONEMPTY(m,.)m))
_______________________________________________ Unsubscribe& other changes: http://lists.boost.org/mailman/listinfo.cgi/boost