fork download
  1. #include <utility>
  2. #include <type_traits>
  3. #include <cstddef>
  4. #include <iostream>
  5.  
  6. #define CONCAT2( a, b ) a##b
  7. #define CONCAT( a, b ) CONCAT2(a,b)
  8.  
  9. // SFINAE helper boilerplate:
  10. template<typename T> struct is_type:std::true_type {};
  11. template<std::size_t n> struct secret_enum { enum class type {}; };
  12. template<bool b, std::size_t n>
  13. using EnableIf = typename std::enable_if< b, typename secret_enum<n>::type >::type;
  14.  
  15. // Macro that takes a srcF name and a dstF name and an integer N and
  16. // forwards arguments matching dstF's signature. An integer N must be
  17. // passed in with a distinct value for each srcF of the same name:
  18. #define FORWARD_FUNC( srcF, dstF, N ) \
  19.   template< typename... Args, \
  20.   EnableIf< is_type< \
  21.   decltype( dstF ( std::forward<Args>(std::declval<Args>())... )) \
  22.   >::value , N >... > \
  23.   auto srcF ( Args&&... args ) \
  24.   -> decltype(dstF ( std::forward<Args>(args)... )) \
  25.   { \
  26.   dstF ( std::forward<Args>(args)... ); \
  27.   }
  28.  
  29. #define MAKE_FUNCS( f ) \
  30.   FORWARD_FUNC( f, ::f, 0 ) \
  31.   FORWARD_FUNC( f, :: CONCAT( f, s ), 1 )
  32.  
  33. void add( double* a, double* b, double* c) {*a = *b+*c;}
  34. void adds( float* a, float* b, float* c) {*a = *b+*c;}
  35. namespace math {
  36. MAKE_FUNCS(add)
  37. }
  38. int main() {
  39. double a, b = 2, c = 3;
  40. float af, bf = 3, cf = 5;
  41. math::add( &a, &b, &c );
  42. math::add( &af, &bf, &cf );
  43. std::cout << a << "=" << b << "+" << c << "\n";
  44. std::cout << af << "=" << bf << "+" << cf << "\n";
  45. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
5=2+3
8=3+5