Is it possible to use #if 0 inside a multiline macro - c++

I want to implement something like below
#define MACRO_X \
MACRO_1 \
MACRO_2 \
#if condition
MACRO_3 \
#endif
MACRO_4 \

You can't embed preprocessor directives into macros. Instead, do this:
#if condition
#define IF_COND(...) __VA_ARGS__
#else
#define IF_COND(...)
#endif
Then:
#define MACRO_X \
MACRO_1 \
MACRO_2 \
IF_COND( \
MACRO_3 \
) \
MACRO_4 \

Related

Token detection within a C preprocessor macro argument

In order to nicely fix https://github.com/ned14/outcome/issues/244#issuecomment-774181015, I want to know if it is possible to detect whether a token sequence is present within a C preprocessor macro argument?
#define OUTCOME_TRY_GLUE2(x, y) x##y
#define OUTCOME_TRY_GLUE(x, y) OUTCOME_TRY_GLUE2(x, y)
#define OUTCOME_TRY_UNIQUE_NAME OUTCOME_TRY_GLUE(unique, __COUNTER__)
#define OUTCOME_TRYV2_SUCCESS_LIKELY(unique, ...) \
auto &&unique = (__VA_ARGS__)
#define OUTCOME_TRY2_SUCCESS_LIKELY(unique, v, ...) \
OUTCOME_TRYV2_SUCCESS_LIKELY(unique, __VA_ARGS__); \
v = std::move(unique).value()
#define OUTCOME_TRYA(v, ...) OUTCOME_TRY2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, v, __VA_ARGS__)
/* I'd like this to generate:
auto unique0 = (expr); auto x = std::move(unique0).value();
*/
OUTCOME_TRYA(auto x, expr);
/* I'd like this to generate:
auto &&unique1 = (expr); auto &&x = std::move(unique1).value();
*/
OUTCOME_TRYA(auto &&x, expr);
(https://godbolt.org/z/MW74cG may be more useful)
What one needs to achieve here is detection of && within the expansion of the v macro argument, but not if it is nested within ()<>".
Other answers on Stackoverflow can find a string within a C preprocessor macro argument, however those techniques can't work here because macro token paste of STRING_ ## && isn't legal. This level of C preprocessor hackery is beyond my capabilities, so I ask Stackoverflow. Thanks in advance for any help.
What one needs to achieve here is detection of && within the expansion of the v macro argument, but not if it is nested within ()<>".
No, it is not possible. I suggest separating the type from the name in a separate argument.
OUTCOME_TRYA_NEW(auto, x, expr);
OUTCOME_TRYA_NEW(auto &&, x, expr);
You could move the detection to runtime with stringify, like:
#define OUTCOME_TRYA(v, ...) \
if constexpr (your_constexpr_strstr(#v, "&&")) { \
/* do stuff with `auto &&` here */ \
} else { \
/* do stuff with `auto` here */ \
}
(or I think also with some std::is_same(decltype(v)....) stuff), but as you want to declare variables in the macro expansion, I think that's not helpful.
Another way you could use is to delay the expansion of first argument to later phase so you could overload it on number of arguments, like so:
// Add a comma. But later.
#define OUTCOME_REF(name) &&, name
#define OUTCOME_TRYA_CHOOSE_1(name, ...) \
auto unique0 = (__VA_ARGS__); name = std::move(unique0).value();
#define OUTCOME_TRYA_CHOOSE_2_IN(name, ...) \
auto &&unique1 = (__VA_ARGS__); name = std::move(unique1).value();
#define OUTCOME_TRYA_CHOOSE_2(name, ...) \
OUTCOME_TRYA_CHOOSE_2_IN(name __VA_ARGS__)
// ^^^^^^ I have no idea why it works without a comma, but it does. It's scary.
#define OUTCOME_TRYA_CHOOSE_N(_1,_2,N,...) \
OUTCOME_TRYA_CHOOSE_##N
#define OUTCOME_TRYA_CHOOSE(...) \
OUTCOME_TRYA_CHOOSE_N(__VA_ARGS__,2,1)
#define OUTCOME_TRYA(name, ...) \
OUTCOME_TRYA_CHOOSE(name)(name, __VA_ARGS__)
// ^^^^ - overload on number of arguments in expansion of first parameter
OUTCOME_TRYA(auto x, expr1) // auto unique0 = (expr1); auto x = std::move(unique0).value();
OUTCOME_TRYA(auto OUTCOME_REF(x), expr2) // auto &&unique1 = (expr2); auto && x = std::move(unique1).value();
In similar fashion you could refactor your interface seamlessly to:
#define UNPACK(...) __VA_ARGS__
#define OUTCOME_TRYA_CHOOSE_1(name, nameunpacked, ...) \
auto unique0 = (__VA_ARGS__); name = std::move(unique0).value();
#define OUTCOME_TRYA_CHOOSE_2_IN(name1, name2, ...) \
auto &&unique1 = (__VA_ARGS__); name1 name2 = std::move(unique1).value();
#define OUTCOME_TRYA_CHOOSE_2(name, nameunpacked, ...) \
OUTCOME_TRYA_CHOOSE_2_IN(nameunpacked, __VA_ARGS__)
#define OUTCOME_TRYA_CHOOSE_N(_1,_2,_3,N,...) \
OUTCOME_TRYA_CHOOSE_##N
#define OUTCOME_TRYA_CHOOSE(n, ...) \
OUTCOME_TRYA_CHOOSE_N(n, __VA_ARGS__, 2, 1)
#define OUTCOME_TRYA(name, ...) \
OUTCOME_TRYA_CHOOSE(name, UNPACK name)(name, UNPACK name, __VA_ARGS__)
OUTCOME_TRYA(auto x, expr1, expr2)
OUTCOME_TRYA((auto &&, x), expr3, expr4)
The above looks nice and allows for the current interface to stay. The trick is in OUTCOME_TRYA_CHOOSE(name, UNPACK name) - when name is (something, something), then OUTCOME_TRYA_CHOOSE_N is passed 3 arguments, if it's not, then 2 arguments are passed - which can be then overloaded on number of arguments. So it effectively overloads if the input contains braces with a comma inside.
I don't suppose you know of a way to achieve OUTCOME_TRYV((auto &&), expr1, expr2)
Meh ;p . Add a comma when unpacking, effectively shifting overloads to one more.
#define UNPACK_ADD_COMMA(...) ,__VA_ARGS__
#define OUTCOME_TRYA_CHOOSE_1(name, nameunpacked, ...) \
auto unique0 = (__VA_ARGS__); name = std::move(unique0).value();
#define OUTCOME_TRYA_CHOOSE_2_IN(name1, ...) \
OCH_MY_GOD()
#define OUTCOME_TRYA_CHOOSE_3_IN(name1, name2, ...) \
auto &&unique1 = (__VA_ARGS__); name1 name2 = std::move(unique1).value();
#define OUTCOME_TRYA_CHOOSE_2(name, nameunpacked, ...) \
OUTCOME_TRYA_CHOOSE_2_IN(nameunpacked, __VA_ARGS__)
#define OUTCOME_TRYA_CHOOSE_3(name, ignore, nameunpacked, ...) \
OUTCOME_TRYA_CHOOSE_3_IN(nameunpacked, __VA_ARGS__)
#define OUTCOME_TRYA_CHOOSE_N(_1,_2,_3,_4,N,...) \
OUTCOME_TRYA_CHOOSE_##N
#define OUTCOME_TRYA_CHOOSE_IN(n, ...) \
OUTCOME_TRYA_CHOOSE_N(n, __VA_ARGS__, 3, 2, 1)
#define OUTCOME_TRYA_CHOOSE(n, ...) \
OUTCOME_TRYA_CHOOSE_IN(n, __VA_ARGS__)
#define OUTCOME_TRYA(name, ...) \
OUTCOME_TRYA_CHOOSE(name, UNPACK_ADD_COMMA name)(name, UNPACK_ADD_COMMA name, __VA_ARGS__)
OUTCOME_TRYA(auto x, expr1, expr2)
OUTCOME_TRYA((auto &&, x), expr3, expr4)
OUTCOME_TRYA((auto &&), expr3, expr4)

Setting enumerated values based on string representions

I have a config file containing string representations of an enum. There are a lot of different enum values. After loading the config, I need to work out enum values from it string representations. Ignoring macros, the only way I can think of doing this would be to create a hideous lookup function doing a string comparison against every possible value. Something like:
typedef enum Fields
{
FieldFlagNone,
FieldFlagOperation,
FieldFlagFormat,
...
}
Fields getFieldEnum(string fieldName){
if( fieldName.compare("FieldFlagNone") == 0 ){
return FieldFlagNone;
}else if( fieldName.compare("FieldFlagOperation") == 0 ){
return FieldFlagOperation;
}else if( fieldName.compare("FieldFlagFormat") == 0 ){
return FieldFlagFormat;
...
}
Is there a faster or more concise way of achieving the desired result?
You can use std::unordered_map<std::string, Fields>, that will speed up the conversion from linear time to constant time:
std::unordered_map<std::string, Fields> fieldsLookupTable {
{ "FieldFlagNone", FieldFlagNone },
...
};
To make it more concise you can use some macros:
#define LOOKUP_TABLE_ENTRY(x) { #x, x }
And then:
std::unordered_map<std::string, Fields> fieldsLookupTable {
LOOKUP_TABLE_ENTRY(FieldFlagNone),
LOOKUP_TABLE_ENTRY(FieldFlagOperation),
...
};
If you want to go really hardcore on eliminating duplication, you can do something like this:
#define ENUM_MODE_DEFINE 0
#define ENUM_MODE_LOOKUP 1
#define ENUM_BEGIN(x) \
#if ENUM_MODE == ENUM_MODE_DEFINE \
typedef enum x { \
#else \
#define LOOKUP_TABLE_NAME x ## LookupTable \
std::unordered_map<std::string, x> LOOKUP_TABLE_NAME; \
#endif
#define ENUM_ENTRY(x) \
#if ENUM_MODE == ENUM_MODE_DEFINE \
x, \
#else \
LOOKUP_TABLE_NAME[#x] = x; \
#endif
#define ENUM_END \
#if ENUM_MODE == ENUM_MODE_DEFINE \
} \
#else \
#undef LOOKUP_TABLE_NAME \
#endif
And then define your enum like this:
#define FIELDS \
ENUM_BEGIN(Fields) \
ENUM_ENTRY(FieldFlagNone) \
ENUM_ENTRY(FieldFlagOperation) \
...
ENUM_END
And where previously there was the enum definition, now there will be this:
#define ENUM_MODE ENUM_MODE_DEFINE
FIELDS
And somewhere else where you had the lookup table, you say this:
#define ENUM_MODE ENUM_MODE_LOOKUP
FIELDS
Basically the FIELDS macro uses the ENUM_BEGIN, ENUM_ENTRY and ENUM_END macros, which generate different code based on the value of ENUM_MODE. If you define it to be ENUM_MODE_DEFINE, then FIELDS will generate the enum definition. If you set it to ENUM_MODE_LOOKUP, it'll generate fieldsLookupTable.
This way we only used the enum entry names in FIELDS, so if you change something there, the lookup table and the enum definition will change automatically and won't go out of sync.

Q_PROPERTY macro within another macro

How to put the Q_PROPERTY macro inside another, helper-macro?
#define SimpleAllinOne(member, _type) \
public: \
void Set##member(_type _arg_##member) \
{ \
m_##member = _arg_##member;\
} \
_type Get##member() const\
{ \
return m_##member;\
} \
private: \
_type m_##member; \
Q_PROPERTY(_type member READ Get##member WRITE Set##member)
.. does not work. Preprocessor output (gcc -E flag or nmake/jom /P flag) shows the (working) setter/getter methods and corresponding member variable but not a single character for the Q_PROPERTY line.
Update: It seems to work with Qt5.1 which expands the user macros properly. Qt4.8 does not work, Qt5.0 has not been tested. See #QTBUG-35 (thanks to ??).
moc in Qt4.x does not recognize Q_ macros within preprocessor macros.
moc in Qt5.x expands the preprocessor macros before parsing the Q_ macros.
You have a bug too in the lines
Set##member##(_type _arg_##member) \
_type Get##member##() const\
because of ##() which is evaluated to
SetArg(
_type GetArg(
by gcc and rejected (MSVC ignores it).
Try the following corrected version and it should work:
#define MachAlles(member, _type) \
public: \
/**
* Set member of type _type.
* #see m_##member for a more detailed description
*/ \
void Set##member(_type _arg_##member) \
{ \
m_##member = _arg_##member;\
} \
/**
* Get member of type _type.
* #see m_##member for a more detailed description
*/ \
_type Get##member() const\
{ \
return m_##member;\
} \
private: \
_type m_##member; \
Q_PROPERTY(_type member READ Get##member WRITE Set##member)

How to disable C4127 for do {} while(false) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C/C++: How to use the do-while(0); construct without compiler warnings like C4127?
//file error.h
#define FAIL(message) \
do { \
std::ostringstream ossMsg; \
ossMsg << message; \
THROW_EXCEPTION(ossMsg.str());\
} while (false)
//main.cpp
...
FAIL("invalid parameters"); // <<< warning C4127: conditional expression is constant
...
As you can see the warning is related to the do {} while(false).
I can only figure out the following way to disable the warning:
#pragma warning( push )
#pragma warning( disable : 4127 )
FAIL("invalid parameters");
#pragma warning( pop )
but I don't like this solution.
I also tried to put those macro in error.h without effect.
Any comments on how to suppress this warning in a decent way?
Thank you
The warning is due to the while(false). This site gives an example of how to workaround this problem. Example from site (you'll have to re-work it for your code):
#define MULTI_LINE_MACRO_BEGIN do {
#define MULTI_LINE_MACRO_END \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
} while(0) \
__pragma(warning(pop))
#define MULTI_LINE_MACRO \
MULTI_LINE_MACRO_BEGIN \
std::printf("Hello "); \
std::printf("world!\n"); \
MULTI_LINE_MACRO_END
Just insert your code between the BEGIN and END:
#define FAIL(message) \
MULTI_LINE_MACRO_BEGIN \
std::ostringstream ossMsg; \
ossMsg << message; \
THROW_EXCEPTION(ossMsg.str());\
MULTI_LINE_MACRO_END
1) Why not just THROW_EXCEPTION("invalid parameters")?
2) while(true) and break at the end?

"#ifdef" inside a macro [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
#ifdef inside #define
How do I use the character "#" successfully inside a Macro? It screams when I do something like that:
#define DO(WHAT) \
#ifdef DEBUG \
MyObj->WHAT() \
#endif \
You can't do that. You have to do something like this:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT) do { } while(0)
#endif
The do { } while(0) avoids empty statements. See this question, for example.
It screams because you can't do that.
I suggest the following as an alternative:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
It seems that what you want to do can be achieved like this, without running into any problems:
#ifdef DEBUG
# define DO(WHAT) MyObj->WHAT()
#else
# define DO(WHAT) while(false)
#endif
Btw, better use the NDEBUG macro, unless you have a more specific reason not to. NDEBUG is more widely used as a macro that means no-debugging. For example the standard assert macro can be disabled by defining NDEBUG. Your code would become:
#ifndef NDEBUG
# define DO(WHAT) MyObj->WHAT()
#else
# define DO(WHAT) while(false)
#endif
You can do the same thing like this:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
How about:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif