Skip to content

Instantly share code, notes, and snippets.

@newnon
Last active August 29, 2015 14:05
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 newnon/34de828099825749e5e9 to your computer and use it in GitHub Desktop.
Save newnon/34de828099825749e5e9 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string>
template< class > struct FormatSupportedType;
#define SUPPORTED_TYPE(C, T) \
template<> struct FormatSupportedType< T > { \
constexpr static bool supports(char c) { return c == C; } }
SUPPORTED_TYPE('c', char);
SUPPORTED_TYPE('d', int);
SUPPORTED_TYPE('f', float);
template< std::size_t N >
constexpr bool checkFormatHelper(const char (&format)[N], std::size_t current)
{
return
current >= N ?
true
: format[current] != '%' ?
checkFormatHelper( format, current + 1 )
: format[current + 1] == '%' ?
checkFormatHelper( format, current + 2 )
:
false;
}
template< std::size_t N, class T, class... Ts >
constexpr bool checkFormatHelper(const char (&format)[N], std::size_t current, const T& arg, const Ts & ... args)
{
return
current >= N ?
false
: format[current] != '%' ?
checkFormatHelper( format, current + 1, arg, args... )
: (format[current] == '%' && format[current + 1] == '%') ?
checkFormatHelper( format, current + 2, arg, args... )
: FormatSupportedType< T >::supports(format[current + 1]) &&
checkFormatHelper( format, current + 2, args... );
}
template< std::size_t N, class... Ts >
constexpr bool checkFormat(const char (&format)[N], const Ts & ... args)
{
return checkFormatHelper( format, 0, args... );
}
#define safe_printf(FORMAT, ...) \
static_assert(checkFormat( FORMAT, __VA_ARGS__ ), "Format is incorrect"); \
printf(FORMAT, __VA_ARGS__)
int main(int argc, const char * argv[])
{
safe_printf("test %% %f %d\n", 1.0f, 1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment