It is a VS2010 C++ project. I have a list of APIs:
int a = API1("para1", "para2", ...);
double a = API2("para1", "para2", ...);
float a = API3("para1", "para2", ...);
Now, I need to add a new API, APINEW(). As long as above APIs are run, APINEW need to called as follow. Therefore, I decided to use the Variadic Macros as shown below:
#define newAPI1(...) ( API1(__VA_ARGS__); APINEW() )
#define newAPI2(...) ( API2(__VA_ARGS__); APINEW() )
#define newAPI3(...) ( API3(__VA_ARGS__); APINEW() )
However, I will not correctly get the return value from my API1, API2 and API3.
I am trying to use the following code since I know the marco will always return the last item, but it cannot pass the compile.
#define newAPI1(...) ( {auto a = API1(__VA_ARGS__); APINEW(); a} )
I wonder is there a way that can make it correct?
(The reason I use new name (e.g. newAPI1) is to avoid comflict because in the project, it may have other macros that overload the existing API1, API2 and API3.)
Another question:
is there a way to pass the combination of
first parameter of __VA_ARGS__
__FUNCTION__
__LINE__
into the APINEW parameter => APINEW(first parameter of __VA_ARGS__ + __FUNCTION__ + __LINE__)
Something along these lines, perhaps.
template <typename FirstArg, typename... Args>
auto API1Helper(const char* file, int line, FirstArg&& first_arg, Args&&... args) {
auto ret = API1(first_arg, std::forward<Args>(args)...);
APINEW(first_arg, file, line);
return ret;
}
#define newAPI1(...) API1Helper(__FILE__, __LINE__, __VA_ARGS__)
Though this may require a compiler newer than VS2010.
In C++, using macros it is easy to pull apart arguments do the following:
#define printThings(stringPrinting, param1, param2) printf(stringPrinting, param1, param2)
printThings(stringPrinting, param1, param2)
// Goes to
printf(stringPrinting, param1, param2)
However I can't find a way to do this:
#define printThings(a, b) printf(?)
printThings(stringPrinting, Blarg(param1, param2))
// Goes to
printf(stringPrinting, param1, param2)
Is this possible?
You can just
#define UNPACK( a, b ) a, b
#define printThings( s, args ) printf( s, UNPACK args )
This is one of the staple macro idioms for advanced preprocessor stuff. The canonical technique for dealing with variadic arguments, e.g. to distribute some macro invocation over the arguments, was posted by some guy I don't remember (French?) in comp.lang.c or comp.std.c newsgroup ca 1999 I think it was, maybe later. The Boost preprocessor library as well as the Boost parameters library have lots of REALLY advanced stuff. If you want to learn. :)
Note 1: It looks like you really want a variadic macro, defined with ... (three dots) instead of named arguments. I'm sure you can google that.
Note 2: Since macros are Evilâ„¢ it may be that you really want some variation of
template< class... Args >
void printThings( char const* s, Args&&... args )
{
printf( s, std::forward<Args>( args )... );
}
Disclaimer: untested code.
I want to do for example:
#define macro(a) foo( _blah_, *(dword*)(&a) );
#define macro(a,b) foo( _blah_, *(dword*)(&a) , *(dword*)(&b) );
#define macro(a,b,c) foo( _blah_, *(dword*)(&a) , *(dword*)(&b) , *(dword*)(&c) );
But of course with variable no. of arguments. I essentially want to wrap each argument indiviudally, not pass all the arguments as one __VA_ARGS__ block.
As any other sane person, I advise you to drop the macros, especially with C++11's variadic templates:
template<class T>
dword& make_dword(T& v){
return *reinterpret_cast<dword*>(&v);
}
template<class... Args>
void bar(Args&... args){
foo(_blah_, make_dword(args)...);
}
This should do the trick.
I need to mention that those reinterpret_casts look pretty dubious, though...
When do I use __if_exists without writing tons of crappy code?
Looks like this keyword is like C preprocessor directive, but is processed after preprocessor. And IntelliSense doesn't parse it and highlight code as dead or alive. These together make analysis of code written with __if_exists really non-trivial.
So far I found only one relatively safe case. We have a container class that takes an address of stored object. When a class stored has an overloaded operator& that overloaded operator is called and this causes problems.
So I added the following check:
__if_exists( T::operator& ) {
static_assert( false );
}
and now the code at least won't compile if there's an operator& member function is the type stored.
IMO this use case is quite clear and easy to read.
What other cases are there of using __if_exists without getting tons of unreadable code?
Though I'm not sure this is always possible or useful, __if_exists can be
used as static if in D language in a sense.
For example, the following code prints b.
template< bool > struct static_if_t;
template<> struct static_if_t< true > {};
#define STATIC_IF( c ) __if_exists ( static_if_t< (c) > )
#define STATIC_UNLESS( c ) __if_not_exists( static_if_t< (c) > )
struct X {
static bool const v = false;
};
STATIC_IF( X::v ) {
void f() { puts("a"); }
}
STATIC_UNLESS( X::v ) {
void f() { puts("b"); }
}
int main() {
f(); // prints "b"
}
I think you can use it to distinguish unions and classes, since classes do have constructors and unions don't.
You'd want this in e.g. boost::type_traits::is_class<T> and boost::type_traits::is_union<T>
So I have a series of global functions, say:
foo_f1(int a, int b, char *c);
foo_f2(int a);
foo_f3(char *a);
I want to make a C++ wrapper around these, something like:
MyFoo::f1(int a, int b, char* c);
MyFoo::f2(int a);
MyFoo::f3(char* a);
There's about 40 functions like this, 35 of them I just want to pass through to the global function, the other 5 I want to do something different with.
Ideally the implementation of MyFoo.cpp would be something like:
PASSTHRU( f1, (int a, int b, char *c) );
PASSTHRU( f2, (int a) );
MyFoo::f3(char *a)
{
//do my own thing here
}
But I'm having trouble figuring out an elegant way to make the above PASSTHRU macro.
What I really need is something like the mythical X getArgs() below:
MyFoo::f1(int a, int b, char *c)
{
X args = getArgs();
args++; //skip past implicit this..
::f1(args); //pass args to global function
}
But short of dropping into assembly I can't find a good implementation of getArgs().
You could use Boost.Preprocessor to let the following:
struct X {
PASSTHRU(foo, void, (int)(char))
};
... expand to:
struct X {
void foo ( int arg0 , char arg1 ) { return ::foo ( arg0 , arg1 ); }
};
... using these macros:
#define DO_MAKE_ARGS(r, data, i, type) \
BOOST_PP_COMMA_IF(i) type arg##i
#define PASSTHRU(name, ret, args) \
ret name ( \
BOOST_PP_SEQ_FOR_EACH_I(DO_MAKE_ARGS, _, args) \
) { \
return ::name ( \
BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(args), arg) \
); \
}
At 40-odd functions, you could type the wrappers out by hand in an hour. The compiler will check the correctness of the result. Assume an extra 2 minutes for each new function that needs wrapping, and an extra 1 minute for a change in signature.
As specified, and with no mention of frequent updates or changes, it doesn't sound like this problem requires a cunning solution.
So, my recommendation is to keep it simple: do it by hand. Copy prototypes into source file, then use keyboard macros (emacs/Visual Studio/vim) to fix things up, and/or multiple passes of search and replace, generating one set of definitions and one set of declarations. Cut declarations, paste into header. Fill in definitions for the non-passing-through functions. This won't win you any awards, but it'll be over soon enough.
No extra dependencies, no new build tools, works well with code browsing/tags/intellisense/etc., works well with any debugger, and no specialized syntax/modern features/templates/etc., so anybody can understand the result. (It's true that nobody will be impressed -- but it will be the good kind of unimpressed.)
Slightly different syntax but...
#include <boost/preprocessor.hpp>
#include <iostream>
void f1(int x, int y, char* z) { std::cout << "::f1(int,int,char*)\n"; }
#define GENERATE_ARG(z,n,unused) BOOST_PP_CAT(arg,n)
#define GET_ARGS(n) BOOST_PP_ENUM(n, GENERATE_ARG, ~)
#define GENERATE_PARAM(z,n,seq) BOOST_PP_SEQ_ELEM(n,seq) GENERATE_ARG(z,n,~)
#define GENERATE_PARAMS(seq) BOOST_PP_ENUM( BOOST_PP_SEQ_SIZE(seq), GENERATE_PARAM, seq )
#define PASSTHROUGH(Classname, Function, ArgTypeSeq) \
void Classname::Function( GENERATE_PARAMS(ArgTypeSeq) ) \
{ \
::Function( GET_ARGS( BOOST_PP_SEQ_SIZE(ArgTypeSeq) ) ); \
}
struct test
{
void f1(int,int,char*);
};
PASSTHROUGH(test,f1,(int)(int)(char*))
int main()
{
test().f1(5,5,0);
std::cin.get();
}
You could get something closer to yours if you use tuples, but you'd have to supply the arg count to the base function (you can't derive a size from a tuple). Sort of like so:
PASSTHROUGH(test,f1,3,(int,int,char*))
That about what you're looking for? I knew it could be done; took about a half hour to solve. You seem to expect that there's an implicit 'this' that has to be gotten rid of but I don't see why...so maybe I misunderstand the problem. At any rate, this will let you quickly make default "passthrough" member functions that defer to some global function. You'll need a DECPASSTHROUGH for the class declaration if you want to skip having to declare them all...or you could modify this to make inline functions.
Hint: Use BOOST_PP_STRINGIZE((XX)) to test the output of preprocessor metafunctions.
My initial thought, and this probably won't work or others would have stated this, is to put all your base functions together in a class as virtual. Then, write the functionality improvements into inherited classes and run with it. It's not a macro wrapper, but you could always call the global functions in the virtual classes.
With some assembly trickery, you could probably do exactly what you'd want, but you would lose portability more than likely. Interesting question and I want to hear other's answers as well.
You may want to use a namespace if you want to not deal with class stuff, like this. You could also use static member methods in a class, but I think that people don't like that anymore.
#ifndef __cplusplus
#define PASSTHRU(type, prefix, func, args) type prefix##_##func args
#else
#define PASSTHRU(type, prefix, func, args) type prefix::func args
#endif
Or
#ifndef __cplusplus
#define PASSTHRU(type, prefix, func, ...) type prefix##_##func(__VA_ARGS__)
...
Perfect forwarding relies on rvalue references. STL has a blog entry on it at Link and you would want to choose a compiler that supported the feature to take this approach. He's discussing Visual C++ 2010.