Skip to content

Instantly share code, notes, and snippets.

@3Hren
Created September 7, 2013 20:43
Show Gist options
  • Save 3Hren/6479124 to your computer and use it in GitHub Desktop.
Save 3Hren/6479124 to your computer and use it in GitHub Desktop.
Compile-time simple format string check.
template<typename T>
struct FormatTraits;
template<std::size_t N>
struct FormatTraits<char[N]> {
constexpr static bool supports(char c) {
return c == 's';
}
};
#define DECLARE_SUPPORTED_FORMAT(__type, __char) \
template<> \
struct FormatTraits<__type> { \
constexpr static bool supports(char c) { \
return c == __char; \
} \
}
DECLARE_SUPPORTED_FORMAT(char, 'c');
DECLARE_SUPPORTED_FORMAT(unsigned int, 'o');
DECLARE_SUPPORTED_FORMAT(int, 'd');
DECLARE_SUPPORTED_FORMAT(double, 'f');
DECLARE_SUPPORTED_FORMAT(std::string, 's');
template<std::size_t N, class T>
constexpr bool check_format_helper(const T(&format)[N], std::size_t current) {
return current == N ? true : format[current] != '%' ?
check_format_helper(format, current + 1) : format[current + 1] == '%' ?
check_format_helper(format, current + 2) : false;
}
template<std::size_t N, class T, class Arg, class... Args>
constexpr bool check_format_helper(const T(&format)[N], std::size_t current, Arg const& arg, Args const& ...args) {
return current == N ?
false :
format[current] != '%' ?
check_format_helper(format, current + 1, arg, args...) :
format[current + 1] == '%' && format[current + 2] == '%' ?
check_format_helper(format, current + 2, arg, args...) :
FormatTraits<Arg>::supports(format[current + 1]) && check_format_helper(format, current + 2, args...);
}
template<class T, std::size_t N, class... Args>
constexpr bool check_format(const T(&format)[N], Args const& ... args) {
return check_format_helper(format, 0, args...);
}
// usage: static_assert(check_format("this is %s and %d", "blah-blah", 10), "ha-ha, you suck!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment