#include <utility>
#include <type_traits>
#include <cstddef>
#include <iostream>
#define CONCAT2( a, b ) a##b
#define CONCAT( a, b ) CONCAT2(a,b)
// SFINAE helper boilerplate:
template<typename T> struct is_type:std::true_type {};
template<std::size_t n> struct secret_enum { enum class type {}; };
template<bool b, std::size_t n>
using EnableIf = typename std::enable_if< b, typename secret_enum<n>::type >::type;
// Macro that takes a srcF name and a dstF name and an integer N and
// forwards arguments matching dstF's signature. An integer N must be
// passed in with a distinct value for each srcF of the same name:
#define FORWARD_FUNC( srcF, dstF, N ) \
template< typename... Args, \
EnableIf< is_type< \
decltype( dstF ( std::forward<Args>(std::declval<Args>())... )) \
>::value , N >... > \
auto srcF ( Args&&... args ) \
-> decltype(dstF ( std::forward<Args>(args)... )) \
{ \
dstF ( std::forward<Args>(args)... ); \
}
#define MAKE_FUNCS( f ) \
FORWARD_FUNC( f, ::f, 0 ) \
FORWARD_FUNC( f, :: CONCAT( f, s ), 1 )
void add( double* a, double* b, double* c) {*a = *b+*c;}
void adds( float* a, float* b, float* c) {*a = *b+*c;}
namespace math {
MAKE_FUNCS(add)
}
int main() {
double a, b = 2, c = 3;
float af, bf = 3, cf = 5;
math::add( &a, &b, &c );
math::add( &af, &bf, &cf );
std::cout << a << "=" << b << "+" << c << "\n";
std::cout << af << "=" << bf << "+" << cf << "\n";
}
ICAjaW5jbHVkZSA8dXRpbGl0eT4KICAjaW5jbHVkZSA8dHlwZV90cmFpdHM+CiAgI2luY2x1ZGUgPGNzdGRkZWY+CiAgI2luY2x1ZGUgPGlvc3RyZWFtPgogIAogICNkZWZpbmUgQ09OQ0FUMiggYSwgYiApIGEjI2IKICAjZGVmaW5lIENPTkNBVCggYSwgYiApIENPTkNBVDIoYSxiKQogIAogIC8vIFNGSU5BRSBoZWxwZXIgYm9pbGVycGxhdGU6CiAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IGlzX3R5cGU6c3RkOjp0cnVlX3R5cGUge307CiAgdGVtcGxhdGU8c3RkOjpzaXplX3Qgbj4gc3RydWN0IHNlY3JldF9lbnVtIHsgZW51bSBjbGFzcyB0eXBlIHt9OyB9OwogIHRlbXBsYXRlPGJvb2wgYiwgc3RkOjpzaXplX3Qgbj4KICB1c2luZyBFbmFibGVJZiA9IHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPCBiLCB0eXBlbmFtZSBzZWNyZXRfZW51bTxuPjo6dHlwZSA+Ojp0eXBlOwoKICAvLyBNYWNybyB0aGF0IHRha2VzIGEgc3JjRiBuYW1lIGFuZCBhIGRzdEYgbmFtZSBhbmQgYW4gaW50ZWdlciBOIGFuZAogIC8vIGZvcndhcmRzIGFyZ3VtZW50cyBtYXRjaGluZyBkc3RGJ3Mgc2lnbmF0dXJlLiAgQW4gaW50ZWdlciBOIG11c3QgYmUKICAvLyBwYXNzZWQgaW4gd2l0aCBhIGRpc3RpbmN0IHZhbHVlIGZvciBlYWNoIHNyY0Ygb2YgdGhlIHNhbWUgbmFtZToKICAjZGVmaW5lIEZPUldBUkRfRlVOQyggc3JjRiwgZHN0RiwgTiApIFwKICB0ZW1wbGF0ZTwgdHlwZW5hbWUuLi4gQXJncywgXAogICAgRW5hYmxlSWY8IGlzX3R5cGU8IFwKICAgICAgZGVjbHR5cGUoIGRzdEYgKCBzdGQ6OmZvcndhcmQ8QXJncz4oc3RkOjpkZWNsdmFsPEFyZ3M+KCkpLi4uICkpIFwKICAgID46OnZhbHVlICwgTiA+Li4uID4gXAogIGF1dG8gc3JjRiAoIEFyZ3MmJi4uLiBhcmdzICkgXAogICAgLT4gZGVjbHR5cGUoZHN0RiAoIHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLiApKSBcCiAgeyBcCiAgICBkc3RGICggc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uICk7IFwKICB9CgogICNkZWZpbmUgTUFLRV9GVU5DUyggZiApIFwKICAgIEZPUldBUkRfRlVOQyggZiwgOjpmLCAwICkgXAogICAgRk9SV0FSRF9GVU5DKCBmLCA6OiBDT05DQVQoIGYsIHMgKSwgMSApCiAgICAKdm9pZCBhZGQoIGRvdWJsZSogYSwgZG91YmxlKiBiLCBkb3VibGUqIGMpIHsqYSA9ICpiKypjO30Kdm9pZCBhZGRzKCBmbG9hdCogYSwgZmxvYXQqIGIsIGZsb2F0KiBjKSB7KmEgPSAqYisqYzt9Cm5hbWVzcGFjZSBtYXRoIHsKICAgIE1BS0VfRlVOQ1MoYWRkKQp9CmludCBtYWluKCkgewogICAgZG91YmxlIGEsIGIgPSAyLCBjID0gMzsKICAgIGZsb2F0IGFmLCBiZiA9IDMsIGNmID0gNTsKICAgIG1hdGg6OmFkZCggJmEsICZiLCAmYyApOwogICAgbWF0aDo6YWRkKCAmYWYsICZiZiwgJmNmICk7CiAgICBzdGQ6OmNvdXQgPDwgYSA8PCAiPSIgPDwgYiA8PCAiKyIgPDwgYyA8PCAiXG4iOwogICAgc3RkOjpjb3V0IDw8IGFmIDw8ICI9IiA8PCBiZiA8PCAiKyIgPDwgY2YgPDwgIlxuIjsKfQ==