|
Boost : |
Subject: Re: [boost] For Boost PP: IF_NONEMPTY(), IS_NONEMPTY
From: Edward Diener (eldiener_at_[hidden])
Date: 2012-05-10 21:45:01
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
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk