Skip to content

Instantly share code, notes, and snippets.

@mbolt35
Created September 3, 2013 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbolt35/4e60da5aaec94dcd39ca to your computer and use it in GitHub Desktop.
Save mbolt35/4e60da5aaec94dcd39ca to your computer and use it in GitHub Desktop.
Example to demonstrate using a C99 preprocessor macro to execute a variadict function without having to explicitly pass the argument list size.
// arg_helper.h
#ifndef ARG_HELPER_H
#define ARG_HELPER_H
#include <stdarg.h>
/**
* Using MSVC?
*/
#define IS_MSVC _MSC_VER && !__INTEL_COMPILER
/**
* Define the macros to determine variadic argument lengths up to 20 arguments. The MSVC
* preprocessor handles variadic arguments a bit differently than the GNU preprocessor,
* so we account for that here.
*/
#if IS_MSVC
#define MSVC_HACK(FUNC, ARGS) FUNC ARGS
#define APPLY(FUNC, ...) MSVC_HACK(FUNC, (__VA_ARGS__))
#define VA_LENGTH(...) APPLY(VA_LENGTH_, 0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#else
#define VA_LENGTH(...) VA_LENGTH_(0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#endif
/**
* Strip the processed arguments to a length variable.
*/
#define VA_LENGTH_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#endif // ARG_HELPER_H
// ----
// mymath.h
#ifndef MY_MATH_H
#define MY_MATH_H
#include "arg_helper.h"
/**
* Use the VA_LENGTH macro to determine the length of the variadict args to
* pass in as the first parameter, and forward along the arguments after that.
*/
#define ExecVF(Func, ...) Func(VA_LENGTH(__VA_ARGS__), __VA_ARGS__)
namespace my {
namespace math {
template<class T>
extern T Min(int count, T value, ...) {
va_list args;
va_start(args, value);
T min = value;
for (int i = 0; i < count-1; ++i) {
T next = va_arg(args, T);
min = min < next ? min : next;
}
va_end(args);
return min;
}
};
};
#endif // MY_MATH_H
// ----
// main.cpp
#include <cstdio>
#include "mymath.h"
int main() {
int min = ExecVF(my::math::Min<int>, 5, 2, 20, -3, 66, 0, 34);
printf("min: %d\n", min);
return 0;
}
// Output
// min: -3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment