#include <iostream>
#include <type_traits>

#include <boost/tti/has_member_function.hpp>
#include <boost/function_types/result_type.hpp>

struct Interface
{
    std::string interface()const
    {
        return "interface";
    }
};

struct my_interface
{
    std::string get_my_interface()const
    {
        return "get_my_interface";
    }
};

struct myInterfaceType
{
    std::string myInterface()const
    {
        return "myInterface";
    }
};

namespace foo
{
namespace detail
{
    BOOST_TTI_HAS_MEMBER_FUNCTION(interface)
    BOOST_TTI_HAS_MEMBER_FUNCTION(get_my_interface)
    BOOST_TTI_HAS_MEMBER_FUNCTION(myInterface)
}

template<typename Interface>
struct GenericInterface
{
    template<typename T = Interface>
    typename std::enable_if<  detail::has_member_function_interface<std::string (T::*)()const>::value,std::string >::type  query_interface()const
    {
        return i.interface();
    }
    template<typename T = Interface>
    typename std::enable_if<  detail::has_member_function_get_my_interface<std::string (T::*)()const >::value, std::string>::type query_interface()const
    {
        return i.get_my_interface();
    }
    template<typename T = Interface>
    typename std::enable_if< detail::has_member_function_myInterface<std::string (T::*)()const >::value, std::string >::type query_interface()const
    {
        return i.myInterface();
    }
    void print()
    {
        std::cout << query_interface() << "\n";
    }

private:
    Interface i;
};
}

int main(int argc, char *argv[])
{
    foo::GenericInterface<Interface> gInterface;
    foo::GenericInterface<my_interface> gmy_interface;
    foo::GenericInterface<myInterfaceType> gmyInterface;

    gInterface.print();
    gmy_interface.print();
    gmyInterface.print();

    std::cout << std::boolalpha <<foo::detail::has_member_function_get_my_interface<std::string (my_interface::*)()const>::value << std::endl;
    std::cout << std::boolalpha <<foo::detail::has_member_function_interface<myInterfaceType,std::string>::value << std::endl;
    std::cout << std::boolalpha << foo::detail::has_member_function_interface<std::string (Interface::*)()const>::value << std::endl;

    static_assert(foo::detail::has_member_function_interface<std::string (Interface::*)()const>::value,"fail");

    std::cout << "Hello World!" << std::endl;
    return 0;
}
