namespace std { class type_info; }
typedef char yes_type;
struct no_type { char padding[8]; };

#include <iostream>
#include <type_traits>
 
template< typename _1 >
struct EqualityComparable
{
    struct requires0 {
        template< typename T >
        static yes_type check (
            T a, T b,
            char (*) [sizeof(decltype( bool{a == b} ))]
        );
        template< typename T >
        static no_type check ( ... );
 
        template< typename T >
        struct sizeof_check {
            T a; T b;
            static size_t const value = sizeof check<_1>(a , b , 0);
        };
 
        static bool const value = sizeof(yes_type) ==
                sizeof_check< _1 >::value;
    };
    static bool const value = requires0::value;
};

template<typename T> void print_type()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

template<typename T>
struct remove_refs
{
    typedef T type;
};


template<typename T>
struct remove_refs<T&&>
{
    typedef T type;
};


template<typename T>
struct remove_refs<T&>
{
    typedef T type;
};
 
int main ( void )
{
    std::cout << EqualityComparable<int>::value << std::endl; // 1 -- ok
    std::cout << EqualityComparable<std::common_type<int>::type>::value
            << std::endl; // 1 -- ok
    std::cout << EqualityComparable<std::common_type<int, int>::type>::value
            << std::endl; // 0 -- why??
    std::cout << EqualityComparable<remove_refs<std::common_type<int, int>::type>::type>::value
            << std::endl; // 1 -- OK on Clang too
    print_type<std::common_type<int, int>::type>(); // GCC - int, Clang - int&&
    print_type<remove_refs<std::common_type<int, int>::type>::type>();  // GCC - int, Clang - int
    return 0;
}