I am checking the validity of a string whose valid values are known at compile time. I have the following simplified code snippet:
#include <cassert>
#include <string>
template <char const* const _Rhs, char const* const _Rhs2,
char const* const _Rhs3>
bool IsValid(std::string const& _Lhs) {
return _Rhs == _Lhs or _Rhs2 == _Lhs or _Rhs3 == _Lhs;
}
template <char const* const _Rhs, char const* const _Rhs2>
bool IsValid(std::string const& _Lhs) {
return _Rhs == _Lhs or _Rhs2 == _Lhs;
}
template <char const* const _Rhs>
bool IsValid(std::string const& _Lhs) {
return _Rhs == _Lhs;
}
static const char record[] = "record";
static const char replay[] = "replay";
static const char idle[] = "idle";
int main() {
assert((IsValid<record>("record")));
assert((IsValid<record, replay>("replay")));
assert((IsValid<record, replay, idle>("idle")));
assert((not IsValid<record, replay, idle>("unknown")));
}
Is there a way I could generalize the IsValid function to take an arbitrary number of template parameters?
Something like:
template <char const* const _Rhs, typename... Args>
bool IsValid(std::string const& _Lhs) {
return _Rhs == _Lhs or IsValid<Args...>(_Lhs);
}
template<char const* str>
struct str_t {
static const char* string = str;
};
bool IsValidImpl(std::string const& str) {
return false;
}
template<class String, class...Strings>
bool IsValidImpl(std::string const& str, String, Strings... strings) {
return (str == String::string) || IsValidImpl( str, strings... );
}
template<class...Strings>
bool IsValid(std::string const& str) {
return IsValidImpl(str, Strings{}...);
}
assert((IsValid<str_t<record> >("record")));
assert((IsValid<str_t<record>, str_t<replay> >("replay")));
assert((IsValid<str_t<record>, str_t<replay>, str_t<idle> >("idle")));
assert((not IsValid<str_t<record>, str_t<replay>, str_t<idle> >("unknown")));
there are much cleaner ways to do this in c++14 c++17 and c++20, but this is a c++11 solution as required.