Test if a C macro's value is empty - c++

I need to write some code to verify that a macro is defined but empty (not having any values). The test does not need to be in compile time.
I am attempting to write:
#if (funcprototype == "")
MY_WARN("funcprototype is empty");
#endif
the code does not compile, as funcprototype expands to empty.

If a run-time check is okay, then you can test the length of the stringized replacement:
#define REAL_STRINGIZE(x) #x
#define STRINGIZE(x) REAL_STRINGIZE(x)
if (STRINGIZE(funcprototype)[0] == '\0') {
// funcprototype expanded to an empty replacement list
}
else {
// funcprototype expanded to a non-empty replacement list
}
I don't think there is a general-case "is this macro replaced by an empty sequence of tokens" compile-time check. That is a similar problem to "is it possible to compare two sequences of tokens for equality," which is impossible to do at compile-time.

C++20 __VA_OPT__ makes this easier:
#define EMPTY(...) (true __VA_OPT__(&& false))
Then:
if (EMPTY(MY_MACRO))

With VS2013 the following works for me at pre-compile-time:
#define EXPAND(x) x
#define ARGS_dummy(...) dummy,##__VA_ARGS__
#define SELECT_from5(_1,_2,_3,_4,_5,num,...) num
#define IS_EMPTY_impl(...) EXPAND(SELECT_from5(__VA_ARGS__,0,0,0,0,1))
#define IS_EMPTY(...) EXPAND(IS_EMPTY_impl(ARGS_dummy(__VA_ARGS__)))
IS_EMPTY expands to 1 if there is no argument or the 1st argument expands to nothing, otherwise to 0.
Additional arguments are ignored.
#define x2 X
#define x1
#undef x0
IS_EMPTY(); // () -> 1
IS_EMPTY( ); // ( ) -> 1
IS_EMPTY(,); // (,) -> 1
IS_EMPTY(aaa,); // (aaa, ) -> 0
IS_EMPTY(,,); // (,,) -> -> 1
IS_EMPTY(x2); // (x2) -> (X) -> 0
IS_EMPTY(x1); // (x1) -> () -> 1
IS_EMPTY(x0); // (x0) -> 0
Now you could generate a bit mask depending on empty/nonempty parameters:
#define check_5e(a,b,c,d,e) a ## b ## c## d ## e
#define check_5d(a,b,c,d,e) check_5e(a,b,c,d,e)
#define check_5c(e,a,b,c,d) check_5d(a,b,c,d,IS_EMPTY(e))
#define check_5b(d,e,a,b,c) check_5c(e,a,b,c,IS_EMPTY(d))
#define check_5a(c,d,e,a,b) check_5b(d,e,a,b,IS_EMPTY(c))
#define check_5(b,c,d,e,a) check_5a(c,d,e,a,IS_EMPTY(b))
#define CHECK_FIVE_ARGS(a,b,c,d,e) check_5(b,c,d,e,IS_EMPTY(a))
CHECK_FIVE_ARGS(aa, , x1, x2, x0); // -> (aa,,,X,x0) -> 01100
or you can choose sub macro depending on given arguments ...
(note that VERSION_BUILD is defined but empty!)
#define VERSION_Major 3
#define VERSION_Minor 22
#define VERSION_Patch 111
#define VERSION_Build
#define VERSION_Label debug
#define MAKE_VERSION_11(a,b,c,d,e) a##.##b##.##c
#define MAKE_VERSION_10(a,b,c,d,e) a##.##b##.##c##--##e
#define MAKE_VERSION_01(a,b,c,d,e) a##.##b##.##c##-##d
#define MAKE_VERSION_00(a,b,c,d,e) a##.##b##.##c##-##d##--##e
#define MAKE_VERSION_impl2(_de) MAKE_VERSION_ ## _de
#define MAKE_VERSION_impl(_de) EXPAND(MAKE_VERSION_impl2(_de))
#define MAKE_VERSION(a,b,c,d,e) \
MAKE_VERSION_impl(IS_EMPTY(d)IS_EMPTY(e))(a,b,c,d,e)
// check 4th and 5th arg -> "MAKE_VERSION_10"
MAKE_VERSION_impl(IS_EMPTY(VERSION_Build)IS_EMPTY(VERSION_Label));
// -> 3.22.111--debug
MAKE_VERSION(VERSION_Major, VERSION_Minor, VERSION_Patch, VERSION_Build, VERSION_Label);
MAKE_VERSION(2, 3, 4, 5678, ); // -> 2.3.4-5678
MAKE_VERSION(2, 3, 4, 5678, beta); // -> 2.3.4-5678--beta
MAKE_VERSION(2, 3, 4,,); // -> 2.3.4
MAKE_VERSION(2, 3, 4, ,beta); // -> 2.3.4--beta

Related

clang-format - Format long macro

I'm here because honestly, I can't figure out this one.
My problem lies in how clang-format rearranges long preprocessor definition.
Here's what my code look like, after formating.
#define CMD_FRAME_PACKET_HEADER_SIZE \
(CMD_FRAME_SOF_SIZE + CMD_FRAME_MSG_ID_SIZE + CMD_FRAME_CMD_CODE_SIZE + CMD_FRAME_CMD_STATE_SIZE + \
CMD_FRAME_DATA_LENGTH_SIZE)
#define CMD_FRAME_PACKET_FOOTER_SIZE (CMD_FRAME_CRC_SIZE + CMD_FRAME_EOF_SIZE)
#define CMD_FRAME_PACKET_PAYLOAD_MAX_SIZE (2 * CMD_FRAME_DATA_FIELDS_MAX_SIZE)
#define CMD_FRAME_PACKET_PAYLOAD_MIN_SIZE (0)
#define CMD_FRAME_PACKET_MAX_SIZE \
(CMD_FRAME_PACKET_HEADER_SIZE + CMD_FRAME_PACKET_PAYLOAD_MAX_SIZE + CMD_FRAME_PACKET_FOOTER_SIZE)
#define CMD_FRAME_PACKET_MIN_SIZE \
(CMD_FRAME_PACKET_HEADER_SIZE + CMD_FRAME_PACKET_PAYLOAD_MIN_SIZE + CMD_FRAME_PACKET_FOOTER_SIZE)
Here's what I like to see:
#define CMD_FRAME_PACKET_HEADER_SIZE (CMD_FRAME_SOF_SIZE + CMD_FRAME_MSG_ID_SIZE + CMD_FRAME_CMD_CODE_SIZE \
+ CMD_FRAME_CMD_STATE_SIZE + CMD_FRAME_DATA_LENGTH_SIZE)
#define CMD_FRAME_PACKET_FOOTER_SIZE (CMD_FRAME_CRC_SIZE + CMD_FRAME_EOF_SIZE)
#define CMD_FRAME_PACKET_PAYLOAD_MAX_SIZE (2 * CMD_FRAME_DATA_FIELDS_MAX_SIZE)
#define CMD_FRAME_PACKET_PAYLOAD_MIN_SIZE (0)
#define CMD_FRAME_PACKET_MAX_SIZE (CMD_FRAME_PACKET_HEADER_SIZE + CMD_FRAME_PACKET_PAYLOAD_MAX_SIZE \
+ CMD_FRAME_PACKET_FOOTER_SIZE)
#define CMD_FRAME_PACKET_MIN_SIZE (CMD_FRAME_PACKET_HEADER_SIZE + CMD_FRAME_PACKET_PAYLOAD_MIN_SIZE \
+ CMD_FRAME_PACKET_FOOTER_SIZE)
For those interested, here is my .clang-format
---
#
# Global style
BasedOnStyle: Microsoft
#
# Basic
IndentWidth: 4
TabWidth: 4
ColumnLimit: 120
UseTab: Never
#
# Function and macro
AlignAfterOpenBracket: Align
AllowAllParametersOfDeclarationOnNextLine: false
BinPackParameters: true
AlignConsecutiveMacros: Consecutive
AllowAllArgumentsOnNextLine: false
#
# if and switch case
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AlignTrailingComments: true
IndentCaseLabels: true
BraceWrapping:
AfterCaseLabel: true
#
# Other
SpaceInEmptyBlock: true
AlignConsecutiveAssignments: Consecutive
SpacesInContainerLiterals: true
# AlignArrayOfStructures: Right
"what I like to see" involves the layout of one macro to depend on others. Should that "other" macros only depend on nearby macros, all macros in the .c file, all macros in the .c and .h files or what?
Consider how one long macro would impact the others
#define CMD_FRAME_PACKET_FOOTER_SIZE_AALKJSLFAKJFALFEUEUFELUFEU (0)
#define CMD_FRAME_PACKET_HEADER_SIZE (CMD_FRAME_SOF_SIZE \
+ CMD_FRAME_MSG_ID_SIZE \
+ CMD_FRAME_CMD_CODE_SIZE \
+ CMD_FRAME_CMD_STATE_SIZE \
+ CMD_FRAME_DATA_LENGTH_SIZE)
The desired format is higher maintenance and not effective use of valuable coder time. OTOH, your own time is yours to do as you will. Yet since much programming is paid by others, payers would not likely want to pay for this and so Clang (or other simple auto formatting) becomes more common and familiar/understandable.
I recommend to format code based on your group's coding standard.

How to understand the below macros in the code

I am trying to understand the code base of an application but having issue in interpreting the below macros. Would any one please help me in understanding the code below.
#define LIST_OF_AP_COMMANDS(ENTRY) \
ENTRY(WLAN_AP_SET_IP, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "ifconfig wlan1 %s > /dev/null", abAPIpAddress) \
ENTRY(WLAN_AP_REMOVE_NETWORK, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 remove_network 0 > /dev/null") \
ENTRY(WLAN_AP_ADD_NETWORK, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 add_network > /dev/null") \
ENTRY(WLAN_AP_SET_SSID, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 set_network 0 ssid '\"%s\"' > /dev/null", CON_acbSSID) \
ENTRY(WLAN_AP_SET_PASS, 2, (WPA_MODE), "wpa_cli -iwlan1 set_network 0 psk '\"%s\"' > /dev/null", CON_acPassword) \
ENTRY(WLAN_AP_SET_PASSWORD, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 set_network 0 key_mgmt %s > /dev/null", pcSecurityTypes[CON_bSecurityType] ) \
ENTRY(WLAN_AP_SET_FREQUENCY, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 set_network 0 frequency %d > /dev/null", CON_awWifiFreqs[ CON_bChannel ]) \
ENTRY(WLAN_AP_SET_MODE, 2, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 set_network 0 mode 2 > /dev/null") \
ENTRY(WLAN_AP_SET_MODE, 2, WEP_MODE , "wpa_cli -iwlan1 set_network 0 wep_key0 %s > /dev/null", CON_acPassword) \
ENTRY(WLAN_AP_SET_MODE, 2, WEP_MODE , "wpa_cli -iwlan1 set_network 0 wep_tx_keyidx 0 > /dev/null") \
ENTRY(WLAN_AP_ENABLE_NETWORK, 10, (WEP_MODE | WPA_MODE | NONE_MODE), "wpa_cli -iwlan1 enable_network 0 > /dev/null" )
//! Expander with the execution of each command
#define EXECUTE_WLAN_COMMANDS(index, delay, mode, command, ...) \
if( ( abSecurityModes[CON_bSecurityType] & mode ) ) { CON_cExecuteWlanCommand(command, ##__VA_ARGS__); } else { printf("wpa_cli %d %d\r\n", abSecurityModes[CON_bSecurityType], mode); } \
sleep( delay );
X-macros are a traditional technique for handling code generation in languages which use macro preprocessors like the C/C++ preprocessor. The idea is that you have a list of elements -- types, enumeration constants, message strings, etc. -- and you need to use that list more than once in order to generate your code.fir example, you might want to make both a list of error messages and an enum which defines symbolic names for each error. Or perhaps you have several different structures and you need to make two or more specific functions for each structure. (In C++, you would probably use templates for this particular case.)
The name "X-macro" comes from the original pattern in which the list macro invoked a macro with a given name -- by convention X -- on each element of the list, leading to a pattern like:
#define X(name, value) … // some use of name and value
HANDLE_LIST
#undef X
#define X(name, value) … // sone other use
HANDLE_LIST
#undef X
// etc.
But at some point, it became much more common to use a list-handler which takes the name of the macro to call as an argument (a so-called "higher order macro"). This allows for more meaningful names and avoids to need to repeatedly undefine X. (Particularly useful if you have miore than one list.)
And that's what you are seeing here.

macro parameter pack with boost preprocessor

I don't know there similar question, or not.
How to simplify
(a == 78 || a == 98 || a == 73 || a == 11 || a == 90 || a==103 || a==45 )
expression to
MY_CHECK(a, (78, 98, 73, 11, 90, 103, 45) )
With boost preprocessor ??
Is there any ready solution in boost preprocessor.
I couldn't find better than a transform followed by a fold, since BOOST_PP_SEQ_FOLD_LEFT does not carry a data parameter around. Still:
#define MY_CHECK_FOLD_OR(s, a, b) a || b
#define MY_CHECK_FOLD_EQ(s, var, elem) (var) == (elem)
#define MY_CHECK(var, values) \
(BOOST_PP_SEQ_FOLD_LEFT( \
MY_CHECK_FOLD_OR, false, \
BOOST_PP_SEQ_TRANSFORM( \
MY_CHECK_FOLD_EQ, var, \
BOOST_PP_TUPLE_TO_SEQ(values) \
) \
))
... which expands:
if (MY_CHECK(a, (1, 2, 3)))
... into:
if ((false || (a) == (1) || (a) == (2) || (a) == (3)))
See it live on Coliru
There's no need to use the preprocessor here. A variadic template will do just fine. Here's an example using a C++17 fold expression:
template <typename Needle, typename... Haystack>
bool my_check(const Needle& needle, const Haystack&... haystack)
{
return ((needle == haystack) || ...);
}
live example on wandbox

Regarding expansion of MACROS during preprocessing

I have an existing MACRO which takes two entities.
ROOT_MACRO(x,y)
I want to define 2 new macros like this :- MACRO_1(x,y)= ROOT_MACRO(z,x__y)
Here I want z to be evaluated in preprocessing using MACRO_2
For ex. my cpp file would look something like this :-
MACRO_2(z)
MACRO_1(x,y)==> Should expand to ROOT_MACRO(z,x__y)
//Later on in the .cpp file,
MACRO_2(p)
MACRO_1(x,y)==> Should expand here to ROOT_MACRO(p,x__y)
Is there a way to achieve this ? I hope the question is clear.
If I understand correctly, you want something like the following:
#define MACRO_2(p) #define MACRO_2_DEFINED p
#define MACRO_1(x,y) ROOT_MACRO(MACRO_2_DEFINED,x__y)
But cpp (c pre-processor) works in one-pass, and you can't define a define. What you could do if you are able to change the build system is use m4 before sending the code to cpp. Here is an example using m4:
#define ROOT_MACRO(x,y) This is the root macro with arguments x and y
define(`MACRO_2',`#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED $1')
define(`MACRO_1', `ROOT_MACRO(MACRO_2_DEFINED, $1__$2)')
MACRO_2(z)
MACRO_1(x,y)
MACRO_2(p)
MACRO_1(x,y)
Then running m4 on the file above (e.g. $m4 foo.c) yields:
#define ROOT_MACRO(x,y) This is the root macro with arguments x and y
#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED z
ROOT_MACRO(MACRO_2_DEFINED, x__y)
#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED p
ROOT_MACRO(MACRO_2_DEFINED, x__y)
And running cpp on the code above (e.g. $m4 foo.c | cpp -) yields:
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
This is the root macro with arguments z and x__y
This is the root macro with arguments p and x__y
#davir is right, you can't #define a define. The best you can get with the standard preprocesor is something like this:
#define M1(x,y) MACRO_BASE(M2, x##__##y)
...
#define M2 z
M1(x,y) //# expands to MACRO_BASE(z,x__y)
...//later
#define M2 p
M1(x,y) //# expands to MACRO_BASE(p,x__y)
If z and p are values of a fixed type, you could get away with something awful like:
#define M2(v) thetype_t current_m2__ = v
#define M1(x,y) MACRO_BASE(current_m2__, x##__##y)
Which could work as long as you always have one and only one call to M2 in the same scope as M1.
But why not just combine the M2 and M1 calls like #define M(v,x,y) MACRO_BASE(v,x##__##y)?

Foreach macro on macros arguments

I wonder if it is possible to write a macro foreach on macros arguments. Here is what want to do:
#define PRINT(a) printf(#a": %d", a)
#define PRINT_ALL(...) ? ? ? THE PROBLEM ? ? ?
And possible usage:
int a = 1, b = 3, d = 0;
PRINT_ALL(a,b,d);
Here is what I achieved so far
#define FIRST_ARG(arg,...) arg
#define AFTER_FIRST_ARG(arg,...) , ##__VA_ARGS__
#define PRINT(a) printf(#a": %d", a)
#define PRINT_ALL PRINT(FIRST_ARG(__VA_ARGS__)); PRINT_ALL(AFTER_FIRST_ARG(__VA_ARGS__))
This is a recursive macro, which is illegal. And another problem with that is stop condition of recursion.
Yes, recursive macros are possible in C using a fancy workaround. The end goal is to create a MAP macro which works like this:
#define PRINT(a) printf(#a": %d", a)
MAP(PRINT, a, b, c) /* Apply PRINT to a, b, and c */
Basic Recursion
First, we need a technique for emitting something that looks like a macro
call, but isn't yet:
#define MAP_OUT
Imagine we have the following macros:
#define A(x) x B MAP_OUT (x)
#define B(x) x A MAP_OUT (x)
Evaluating the macro A (blah) produces the output text:
blah B (blah)
The preprocessor doesn't see any recursion, since the B (blah) call is
just plain text at this point, and B isn't even the name of the current
macro. Feeding this text back into the preprocessor expands the call,
producing the output:
blah blah A (blah)
Evaluating the output a third time expands the A (blah) macro, carrying
the recursion full-circle. The recursion continues as long as the caller
continues to feed the output text back into the preprocessor.
To perform these repeated evaluations, the following EVAL macro passes
its arguments down a tree of macro calls:
#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0 (EVAL0 (EVAL0 (__VA_ARGS__)))
#define EVAL2(...) EVAL1 (EVAL1 (EVAL1 (__VA_ARGS__)))
#define EVAL3(...) EVAL2 (EVAL2 (EVAL2 (__VA_ARGS__)))
#define EVAL4(...) EVAL3 (EVAL3 (EVAL3 (__VA_ARGS__)))
#define EVAL(...) EVAL4 (EVAL4 (EVAL4 (__VA_ARGS__)))
Each level multiplies the effort of the level before, evaluating the input
365 times in total. In other words, calling EVAL (A (blah)) would
produce 365 copies of the word blah, followed by a final un-evaluated B (blah). This provides the basic framework for recursion, at least within a
certain stack depth.
End Detection
The next challenge is to stop the recursion when it reaches the end of the
list.
The basic idea is to emit the following macro name instead of the normal
recursive macro when the time comes to quit:
#define MAP_END(...)
Evaluating this macro does nothing, which ends the recursion.
To actually select between the two macros, the following MAP_NEXT
macro compares a single list item against the special end-of-list marker
(). The macro returns MAP_END if the item matches, or the next
parameter if the item is anything else:
#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(item, next, ...) next MAP_OUT
#define MAP_NEXT1(item, next) MAP_NEXT0 (item, next, 0)
#define MAP_NEXT(item, next) MAP_NEXT1 (MAP_GET_END item, next)
This macro works by placing the item next to the MAP_GET_END macro. If
doing that forms a macro call, everything moves over by a slot in the
MAP_NEXT0 parameter list, changing the output. The MAP_OUT trick
prevents the preprocessor from evaluating the final result.
Putting it All Together
With these pieces in place, it is now possible to implement useful versions
of the A and B macros from the example above:
#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
These macros apply the operation f to the current list item x. They then
examine the next list item, peek, to see if they should continue or not.
The final step is to tie everything together in a top-level MAP macro:
#define MAP(f, ...) EVAL (MAP1 (f, __VA_ARGS__, (), 0))
This macro places a () marker on the end of the list, as well as an extra
0 for ANSI compliance (otherwise, the last iteration would have an illegal
0-length list). It then passes the whole thing through EVAL and
returns the result.
I have uploaded this code as a library on github for your convenience.
Using PPNARG, I wrote a set of macros to apply a macro to each argument in a macro. I call it a variadic X-macro.
/*
* The PP_NARG macro evaluates to the number of arguments that have been
* passed to it.
*
* Laurent Deniau, "__VA_NARG__," 17 January 2006, <comp.std.c> (29 November 2007).
*/
#define PP_NARG(...) PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
PPNARG lets us get a count of how many arguments there are. Then we append that number to the macro name and call it with the original arguments.
/* need extra level to force extra eval */
#define Paste(a,b) a ## b
#define XPASTE(a,b) Paste(a,b)
/* APPLYXn variadic X-Macro by M Joshua Ryan */
/* Free for all uses. Don't be a jerk. */
/* I got bored after typing 15 of these. */
/* You could keep going upto 64 (PPNARG's limit). */
#define APPLYX1(a) X(a)
#define APPLYX2(a,b) X(a) X(b)
#define APPLYX3(a,b,c) X(a) X(b) X(c)
#define APPLYX4(a,b,c,d) X(a) X(b) X(c) X(d)
#define APPLYX5(a,b,c,d,e) X(a) X(b) X(c) X(d) X(e)
#define APPLYX6(a,b,c,d,e,f) X(a) X(b) X(c) X(d) X(e) X(f)
#define APPLYX7(a,b,c,d,e,f,g) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g)
#define APPLYX8(a,b,c,d,e,f,g,h) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h)
#define APPLYX9(a,b,c,d,e,f,g,h,i) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i)
#define APPLYX10(a,b,c,d,e,f,g,h,i,j) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j)
#define APPLYX11(a,b,c,d,e,f,g,h,i,j,k) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j) X(k)
#define APPLYX12(a,b,c,d,e,f,g,h,i,j,k,l) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j) X(k) X(l)
#define APPLYX13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j) X(k) X(l) X(m)
#define APPLYX14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j) X(k) X(l) X(m) X(n)
#define APPLYX15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
X(a) X(b) X(c) X(d) X(e) X(f) X(g) X(h) X(i) X(j) X(k) X(l) X(m) X(n) X(o)
#define APPLYX_(M, ...) M(__VA_ARGS__)
#define APPLYXn(...) APPLYX_(XPASTE(APPLYX, PP_NARG(__VA_ARGS__)), __VA_ARGS__)
And here are some examples with the output from gcc -E in comments.
/* Example */
#define X(a) #a,
char *list[] = {
APPLYXn(sugar,coffee,drink,smoke)
};
#undef X
/* Produces (gcc -E)
char *list[] = {
"sugar", "coffee", "drink", "smoke",
};
*/
#define c1(a) case a:
#define c2(a,b) c1(a) c1(b)
#define c3(a,b,c) c1(a) c2(b,c)
#define c4(a,b,c,d) c1(a) c3(b,c,d)
#define c_(M, ...) M(__VA_ARGS__)
#define cases(...) c_(XPASTE(c, PP_NARG(__VA_ARGS__)), __VA_ARGS__)
//cases(3,4,5,6,7)
//produces
//case 3: case 4: case 5: case 6:
#define r_(a,b) range(a,b)
#define range(a,b) a,r_(a+1,b-1)
//range(3,4)
#define ps1(a) O ## a ();
#define ps2(a,b) ps1(a) ps1(b)
#define ps3(a,b,c) ps1(a) ps2(b,c)
#define ps4(a,b,c,d) ps1(a) ps3(b,c,d)
#define ps_(M, ...) M(__VA_ARGS__)
#define ps(...) ps_(XPASTE(ps, PP_NARG(__VA_ARGS__)), __VA_ARGS__)
//ps(dup,add,sub)
This last was the motive for the whole thing. But it didn't turn out to be very useful.
Edit: many years later...
If we take a step back and reimagine the goal "apply a macro to each argument of a macro", this ia almost the same thing as an X-Macro. And I think an X-Macro can be made to do roughly the same job with a slight difference in syntax.
#define EACH_THING(X) \
X(Thing1) \
X(Thing2) \
X(OtherThing) \
/**/
Then you can write a macro that deals with each thing individually and by invoking the EACH_* with the name of the macro to use.
#define BareWord_comma(X) X ,
#define String_comma(X) #X ,
enum{ EACH_THING( BareWord_comma ) NUM_THINGS };
char*names[]={ EACH_THING( String_comma ) NULL };
Here the list of things isn't the argument list to a macro, but a sequence of macro invocations in the body of a macro. The important parts are all here, though: separating the list of things from the transformation to apply to each one.
Since you are accepting that the preprocessor has VA_ARGS (in C99, but not in the current C++ standard) you can go with P99. It has exactly what you are asking for: P99_FOR. It works without the crude ()()() syntax from BOOST. The interface is just
P99_FOR(NAME, N, OP, FUNC,...)
and you can use it with something like
#define P00_SEP(NAME, I, REC, RES) REC; RES
#define P00_VASSIGN(NAME, X, I) X = (NAME)[I]
#define MYASSIGN(NAME, ...) P99_FOR(NAME, P99_NARG(__VA_ARGS__), P00_SEP, P00_VASSIGN, __VA_ARGS__)
MYASSIGN(A, toto, tutu);
In C++ without extensions you could go for Boost.Preprocessor and it's sequences:
PRINT_ALL((a)(b)(c));
By using BOOST_PP_SEQ_FOR_EACH() on the sequence you can iterate it and easily generate code that prints them.
Untested straight-forward sample:
#define DO_PRINT(elem) std::cout << BOOST_PP_STRINGIZE(elem) << "=" << (elem) << "\n";
#define PRINT_ALL(seq) { BOOST_PP_SEQ_FOR_EACH(DO_PRINT, _, seq) }
Old question, but I thought I'd tack on a solution I came up with to use Boost.Preprocessor without the ugly (a)(b) syntax.
Header:
#include <iostream>
#include <boost\preprocessor.hpp>
#define _PPSTUFF_OUTVAR1(_var) BOOST_PP_STRINGIZE(_var) " = " << (_var) << std::endl
#define _PPSTUFF_OUTVAR2(r, d, _var) << _PPSTUFF_OUTVAR1(_var)
#define _PPSTUFF_OUTVAR_SEQ(vseq) _PPSTUFF_OUTVAR1(BOOST_PP_SEQ_HEAD(vseq)) \
BOOST_PP_SEQ_FOR_EACH(_PPSTUFF_OUTVAR2,,BOOST_PP_SEQ_TAIL(vseq))
#define OUTVAR(...) _PPSTUFF_OUTVAR_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
Usage:
int a = 3;
char b[] = "foo";
std::cout << OUTVAR(a);
// Expands to:
//
// std::cout << "a" " = " << (a ) << std::endl ;
//
// Output:
//
// a = 3
std::cout << OUTVAR(a, b);
// Expands to:
//
// std::cout << "a" " = " << (a ) << std::endl << "b" " = " << (b) << std::endl ;
//
// Output:
//
// a = 3
// b = foo
Nice and clean.
Of course you can replace the std::endl with a comma or something if you want it all on one line.
You can use Boost.PP (after adding Boost's boost folder to your list of include directories) to get macros for this. Here's an example (tested with GCC 8.1.0):
#include <iostream>
#include <limits.h>
#include <boost/preprocessor.hpp>
#define WRITER(number,middle,elem) std::cout << \
number << BOOST_PP_STRINGIZE(middle) << elem << "\n";
#define PRINT_ALL(...) \
BOOST_PP_SEQ_FOR_EACH(WRITER, =>, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
int main (int argc, char *argv[])
{
PRINT_ALL(INT_MAX, 123, "Hello, world!");
}
Output:
2=>2147483647
3=>123
4=>Hello, world!
The BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) part converts the variable-argument list to Boost's traditional way of expressing multiple arguments as a single argument, which looks like this: (item1)(item2)(item3).
Not sure why it starts numbering the arguments at two. The documentation just describes the first parameter as "the next available BOOST_PP_FOR repetition".
Here's another example that defines an enum with the ability to write it as a string to an ostream, which also enables Boost's lexical_cast<string>:
#define ENUM_WITH_TO_STRING(ENUMTYPE, ...) \
enum ENUMTYPE { \
__VA_ARGS__ \
}; \
inline const char* to_string(ENUMTYPE value) { \
switch (value) { \
BOOST_PP_SEQ_FOR_EACH(_ENUM_TO_STRING_CASE, _, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
default: return nullptr; \
} \
} \
inline std::ostream& operator<<(std::ostream& os, ENUMTYPE v)\
{ return os << to_string(v); }
#define _ENUM_TO_STRING_CASE(_,__,elem) \
case elem: return BOOST_PP_STRINGIZE(elem);
ENUM_WITH_TO_STRING(Color, Red, Green, Blue)
int main (int argc, char *argv[])
{
std::cout << Red << Green << std::endl;
std::cout << boost::lexical_cast<string>(Blue) << std::endl;
}
Output:
RedGreen
Blue
The preprocessor is not powerful enough to do stuff like this. However, you don't really need the preprocessor that badly. If all you want to do is to dump variable names and their values in a convenient manner. You could have two simple macros:
#define PRINT(x) \
{ \
std::ostringstream stream; \
stream << x; \
std::cout << stream.str() << std::endl; \
}
#define VAR(v) #v << ": " << v << ", "
You could then almost use your intended usage:
int a = 1, b = 3, d = 0;
PRINT(VAR(a) << VAR(b) << VAR(d))
This prints
a: 1, b: 3, d: 0,
There are a lot of ways to make this more powerful, but this works, allows you to print non-integer values nicely and it's a rather simple solution.