#include <iostream>
#include <algorithm>
using namespace std;
template< typename Base, typename... T >
struct Comparer
{
template< T Base::* ... ptr >
struct Members
{
static bool compare( Base const& lhs, Base const& rhs )
{
bool arr[]{ ( lhs.*ptr == rhs.*ptr )... };
return all_of( begin(arr), end(arr), [](bool b){return b;} );
}
};
};
template< typename T > struct get_type;
template< typename Type, typename Class >
struct get_type<Type Class::*>
{
using type = Type;
using class_type = Class;
};
template<typename...> struct type_list;
template<typename ... Args>
type_list<Args...> get_types( Args... );
template<typename> struct create_comparer;
template< typename First, typename ... Tail >
struct create_comparer<type_list<First, Tail...>> :
Comparer<typename get_type<First>::class_type,
typename get_type<First>::type,
typename get_type<Tail>::type...> {};
#define CREATE_COMPARER(...) create_comparer<decltype(get_types(__VA_ARGS__))>::Members<__VA_ARGS__>
struct A
{
int a;
char b;
};
int main()
{
A a{4, '7'}, b=a, c{5, '7'};
cout << CREATE_COMPARER(&A::a, &A::b)::compare(a, b);
cout << CREATE_COMPARER(&A::a, &A::b)::compare(a, c);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8IHR5cGVuYW1lIEJhc2UsIHR5cGVuYW1lLi4uIFQgPgpzdHJ1Y3QgQ29tcGFyZXIKewoJdGVtcGxhdGU8IFQgQmFzZTo6KiAuLi4gcHRyID4KCXN0cnVjdCBNZW1iZXJzIAoJewoJCXN0YXRpYyBib29sIGNvbXBhcmUoIEJhc2UgY29uc3QmIGxocywgQmFzZSBjb25zdCYgcmhzICkKCQl7CgkJCWJvb2wgYXJyW117ICggbGhzLipwdHIgPT0gcmhzLipwdHIgKS4uLiB9OwoJCQlyZXR1cm4gYWxsX29mKCBiZWdpbihhcnIpLCBlbmQoYXJyKSwgW10oYm9vbCBiKXtyZXR1cm4gYjt9ICk7CgkJfQoJfTsKfTsKCnRlbXBsYXRlPCB0eXBlbmFtZSBUID4gc3RydWN0IGdldF90eXBlOwp0ZW1wbGF0ZTwgdHlwZW5hbWUgVHlwZSwgdHlwZW5hbWUgQ2xhc3MgPiAKc3RydWN0IGdldF90eXBlPFR5cGUgQ2xhc3M6Oio+CnsKCXVzaW5nIHR5cGUgPSBUeXBlOwoJdXNpbmcgY2xhc3NfdHlwZSA9IENsYXNzOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUuLi4+IHN0cnVjdCB0eXBlX2xpc3Q7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSAuLi4gQXJncz4KdHlwZV9saXN0PEFyZ3MuLi4+IGdldF90eXBlcyggQXJncy4uLiApOwoKdGVtcGxhdGU8dHlwZW5hbWU+IHN0cnVjdCBjcmVhdGVfY29tcGFyZXI7CnRlbXBsYXRlPCB0eXBlbmFtZSBGaXJzdCwgdHlwZW5hbWUgLi4uIFRhaWwgPgpzdHJ1Y3QgY3JlYXRlX2NvbXBhcmVyPHR5cGVfbGlzdDxGaXJzdCwgVGFpbC4uLj4+IDogIAoJQ29tcGFyZXI8dHlwZW5hbWUgZ2V0X3R5cGU8Rmlyc3Q+OjpjbGFzc190eXBlLCAKICAgICAgICAgICAgIHR5cGVuYW1lIGdldF90eXBlPEZpcnN0Pjo6dHlwZSwKICAgICAgICAgICAgIHR5cGVuYW1lIGdldF90eXBlPFRhaWw+Ojp0eXBlLi4uPiB7fTsKCiNkZWZpbmUgQ1JFQVRFX0NPTVBBUkVSKC4uLikgY3JlYXRlX2NvbXBhcmVyPGRlY2x0eXBlKGdldF90eXBlcyhfX1ZBX0FSR1NfXykpPjo6TWVtYmVyczxfX1ZBX0FSR1NfXz4KCnN0cnVjdCBBCnsKCWludCBhOwoJY2hhciBiOwp9OwoKaW50IG1haW4oKSAKewoJQSBhezQsICc3J30sIGI9YSwgY3s1LCAnNyd9OwoJY291dCA8PCBDUkVBVEVfQ09NUEFSRVIoJkE6OmEsICZBOjpiKTo6Y29tcGFyZShhLCBiKTsKCWNvdXQgPDwgQ1JFQVRFX0NPTVBBUkVSKCZBOjphLCAmQTo6Yik6OmNvbXBhcmUoYSwgYyk7Cn0=