#pragma once #include "comparator.h" namespace meta { namespace detail { template struct ptr_mem_info; template struct ptr_mem_info { using class_t = C; using type = T; }; template using ptr_mem_info_type = typename ptr_mem_info::type; template using ptr_mem_info_class = typename ptr_mem_info::class_t; struct poss { static constexpr int yes = 0, no = 1, maybe = -1; int val = maybe; inline poss operator|(const poss& rhs)const noexcept { int nval = rhs.val; nval = val == maybe ? nval : val; return poss{ nval }; } inline operator bool()const noexcept { return (val == yes); } }; template inline poss compare(const T& lhs, const T& rhs) noexcept { //using curr_t = typename Index_::type; int v = curr_t::get(lhs) < curr_t::get(rhs) ? poss::yes : poss::no; v = curr_t::get(lhs) != curr_t::get(rhs) ? v : poss::maybe; return poss{ v }; } template bool or_together(Args... args) noexcept { return static_cast((args | ...)); } } template struct PtrMem { using T = detail::ptr_mem_info_type ; using C = detail::ptr_mem_info_class; constexpr static Ptr pointer = ptr; static const T& get(const C& obj) noexcept { return (obj.*pointer); } }; template bool ordered_comparator::operator()(const T& lhs, const T& rhs)const noexcept { return detail::or_together(detail::compare(lhs, rhs)...); } }