Using a C++ macro to pull out items from nested parentheses - c++

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.

Related

How to keep original function return value after using Variadic Macros?

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.

Cannot use Macro in a C++ constructor?

I have a complex class that I was trying to simplify with a Macro. The Macro works fine with some compilers, but not with others. I was thinking that a macro was just text replacement, am I wrong?
struct FooManager
{
FooManager(){}
void Add( Foo* i_pFoo ){ m_FooObjects.Add( i_pFoo ); }
private:
DynamicArray<Foo*> m_FooObjects;
};
struct Foo
{
Foo( FooManager& mgr, int param1, int param2 = 0 )
: m_Param1( param1 )
, m_Param2( param2 )
{
mgr.Add( this );
}
private:
const int m_Param1, m_Param2;
}
class Bar
{
FooManager m_Manager;
Foo m_Foo1, m_Foo2;
public:
Bar();
};
Then in the .cpp file...
#define Macro( f, a, ... ) f( m_Manager, a, __VA_ARGS__ )
Bar::Bar()
: m_Manager()
, Macro( m_Foo1, 1 )
, Macro( m_Foo2, 2, 3 )
{}
I get an "error 29: expected an expression" when using a gcc compiler.
All I really want is my Bar to have a Manager that knows about all of the Foo's in it. I can unroll the Macro, but was hoping I didn't have to because it makes things look a lot cleaner, and it can provide other shared parameters based on usage.
I am inclined to believe that there is a rule I am breaking by doing this, and that the compilers that it does work with are for some reason ignoring this rule.
In situations when __VA_ARGS__ is empty (e.g. when expanding Macro( m_Foo1, 1 )) your macro will generate the following entry in the constructor initializer list
m_Manager(<some argument>, )
This is obviously invalid. The idea of __VA_ARGS__ is that you should supply at least one argument for the __VA_ARGS__ part.
In order to make __VA_ARGS__ easier to use in such contexts, compilers like MSVC are known to implement non-standard behavior in this case: they quietly remove the excessive comma, making your original code to compile as intended.
GCC also implements a non-standard extension that serves the same purpose, but you have to activate it by using a non-standard trick with ##
#define Macro( f, a, ... ) f( m_Manager, a, ##__VA_ARGS__ )
This will automatically remove the trailing comma in GCC when __VA_ARGS__ is empty.

C++ createObject() Factory

I would like to create a simple factory method with a simple C++ syntax:
void *createObject(const char *str,...)
{
if(!strcmp("X",str))
return new X(...);
}
I cannot figure out the syntax for this. I've been looking at template metaprogramming and use mpl::vectors, but I am not sure how to pass down this syntax. I want to really avoid using C va_lists if possible and go for a clean syntax like the one above.
This would be a better approach on C++11:
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
if( name == "X" )
{
return try_make_shared< X >( std::forward< Args >( args )... );
}
/* other cases here*/
return nullptr;
}
template< typename T, typename ...Args >
typename std::enable_if<
std::is_constructible< T, Args >::value
, std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
return std::make_shared< X >( std::forward< Args >( args )... );
}
template< typename T, typename ...Args >
typename std::enable_if<
!std::is_constructible< T, Args >::value
, std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
throw std::invalid_argument( "The type is not constructible from the supplied arguments" );
return nullptr;
}
The differences with your code are
It uses a variadic template function instead of an ellipsis argument, thus the number and type of the parameters are still available at compile time (you don't loose type checking). Additionally you can call this function with non-POD types.
It returns a shared_ptr<void> instead of a plain void*. This allows you to control from within the factory how the object should be cleaned once all references to it are gone. The user doesn't need to know or care if he should call the standard delete, or maybe a deleteObject method from your factory.
Update: For those suggesting unique_ptr, you can read here about the possibilities that a shared_ptr brings to the table. A restricted factory that does only ever return pointers to new-ly allocated objects may and should use a unique_ptr.
In addition to the code on how to create objects using the nice C++11 variadic templates (as seen in K-ballo's answer), this answer shows how I would handle a set of classes in a project. This method is a big hack and only recommended if you know what you're doing, however, when adding new classes to your project, you only have to add them to a single file listing all your classes, so if the project gets huge, it helps to keep the overview.
Use this approach only, if you have to list your classes multiple times, for example if you also want to have a std::string className() function, for example, returning the name of a class without using C++ runtime type information. Every such function which requires to list all classes in your project can be implemented in a similar way than the following.
classes.h
/* For every class in your project which should be creatable through your
* factory, add a line here. */
CLASS(Foo)
CLASS(Bar)
CLASS(Baz)
factory.cpp
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
// Define what code to insert for every class:
#define CLASS(T) \
else if(name == #T) \
return std::make_shared<T>(std::forward(args)...);
// List all cases:
if(0) /*do nothing*/; // <-- needed because the macro uses else if
#include "classes.h"
#undef CLASS
return nullptr;
}
If you can't use variadic templates, and don't want to use C-style varargs, your only option is to come up with some common representation for the arguments.
boost::shared_ptr<void> createObject(const char *str,
int argc, const char *argv[])
{
if(!strcmp("X",str))
return new X(argc, argv);
if(!strcmp("Y",str))
return make_Y(argc, argv);
}
as illustrated for Y, it may be sensible to split the argument handling out into a factory function instead of coupling your constructor to the option format. For example, you might want to switch to a property map or Boost program options.
The solution I ended up using was to create 0, N singletons with templated parameters. It is working pretty well with N = 8. A bit ugly, but only needs to be done once.

C++ wrapping variable argument macros

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...

How can one make a 'passthru' function in C++ using macros or metaprogramming?

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.