#include <functional>
#include <algorithm>
#include <iostream>
#include <utility>
#include <string>
#include <vector>
template <class type>
using compare = std::function<bool(const type&, const type&)>;
template<
class classT
>
struct field_comparer {
using type = classT;
bool operator() (const type& a, const type& b) {
return functor (a, b);
}
field_comparer():functor(nullptr) {}
field_comparer(const compare<type>& f):functor(f) {}
field_comparer(const compare<type>&& f):functor(std::move(f)) {}
//field_comparer(const field_comparer<type>& f):functor(f.functor) {}
//field_comparer(const field_comparer<type>&& f):functor(std::move(f.functor)) {}
template<class T>
field_comparer<T> operator=(const field_comparer<T>& f) { functor.assign(f.functor); }
template<class T>
field_comparer<T> operator=(const field_comparer<T>&& f){ functor.assign(std::move(f.functor)); }
compare<type> functor;
};
template<
class classT,
class memberT
>
struct some:public field_comparer<classT> {
using type = classT;
using member_type = memberT;
using member_ptr = member_type type::*;
using compare = std::function<bool(const member_type&, const member_type&)>;
some(member_ptr mem, compare func)
:member(mem), comp(func){
this->field_comparer<type>::functor = std::bind(&some<type, member_type>::call, this,
std::placeholders::_1, std::placeholders::_2);
}
some(some<classT, memberT> const& l)
:field_comparer<type>(l.functor),
member(l.member), comp(l.comp){}
some(some<classT, memberT> const&& l)
:field_comparer<type>(l.functor),
member(std::move(l.member)), comp(std::move(l.comp)){}
bool call(const type& a, const type& b) {
return comp(a.*member, b.*member);
}
private:
member_ptr member;
compare comp;
};
template<
class classT,
class memberT,
class cmpT = std::less<memberT>
>
field_comparer<classT> make_comparer(
memberT classT::*member,
cmpT cmp = cmpT()
) {
return std::move(some<classT, memberT>(member, cmp));
}
struct test_idx {
char one;
int two;
std::string three;
test_idx* four;
};
int main() {
using namespace std;
vector<test_idx> a{
{'a', 100500, "hello", nullptr},
{'z', 42, "a hell", (test_idx*)(0xdead)}
};
auto print = [&a]() ->void
{
for(auto& i: a)
cout << '{'
<< i.one << ", "
<< i.two << ", "
<< i.three << ", "
<< i.four << "} ";
cout << endl;
};
vector<field_comparer<test_idx>>
one_idx{
make_comparer(&test_idx::one),
make_comparer(&test_idx::two),
make_comparer(&test_idx::three),
make_comparer(&test_idx::four)
};
print();
for(auto& cmp: one_idx) {
std::sort(a.begin(), a.end(), cmp);
print();
}
return 0;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+Cgp0ZW1wbGF0ZSA8Y2xhc3MgdHlwZT4KdXNpbmcgY29tcGFyZSAgICAgPSBzdGQ6OmZ1bmN0aW9uPGJvb2woY29uc3QgdHlwZSYsIGNvbnN0IHR5cGUmKT47CnRlbXBsYXRlPAogICAgICAgIGNsYXNzIGNsYXNzVAogICAgICAgID4Kc3RydWN0IGZpZWxkX2NvbXBhcmVyICB7CiAgICB1c2luZyB0eXBlICAgICAgICA9IGNsYXNzVDsKICAgIGJvb2wgb3BlcmF0b3IoKSAoY29uc3QgdHlwZSYgYSwgY29uc3QgdHlwZSYgYikgewogICAgICAgIHJldHVybiBmdW5jdG9yIChhLCBiKTsKICAgIH0KICAgIGZpZWxkX2NvbXBhcmVyKCk6ZnVuY3RvcihudWxscHRyKSB7fQogICAgZmllbGRfY29tcGFyZXIoY29uc3QgY29tcGFyZTx0eXBlPiYgZik6ZnVuY3RvcihmKSB7fQogICAgZmllbGRfY29tcGFyZXIoY29uc3QgY29tcGFyZTx0eXBlPiYmIGYpOmZ1bmN0b3Ioc3RkOjptb3ZlKGYpKSB7fQogICAgLy9maWVsZF9jb21wYXJlcihjb25zdCBmaWVsZF9jb21wYXJlcjx0eXBlPiYgZik6ZnVuY3RvcihmLmZ1bmN0b3IpIHt9CiAgICAvL2ZpZWxkX2NvbXBhcmVyKGNvbnN0IGZpZWxkX2NvbXBhcmVyPHR5cGU+JiYgZik6ZnVuY3RvcihzdGQ6Om1vdmUoZi5mdW5jdG9yKSkge30KCiAgICB0ZW1wbGF0ZTxjbGFzcyBUPgogICAgZmllbGRfY29tcGFyZXI8VD4gb3BlcmF0b3I9KGNvbnN0IGZpZWxkX2NvbXBhcmVyPFQ+JiBmKSB7IGZ1bmN0b3IuYXNzaWduKGYuZnVuY3Rvcik7IH0KICAgIHRlbXBsYXRlPGNsYXNzIFQ+CiAgICBmaWVsZF9jb21wYXJlcjxUPiBvcGVyYXRvcj0oY29uc3QgZmllbGRfY29tcGFyZXI8VD4mJiBmKXsgZnVuY3Rvci5hc3NpZ24oc3RkOjptb3ZlKGYuZnVuY3RvcikpOyB9CiAgICBjb21wYXJlPHR5cGU+IGZ1bmN0b3I7Cn07Cgp0ZW1wbGF0ZTwKICAgICAgICBjbGFzcyBjbGFzc1QsCiAgICAgICAgY2xhc3MgbWVtYmVyVAogICAgICAgID4Kc3RydWN0IHNvbWU6cHVibGljIGZpZWxkX2NvbXBhcmVyPGNsYXNzVD4gewogICAgdXNpbmcgdHlwZSAgICAgICAgPSBjbGFzc1Q7CiAgICB1c2luZyBtZW1iZXJfdHlwZSA9IG1lbWJlclQ7CiAgICB1c2luZyBtZW1iZXJfcHRyICA9IG1lbWJlcl90eXBlIHR5cGU6Oio7CiAgICB1c2luZyBjb21wYXJlICAgICA9IHN0ZDo6ZnVuY3Rpb248Ym9vbChjb25zdCBtZW1iZXJfdHlwZSYsIGNvbnN0IG1lbWJlcl90eXBlJik+OwogICAgc29tZShtZW1iZXJfcHRyIG1lbSwgY29tcGFyZSBmdW5jKQogICAgICAgIDptZW1iZXIobWVtKSwgY29tcChmdW5jKXsKICAgICAgICB0aGlzLT5maWVsZF9jb21wYXJlcjx0eXBlPjo6ZnVuY3RvciA9IHN0ZDo6YmluZCgmc29tZTx0eXBlLCBtZW1iZXJfdHlwZT46OmNhbGwsIHRoaXMsCiAgICAgICAgICAgICAgICAgIHN0ZDo6cGxhY2Vob2xkZXJzOjpfMSwgc3RkOjpwbGFjZWhvbGRlcnM6Ol8yKTsKICAgIH0KICAgIHNvbWUoc29tZTxjbGFzc1QsIG1lbWJlclQ+IGNvbnN0JiBsKQogICAgICAgIDpmaWVsZF9jb21wYXJlcjx0eXBlPihsLmZ1bmN0b3IpLAogICAgICAgICAgbWVtYmVyKGwubWVtYmVyKSwgY29tcChsLmNvbXApe30KICAgIHNvbWUoc29tZTxjbGFzc1QsIG1lbWJlclQ+IGNvbnN0JiYgbCkKICAgICAgICA6ZmllbGRfY29tcGFyZXI8dHlwZT4obC5mdW5jdG9yKSwKICAgICAgICAgIG1lbWJlcihzdGQ6Om1vdmUobC5tZW1iZXIpKSwgY29tcChzdGQ6Om1vdmUobC5jb21wKSl7fQogICAgYm9vbCBjYWxsKGNvbnN0IHR5cGUmIGEsIGNvbnN0IHR5cGUmIGIpIHsKICAgICAgICByZXR1cm4gY29tcChhLiptZW1iZXIsIGIuKm1lbWJlcik7CiAgICB9CnByaXZhdGU6CiAgICBtZW1iZXJfcHRyIG1lbWJlcjsKICAgIGNvbXBhcmUgICAgY29tcDsKfTsKdGVtcGxhdGU8CiAgICAgICAgY2xhc3MgY2xhc3NULAogICAgICAgIGNsYXNzIG1lbWJlclQsCiAgICAgICAgY2xhc3MgY21wVCA9IHN0ZDo6bGVzczxtZW1iZXJUPgogICAgICAgID4KZmllbGRfY29tcGFyZXI8Y2xhc3NUPiBtYWtlX2NvbXBhcmVyKAogICAgICAgIG1lbWJlclQgY2xhc3NUOjoqbWVtYmVyLAogICAgICAgIGNtcFQgY21wID0gY21wVCgpCiAgICAgICAgKSB7CiAgICByZXR1cm4gc3RkOjptb3ZlKHNvbWU8Y2xhc3NULCBtZW1iZXJUPihtZW1iZXIsIGNtcCkpOwp9CgpzdHJ1Y3QgdGVzdF9pZHggewogICAgY2hhciBvbmU7CiAgICBpbnQgdHdvOwogICAgc3RkOjpzdHJpbmcgdGhyZWU7CiAgICB0ZXN0X2lkeCogZm91cjsKfTsKaW50IG1haW4oKSB7CiAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOwogICAgdmVjdG9yPHRlc3RfaWR4PiBhewogICAgICAgIHsnYScsICAxMDA1MDAsICJoZWxsbyIsIG51bGxwdHJ9LAogICAgICAgIHsneicsIDQyLCAiYSBoZWxsIiwgKHRlc3RfaWR4KikoMHhkZWFkKX0KICAgIH07CgogICAgYXV0byBwcmludCA9IFsmYV0oKSAtPnZvaWQKICAgIHsKICAgICAgICAgICAgIGZvcihhdXRvJiBpOiBhKQogICAgICAgICAgICAgICAgIGNvdXQgPDwgJ3snCiAgICAgICAgICAgICAgICAgICAgICA8PCBpLm9uZSA8PCAiLCAiCiAgICAgICAgICAgICAgICAgICAgICA8PCBpLnR3byA8PCAiLCAiCiAgICAgICAgICAgICAgICAgICAgICA8PCBpLnRocmVlIDw8ICIsICIKICAgICAgICAgICAgICAgICAgICAgIDw8IGkuZm91ciA8PCAifSAiOwogICAgICAgICAgICAgY291dCA8PCBlbmRsOwogICAgfTsKICAgIHZlY3RvcjxmaWVsZF9jb21wYXJlcjx0ZXN0X2lkeD4+CiAgICAgICAgICAgIG9uZV9pZHh7CiAgICAgICAgICAgICAgICBtYWtlX2NvbXBhcmVyKCZ0ZXN0X2lkeDo6b25lKSwKICAgICAgICAgICAgICAgIG1ha2VfY29tcGFyZXIoJnRlc3RfaWR4Ojp0d28pLAogICAgICAgICAgICAgICAgbWFrZV9jb21wYXJlcigmdGVzdF9pZHg6OnRocmVlKSwKICAgICAgICAgICAgICAgIG1ha2VfY29tcGFyZXIoJnRlc3RfaWR4Ojpmb3VyKQogICAgfTsKICAgIHByaW50KCk7CiAgICBmb3IoYXV0byYgY21wOiBvbmVfaWR4KSB7CiAgICAgICAgc3RkOjpzb3J0KGEuYmVnaW4oKSwgYS5lbmQoKSwgY21wKTsKICAgICAgICBwcmludCgpOwogICAgfQogICAgcmV0dXJuIDA7Cn0K
{a, 100500, hello, 0} {z, 42, a hell, 0xdead}
{a, 100500, hello, 0} {z, 42, a hell, 0xdead}
{z, 42, a hell, 0xdead} {a, 100500, hello, 0}
{z, 42, a hell, 0xdead} {a, 100500, hello, 0}
{a, 100500, hello, 0} {z, 42, a hell, 0xdead}