Skip to content

Instantly share code, notes, and snippets.

@bedder
Created September 22, 2016 14:53
Show Gist options
  • Save bedder/2954136cee31fa856cc6f2ebdb7dfd34 to your computer and use it in GitHub Desktop.
Save bedder/2954136cee31fa856cc6f2ebdb7dfd34 to your computer and use it in GitHub Desktop.
constexpr Verion string generation
//
// Example of how to use (abuse) constexpr declarations to create program
// version string at compile-time. This is largely taken from the StackOverflow
// user Constructor (http://stackoverflow.com/a/23453841), but with one minor
// fix to null-terminate the string, one to make the code work with MSVC, and
// and comments added.
//
#include <type_traits>
namespace version {
// Use anonymous namespace to make these helpers only locally accessible
namespace {
template <char... S> struct String {
static constexpr char value[sizeof...(S)] = { S... };
};
template <char... S> constexpr char String<S...>::value[];
template <typename, typename> struct Concat;
template <char... S1, char... S2> struct Concat<String<S1...>, String<S2...>> {
using type = String<S1..., S2...>;
};
template <typename...> struct Concatenate;
template <typename S1, typename... S2> struct Concatenate<S1, S2...> {
using type = typename Concat<S1, typename Concatenate<S2...>::type>::type;
};
template <> struct Concatenate<> {
using type = String<>;
};
template <std::size_t N> struct NumberToString {
using type = typename Concat<
typename std::conditional<(N >= 10), typename NumberToString<N / 10>::type, String<>>::type,
String<'0' + N % 10>
>::type;
};
template <> struct NumberToString<0> {
using type = String<'0'>;
};
} // anonymous namespace
constexpr size_t major = 0;
constexpr size_t minor = 1;
constexpr size_t patch = 0;
namespace {
using VersionString = Concatenate<
NumberToString<major>::type, String<'.'>,
NumberToString<minor>::type, String<'.'>,
NumberToString<patch>::type, String<'\0'>
>::type;
} // anonymous namespace
constexpr const char* string = VersionString::value;
} // namespace version
//
// ////////
// // Usage
// ////////
//
// #include <iostream>
//
// int main(int argc, char**argv) {
// std::cout << 'v' << version::string << '\n';
// }
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment