PreProcessor: store array of strings at compile-time - c++

I need a container of strings at compile-time, which should be iterable at runtime.
However, I really need a macro, so that some functions will be produced (can't think of a way to do that with templated code at namespace-level).
But in the following code I get 'error: 'sequence' in 'class LaLaLa' does not name a type', which happens within the ASSIGN macro (I think).
Can somebody help me with this?
#define CREATE_FUNCTION(r, data, i, elem) // creates a function with name 'do_something_with_##elem()'
#define ASSIGN(r, data, i, elem) data::sequence[i] = elem;
#define TO_ARRAY(name, _seq) \
BOOST_PP_SEQ_FOR_EACH(CREATE_FUNCTION, _, _seq) \
class name \
{ \
public: \
static constexpr std::size_t size = BOOST_PP_SEQ_SIZE(_seq); \
static std::string sequence[size]; \
}; \
BOOST_PP_SEQ_FOR_EACH_I(ASSIGN, name, _seq)
TO_ARRAY(LaLaLa, (x)(y)(z)(a))
Then I would like to use it something like this:
do_something_with_x();
do_something_with_z();
std::vector<std::string> use_strings;
for(size_t i = 0; i < LaLaLa::size; ++i)
{
use_strings.push_back(LaLaLa::sequence[i]);
}
// use_strings == {"x", "y", "z", "a"}

The problem wasn't the preprocessor - using the sequence directly after the class definition is the problem. (needs to be done within a function or something like that)

Related

How to avoid re-declare variables with C++ Macros

I want to write a simple Macro function. Because this macro is used in many places by different normal c++ functions, I encountered a variable scope issue. I would like to know if there is a quick way to solve it? Thank you very much.
As you can see in the attached code, depending on whether the macro is called in the function for the first time or not, I want to either declare or reuse the variable ptrCandidate. Note the variable scope is in the function, not in the file or translation unit. In other words, every time the macro is invoked in a new function for the 1st time, I want the top macro. And within the same function, if the macro is invoked again, I want the bottom macro.
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
auto ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
void foo(){
EXPECT_MY_CLASS_EQ("123","abcd")
}
void bar(){
EXPECT_MY_CLASS_EQ("111","aabb")
EXPECT_MY_CLASS_EQ("222","ccdd")
}
void foo(){
auto ptrCandidate = parseAndGetPtr("abcd");
doWork(ptrCandidate);
EXPECT_EQ("123", convertToString(ptrCandidate));
}
void bar(){
auto ptrCandidate = parseAndGetPtr("aabb");
doWork(ptrCandidate);
EXPECT_EQ("111", convertToString(ptrCandidate));
/* auto */ ptrCandidate = parseAndGetPtr("ccdd");
doWork(ptrCandidate);
EXPECT_EQ("222", convertToString(ptrCandidate));
}
As shown in another answer, you don't need a macro in this case.
Generally speaking though, you can avoid re-definitions of variable names by the following means:
Use of __LINE__ preprocessor symbol (or __COUNTER__, though IIRC that's not standard). Note that creating a variable name with the preprocessor requires two levels of indirection (replace VARIABLE in the link with __LINE__).
A do { /* code */ } while(0) ... which is AFAIK the most common way to write macros that are more than just a simple expression.
A lambda which is immediately executed:
([](auto var) { /* code using var */ })(initExpressionForVar())
Note that each of these approaches actually creates a new variable each time, so is semantically different from your approach with two separate macros! This is especially important if the type of the (assigned) variable has a non-default assignment operator!
If, for some reason, you rely on the reuse of a single variable and the assignment to it, then IMO the easiest approach is to define two macros. One macro which declares the variable (and initializes it, if necessary), and another macro with the code which uses the variable.
It seems regular function works:
void EXPECT_MY_CLASS_EQ(const char* expectedStr, const char* candidateStr)
{
auto ptrCandidate = parseAndGetPtr(candidateStr);
doWork(ptrCandidate);
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
}
A possible way might be to use __LINE__ or __COUNTER__ with preprocessor symbol concatenation.
In your case, you probably don't need any macro: prefer some static inline function.
Here is a real-life example (using concatenation and __LINE__) from my Bismon's project file cmacros.h line 285 (it is in C, but the same trick could be done in C++)
#define LOCAL_FAILURE_HANDLE_ATBIS_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
struct failurehandler_stBM fh_##Lin \
= { \
.pA = {.htyp = typayl_FailureHandler_BM}, \
.failh_magic = FAILUREHANDLEMAGIC_BM, \
.failh_lockset = Lockset, \
.failh_reason = NULL, \
.failh_jmpbuf = {}}; \
curfailurehandle_BM = &fh_##Lin; \
volatile int failcod_##Lin = setjmp(fh_##Lin.failh_jmpbuf); \
FcodVar = failcod_##Lin; \
if (failcod_##Lin) { \
ReasonVar = fh_##Lin.failh_reason; \
PlaceVar = fh_##Lin.failh_place; \
goto Flabel; \
}; \
(void)0
#define LOCAL_FAILURE_HANDLE_AT_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
LOCAL_FAILURE_HANDLE_ATBIS_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar)
/// code using LOCAL_FAILURE_HANDLE_BM should probably backup and
/// restore the curfailurehandle_BM
#define LOCAL_FAILURE_HANDLE_BM(Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
LOCAL_FAILURE_HANDLE_AT_BM(__FILE__,__LINE__,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar)
Back to your question, if you still want a macro: just create a block, e.g.
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) do{ \
auto ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));} while(0)

instantiating template functions and classes with boost preprocess

Working with the seemingly standard w, x, y, z demos, suppose I have the following macro trying to be converted to an "iterable" preprocessor macro
#define INSTANTIATE_FUNC(rtype, func_name, ...) \
template rtype func_name< w > (__VA_ARGS__); \
template rtype func_name< x > (__VA_ARGS__); \
template rtype func_name< y > (__VA_ARGS__); \
template rtype func_name< z > (__VA_ARGS__);
For completeness, suppose we're trying to instantiate the following
struct w { static constexpr int data = 0; };
struct x { static constexpr int data = 1; };
struct y { static constexpr int data = 2; };
struct z { static constexpr int data = 3; };
template <class Data>
void printData(const std::string &prefix) {
std::cout << prefix << Data::data << std::endl;
}
INSTANTIATE_FUNC(void, printData, const std::string &prefix)
I made a minimal gist with a build system for convenience so that if you are interested in trying you don't have to recreate everything :)
I can't quite figure out how to approach this. The only functional (but not useful) stab
#include <boost/preprocessor/list/for_each.hpp>
#define LIST (w, (x, (y, (z, BOOST_PP_NIL))))
#define MACRO(r, data, elem) template void data < elem > (const std::string &prefix);
#define INSTANTIATE_FUNC(rtype, func_name, ...) \
BOOST_PP_LIST_FOR_EACH(MACRO, func_name, LIST)
This is works, but is clearly not adequate.
Why does this not also work with sequences?
#include <boost/preprocessor/seq/for_each.hpp>
// this does work, my code included the wrong header
// on what I was testing with (seq/for_each_i.hpp)
#define SEQ (x)(y)(z)(w)
#define INSTANTIATE_FUNC(rtype, func_name, ...) \
BOOST_PP_SEQ_FOR_EACH(MACRO, func_name, SEQ)
How should I approach building template rtype func_name < {w,x,y,z} > {args,in,__VA_ARGS__}? I tried quite a few different things, but the problem seems to be not being able to e.g. only extract w and then loop through __VA_ARGS__, then continue on. I've been trying like heck to get BOOST_PP_LIST_FOR_EACH_R to work. Is this at least the right thing to look at?
As a sanity check, you can't define a macro within a macro right? Something in the spirit of
#define INSTANTIATE_FUNC(rtype, func_name, ...) \
#define MACRO_##func_name(r, data, elem) data < elem > (__VA_ARGS__); \
BOOST_PP_LIST_FOR_EACH(MACRO_##func_name, func_name, LIST)
I'm ultimately working toward the goal of enabling optional extension of LIST / SEQ (SEQ seeming much easier to achieve this for) if that means anything. Thanks for any suggestions / resources.
Your problem seems to be that you need to deliver several pieces of data to your MACRO in BOOST_PP_(LIST|SEQ)_FOR_EACH and there is only one "slot" that you can use. The thing that you seem to be missing is the fact that you can group those pieces in, for example, a tuple and then access the different elements inside your MACRO using BOOST_PP_TUPLE_ELEM. Something like this could work:
//These are not required, just to help with readability
#define MACRO_GET_RETURN_TYPE(TUPLE) BOOST_PP_TUPLE_ELEM(3,0,TUPLE)
#define MACRO_GET_FUNC_NAME(TUPLE) BOOST_PP_TUPLE_ELEM(3,1,TUPLE)
#define MACRO_GET_ARGS_SEQ(TUPLE) BOOST_PP_TUPLE_ELEM(3,2,TUPLE)
#define MACRO(_, DATA, ELEM) template MACRO_GET_RETURN_TYPE(DATA) MACRO_GET_FUNC_NAME(DATA) < ELEM > (BOOST_PP_SEQ_ENUM(MACRO_GET_ARGS_SEQ(DATA)));
// with boost seq
#define SEQ (x)(y)(z)(w)
#define INSTANTIATE_FUNC(rtype, func_name, ...) \
BOOST_PP_SEQ_FOR_EACH(MACRO, (rtype,func_name,BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), SEQ)
Live on Wandbox
PS: No, you can't define a macro within a macro, and the code you posted here does work for sequences, the one in your gist does not due to using the wrong header.

How can I check if there is an assignment in a macro's parameter?

How can we check if there is an assignment in a macro param as in below example?
define:
#define value(x) {...}
call:
case a: value( a = 10 )
case b: value( 10 )
what i want to do is implement a string enum in below way:
#define STR_ENUM_DICT_ITEM_(value) [#((MethodX value)) stringValue]:##value,
#define STR_ENUM_DICT_ITEM(idx, value) STR_ENUM_DICT_ITEM_(value)
#define STR_ENUM(type, name, ...) \
typedef NS_ENUM (type, name){__VA_ARGS__}; \
NSString *name##_S(type value) \
{ \
static NSDictionary *values; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
values = #{ \
metamacro_foreach(STR_ENUM_DICT_ITEM, , __VA_ARGS__) \
}; \
}); \
return [values valueForKey:[#(value)stringValue]]; \
}
STR_ENUM(NSUInteger, MethodX,
Method1 = 100// this is comment
, Method2
, Method3 = Method1
);
so i need to check if there is a assignment in the param, or other way
can get the value of (Method1 = 100) or (Method3 = Method1), which result is 100, 100.
Not very efficient in terms of performance but it works:
#define value(x) \
do { \
assert(!strchr(#x, '=')); \
/* rest of macro */ \
} while (0)
This is a simple example only covering the two cases provided by the OP. However, using the # operator to convert the macro's argument into a "string" one can create as complex rules to test against as one likes.
Can you specify in more details which cases do you want to distinguish? How about
value(a)
value(a+2)
value(a==10)
value(a<=10)
value('=')
?
What do you want to happen in case it contains assignment? Compilation error or something other?
For a compilation error, I managed to get the following work
#define check(a) if (a==a);
int main() {
int a;
check(10);
check(a);
check(a+2);
check(a==10);
check(a<=10);
check('=');
check(a=10);
return 0;
}
Every macros except the a=10 compiles. The latter turns into a=10==a=10, which does not compile.

Confusing macro definition in C++

Recently,I am reading some code from B-Human and I ecountered this confusing snippet:
void enumInit(char* enums, const char** names, int numOfEnums);
#define ENUM(Enum, ...) \
enum Enum : unsigned char {__VA_ARGS__, numOf##Enum##s}; \
inline static const char* getName(Enum e) \
{ \
static char enums[] = #__VA_ARGS__; \
static const char* names[numOf##Enum##s]; \
static bool init = true; \
if(init) \
{ \
enumInit(enums, names, numOf##Enum##s); \
init = false; \
} \
return e >= numOf##Enum##s ? 0 : names[e]; \
}
I cannot understand how this macro works, how could it be a function definition in a macro definition? It is a single cpp header file with #pragma once.
void enumInit(char* enums, const char** names, int numOfEnums);
Isn't defined anywhere in the code you posted, so strictly speaking I don't know what it does.
#define ENUM(Enum, ...) \
enum Enum : unsigned char {__VA_ARGS__, numOf##Enum##s}; \
This defines an enum with the values passed to the macro as "..." (google "variadic macro") as values, and an additional entry whose value is the number of elements in that macro and whose name is the concatenation of "numOf", the value of Enum (passed as a parameter) and "s". This last value is the entry with both value and position n if the enum contains n other values (starting at 0).
inline static const char* getName(Enum e) \
{ \
static char enums[] = #__VA_ARGS__; \
static const char* names[numOf##Enum##s]; \
static bool init = true; \
if(init) \
{ \
enumInit(enums, names, numOf##Enum##s); \
init = false; \
} \
return e >= numOf##Enum##s ? 0 : names[e]; \
}
This defines an inline function whereever your macro is called. It defines a static array containing the stringified value of the of the enum entries (enums[]), and their names (names[...]). On the first fall, enumInit(...) is called. Likely, this function fills the names array with the names of the respective enum values. For this, the string stored inside enums[] is used. To know how exactly that works, I would need to know the definition of enumInit.
edit: To more clearly answer the how could it be a function defination in a macro defination? part of your question: The macro itself is just pasted wherever it is used. The function definition is inserted whereever it is called, so that one function is generated per macro call.

Rare cases where MACROs must be used

Debugging macros can take a lot of time. We are much better off
avoiding them except in the very rare cases when neither constants,
functions nor templates can do what we want.
What are the rare cases?
If you want actual textual replacement, that's where you use macros. Take a look at Boost.Preprocessor, it's a great way to simulate variadic templates in C++03 without repeating yourself too much.
In other words, if you want to manipulate the program code itself, use macros.
Another useful application is assert, which is defined to be a no-op when NDEBUG is not defined (usually release mode compilation).
That brings us to the next point, which is a specialization of the first one: Different code with different compilation modes, or between different compilers. If you want cross-compiler support, you can't get away without macros. Take a look at Boost in general, it needs macros all the time because of various deficiencies in various compilers it has to support.
Another important point is when you need call-site information without wanting to bug the user of your code. You have no way to automatically get that with just a function.
#define NEEDS_INFO() \
has_info(__FILE__, __LINE__, __func__)
With a suitable declaration of has_info (and C++11/C99 __func__ or similar).
This question doesn't appear to have a definite, closed-form answer, so I'll just give a couple of examples.
Suppose you want to print information about a given type. Type names don't exist in the compiled code, so they cannot possibly be expressed by the language itself (except for C++ extensions). Here the preprocessor must step in:
#define PRINT_TYPE_INFO(type) do { printf("sizeof(" #type ") = %zu\n", sizeof(type)); } while (false)
PRINT_TYPE_INFO(int);
PRINT_TYPE_INFO(double);
Similarly, function names are not themselves variable, so if you need to generate lots of similar names, the preprocessor helps:
#define DECLARE_SYM(name) fhandle libfoo_##name = dlsym("foo_" #name, lib);
DECLARE_SYM(init); // looks up "foo_init()", declares "libfoo_init" pointer
DECLARE_SYM(free);
DECLARE_SYM(get);
DECLARE_SYM(set);
My favourite use is for dispatching CUDA function calls and checking their return value:
#define CUDACALL(F, ARGS...) do { e = F(ARGS); if (e != cudaSuccess) throw cudaException(#F, e); } while (false)
CUDACALL(cudaMemcpy, data, dp, s, cudaMemcpyDeviceToHost);
CUDACALL(cudaFree, dp);
Since this an Open ended Question an trick which I often use and find convenient.
If you want to write an wrapper function over an free function like say malloc, without modifying each and every instance in your code where the function is called then a simple macro shall suffice:
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
/*Link List functionality goes in here*/
return p;
}
You can often use this trick to write your own memory leak detector etc, for debugging purposes.
Though the example is for malloc it can be re-used for any free standing function really.
One example is token pasting if you want to use a value as both an identifier and a value. From the msdn link:
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
paster( 9 ); // => printf_s( "token9 = %d", token9 );
There are also cases in the c++ faq where though there may be alternatives the macro solution is the best way to do things. One example is pointers to member functions where the right macro
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
makes it much easier to make the call rather than deal with all the assorted hair of trying to do it w/out the macro.
int ans = CALL_MEMBER_FN(fred,p)('x', 3.14);
Honestly I just take their word for it and do it this way, but apparently it gets worse as the calls become more complicated.
Here's an example of someone trying to go it alone
When you need the call itself to optionally return from a function.
#define MYMACRO(x) if(x) { return; }
void fn()
{
MYMACRO(a);
MYMACRO(b);
MYMACRO(c);
}
This is usually used for small bits of repetitive code.
I am not sure that debugging macros take a lot of time. I would believe that I find simple the debugging of macros (even 100 lines monster macros), because you have the possibility to look at the expansion (using gcc -C -E for instance) - which is less possible with e.g. C++ templates.
C macros are useful when in several occasions:
you want to process a list of things in several different ways
you want to define an "lvalue" expression
you need efficiency
you need to have the location of the macro thru __LINE__)
you need unique identifiers
etc etc
Look at the many uses of #define-d macros inside major free softwaare (like Gtk, Gcc, Qt, ...)
What I regret a lot is that C macro language is so limited.... Imagine if the C macro language would have been as powerful as Guile!!! (Then you could write things as complex as flex or bison as macros).
Look at the power of Common Lisp macros!
If you are using C, you need to use macros to simulate templates.
From http://www.flipcode.com/archives/Faking_Templates_In_C.shtml
#define CREATE_VECTOR_TYPE_H(type) \
typedef struct _##type##_Vector{ \
type *pArray; \
type illegal; \
int size; \
int len; \
} type##_Vector; \
void type##_InitVector(type##_Vector *pV, type illegal); \
void type##_InitVectorEx(type##_Vector *pV, int size, type illegal); \
void type##_ClearVector(type##_Vector *pV); \
void type##_DeleteAll(type##_Vector *pV); \
void type##_EraseVector(type##_Vector *pV); \
int type##_AddElem(type##_Vector *pV, type Data); \
type type##_SetElemAt(type##_Vector *pV, int pos, type data); \
type type##_GetElemAt(type##_Vector *pV, int pos);
#define CREATE_VECTOR_TYPE_C(type) \
void type##_InitVector(type##_Vector *pV, type illegal) \
{ \
type##_InitVectorEx(pV, DEF_SIZE, illegal); \
} \
void type##_InitVectorEx(type##_Vector *pV, int size, type illegal) \
{ \
pV-len = 0; \
pV-illegal = illegal; \
pV-pArray = malloc(sizeof(type) * size); \
pV-size = size; \
} \
void type##_ClearVector(type##_Vector *pV) \
{ \
memset(pV-pArray, 0, sizeof(type) * pV-size); \
pV-len = 0; \
} \
void type##_EraseVector(type##_Vector *pV) \
{ \
if(pV-pArray != NULL) \
free(pV-pArray); \
pV-len = 0; \
pV-size = 0; \
pV-pArray = NULL; \
} \
int type##_AddElem(type##_Vector *pV, type Data) \
{ \
type *pTmp; \
if(pV-len = pV-size) \
{ \
pTmp = malloc(sizeof(type) * pV-size * 2); \
if(pTmp == NULL) \
return -1; \
memcpy(pTmp, pV-pArray, sizeof(type) * pV-size); \
free(pV-pArray); \
pV-pArray = pTmp; \
pV-size *= 2; \
} \
pV-pArray[pV-len] = Data; \
return pV-len++; \
} \
type type##_SetElemAt(type##_Vector *pV, int pos, type data) \
{ \
type old = pV-illegal; \
if(pos = 0 && pos <= pV-len) \
{ \
old = pV-pArray[pos]; \
pV-pArray[pos] = data; \
} \
return old; \
} \
type type##_GetElemAt(type##_Vector *pV, int pos) \
{ \
if(pos = 0 && pos <= pV-len) \
return pV-pArray[pos]; \
return pV-illegal; \
}
Consider the standard assert macro.
It uses conditional compilation to ensure that the code is included only in debug builds (rather than relying on the optimizer to elide it).
It uses the __FILE__ and __LINE__ macros to create references to the location in the source code.
I've once used macro to generate a large string array along with index enumeration:
strings.inc
GEN_ARRAY(a)
GEN_ARRAY(aa)
GEN_ARRAY(abc)
GEN_ARRAY(abcd)
// ...
strings.h
// the actual strings
#define GEN_ARRAY(x) #x ,
const char *strings[]={
#include "strings.inc"
""
};
#undef GEN_ARRAY
// indexes
#define GEN_ARRAY(x) enm_##x ,
enum ENM_string_Index{
#include "strings.inc"
enm_TOTAL
};
#undef GEN_ARRAY
It is useful when you have several array that has to be kept synchronized.
To expand on #tenfour's answer about conditional returns: I do this a lot when writing Win32/COM code where it seems I'm checking an HRESULT every second line. For example, compare the annoying way:
// Annoying way:
HRESULT foo() {
HRESULT hr = SomeCOMCall();
if (SUCCEEDED(hr)) {
hr = SomeOtherCOMCall();
}
if (SUCCEEDED(hr)) {
hr = SomeOtherCOMCall2();
}
// ... ad nauseam.
return hr;
}
With the macro-y nice way:
// Nice way:
HRESULT foo() {
SUCCEED_OR_RETURN(SomeCOMCall());
SUCCEED_OR_RETURN(SomeOtherCOMCall());
SUCCEED_OR_RETURN(SomeOtherCOMCall2());
// ... ad nauseam.
// If control makes it here, nothing failed.
return S_OK;
}
It's doubly handy if you wire up the macro to log any failures automatically: using other macro ideas like token pasting and FILE, LINE, etc; I can even make the log entry contain the code location and the expression that failed. You could also throw an assert in there if you wanted to!
#define SUCCEED_OR_RETURN(expression) { \
HRESULT hrTest = (expression); \
if (!SUCCEEDED(hrTest)) { \
logFailure( \
#expression, \
HResultValueToString(hrTest), \
__FILE__, \
__LINE__, \
__FUNCTION__); \
return hrTest; \
} \
}
Debugging would be much easier as your project will be in divided into various modules for each task. Macros can be very useful when you have a large and complex software project. But there are some pitfalls which are stated here.
For me it's more comfortable to use macros for constants and for parts of code that have no separated logical functionality. But there are some important differences between (inline) functions and (function-like) macros, here they are:
http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx