Home > Net >  C Get name of a template function argument
C Get name of a template function argument

Time:12-08

I want to replace all glXXXX calls to GL_CALL(N, ...) so that I can print function and arguments to trace the calls.

For example, replace glClearColor(0.0f, 0.0f, 0.0f, 1.0f) to GL_CALL(ClearColor, 0.0f, 0.0f, 0.0f, 1.0f) and in console I get [GL_CALL] glClearColor(0, 0, 0, 1)

#include <iostream>

template <class T>
void GL_TRACE_PRINT(T const &t) {
  std::cout << t << ",";
}

template<typename T, typename... Args>
void GL_TRACE_PRINT(T n, Args ... args) {
  GL_TRACE_PRINT(n);
  GL_TRACE_PRINT(args...);
}

#define GL_STR(s) #s

template <class F, typename ...Args>
auto GL_INVOKE(F f, Args && ...args) {
  std::cout << "[GL_CALL] " << GL_STR(f) << '(';
  GL_TRACE_PRINT(std::forward<Args>(args)...);
  std::cout << ")\n";
  return f(std::forward<Args>(args)...);
}

#define GL_CALL(N, ...)                                       \
  GL_INVOKE(gl##N, __VA_ARGS__);

But how to print the function name in GL_INVOKE? Thanks. Or is there better way to do so?

Currently the output is, the glXXX function names are all f.

[GL_CALL] f(0,0,0,1,)
[GL_CALL] f(0,0,0,1,)

CodePudding user response:

You can pass the string name of the function into GL_INVOKE, something like this:

template <class F, typename ...Args>
auto GL_INVOKE(const char* fname, F f, Args && ...args) {
  std::cout << "[GL_CALL] " << fname << '(';
  GL_TRACE_PRINT(std::forward<Args>(args)...);
  std::cout << ")\n";
  return f(std::forward<Args>(args)...);
}

#define GL_INVOKE_F(N, ...) \
  GL_INVOKE(#N, N, ## __VA_ARGS__) 

#define GL_CALL(N, ...)  \
  GL_INVOKE_F(gl##N , ## __VA_ARGS__)

Demo.

In addition, your GL_TRACE_PRINT can be implemented using C 17 fold expression, which will be much more concise.

template <class... Args>
void GL_TRACE_PRINT(Args const&... args) {
  ((std::cout << args << ","), ...);
}
  • Related