I am creating a template function with variardic arguments, to handle a specific classes that have some interface, method, member or whatever is specialized in a specialization area. However I came to a solution to handle even types that are not supported, thus avoid exceptions, polymorphism, virtual functions, RTTI, etc. I'd like to hear a suggestions and also a peak to the implementation. The example below shows a simple parsing of known network protocols (pseudo logic), that can handle all relevant types, if not specialized classes are passed, they shall be omitted as it happens.
#include <iostream>
#include <cstring>
template<typename T>
struct is_validator
{
static const bool value = false;
};
struct Null {
Null(const std::string& res[[maybe_unused]]) {}
bool valid() const {
return false;
}
};
struct RtpRFC
{
std::string m_res;
RtpRFC(const std::string& res) : m_res{res}{}
bool valid() const {
if (!strcmp(m_res.c_str(), "rtp"))
return true;
return false;
}
};
struct RtspRFC
{
public:
std::string m_res;
RtspRFC(const std::string& res) : m_res{res}{}
bool valid() const {
if (!strcmp(m_res.c_str(),"rtsp"))
return true;
return false;
}
};
struct StunRFC
{
std::string m_res;
StunRFC(const std::string& res) : m_res{res}{}
bool valid() const {
if (!strcmp("stun", m_res.c_str()))
return true;
return false;
}
};
struct NonValid
{
};
template<>
struct is_validator<Null>
{
static const bool value = true;
};
template<>
struct is_validator<RtpRFC>
{
static const bool value = true;
};
template<>
struct is_validator<StunRFC>
{
static const bool value = true;
};
template<>
struct is_validator<RtspRFC>
{
static const bool value = true;
};
/*terminator*/
bool VParse(...) {
return false;
}
template <class T,
//typename std::enable_if<is_validator<T>::value>::type,
typename...ARgs>
bool VParse(T type, ARgs&&... FArgs)
{
if constexpr (is_validator<T>::value) {
if (type.valid()) {
return true;
}
else {
return VParse(std::forward<ARgs>(FArgs)...);
}
}
return VParse(std::forward<ARgs>(FArgs)...);
}
int main(void)
{
std::string ret{};
const std::string someNetworkData[10] = {
"stun", "rtp", "stun", "stun", "rtsp", "rtp", "http", "http2", "udp"
};
for(int i=0; i < 10; i++) {
auto res = someNetworkData[i];
bool valid = VParse(
10,
"test",
NonValid{},
RtpRFC{res} ,
RtspRFC{res},
StunRFC{res},
Null{res}, //dummies
Null{res},
Null{res}
);
if (valid) {
ret += res;
ret += "|";
}
}
std::cout << ret;
return 0;
}