Skip to main content
edited tags; edited title
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

C++ variardic universal template for unknown types, used to handle multiple network protocols

Source Link

C++ variardic universal template for unknown types

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;
}