Created
September 22, 2016 14:53
-
-
Save bedder/2954136cee31fa856cc6f2ebdb7dfd34 to your computer and use it in GitHub Desktop.
constexpr Verion string generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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