#include <iostream>
#include <string>
using namespace std;
template <typename StrType, typename EnumType>
class ExampleClass
{};
template <typename StrType, typename EnumType>
void fooSingleCase()
{
std::cout << "In: " << __PRETTY_FUNCTION__ << "\n";
ExampleClass<StrType, EnumType> instance;
// ...
}
template <typename StrType>
struct StrTraits
{
static const std::string pattern;
};
enum class ENUM1
{
VAL1,
VAL2,
VAL3,
VAL4
};
template <typename EnumType>
struct ENUM1Traits
{
static const ENUM1 pattern;
};
class VAL1TYPE {};
class VAL2TYPE {};
class VAL3TYPE {};
class STR1TYPE {};
class STR2TYPE {};
template <>
const std::string StrTraits<STR1TYPE>::pattern = "str1";
template <>
const std::string StrTraits<STR2TYPE>::pattern = "str2";
template <>
const ENUM1 ENUM1Traits<VAL1TYPE>::pattern = ENUM1::VAL1;
template <>
const ENUM1 ENUM1Traits<VAL2TYPE>::pattern = ENUM1::VAL2;
template <>
const ENUM1 ENUM1Traits<VAL3TYPE>::pattern = ENUM1::VAL3;
template <typename EnumType>
void fooFixedEnumCase(std::string strVal)
{
std::cout << strVal << " not found!\n";
}
template <typename EnumType, typename Str1Type, typename ...StrType>
void fooFixedEnumCase(std::string strVal)
{
if (StrTraits<Str1Type>::pattern == strVal)
fooSingleCase<EnumType, Str1Type>();
else
fooFixedEnumCase<EnumType, StrType...>(strVal);
}
template <typename ...EnumType>
struct Enum1Switch;
template <typename EnumType1, typename ...EnumType>
struct Enum1Switch<EnumType1, EnumType...>
{
template <typename ...StrType>
static void strSwitch(std::string str, ENUM1 enumVal)
{
if (ENUM1Traits<EnumType1>::pattern == enumVal)
fooFixedEnumCase<EnumType1, StrType...>(str);
else
Enum1Switch<EnumType...>::template strSwitch<StrType...>(str, enumVal);
}
};
template <>
struct Enum1Switch<>
{
template <typename ...StrType>
static void strSwitch(std::string str, ENUM1 enumVal)
{
std::cout << static_cast<int>(enumVal) << " not found!\n";
}
};
void foo(std::string str, ENUM1 enumVal) {
Enum1Switch<VAL1TYPE, VAL2TYPE, VAL3TYPE>
::strSwitch<STR1TYPE, STR2TYPE>(str, enumVal);
}
int main() {
foo("str2", ENUM1::VAL3);
foo("str1", ENUM1::VAL1);
foo("str4", ENUM1::VAL1);
foo("str2", ENUM1::VAL4);
}