Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <functional>
- #include <type_traits>
- #include <utility>
- namespace details {
- template<typename Member, typename Class>
- using member_result_t = std::decay_t<std::invoke_result_t<Member Class::*, Class>>;
- template<typename Member, typename Class, typename Compare>
- class member_compare_t {
- private:
- using member_result_type = member_result_t<Member, Class>;
- static_assert(
- std::is_invocable_r_v<bool, Compare, member_result_type, member_result_type>,
- "Compare is not Predicate"
- );
- static constexpr bool is_nothrow_comparable = noexcept(
- std::declval<Compare>()(std::declval<member_result_type>(), std::declval<member_result_type>())
- );
- static constexpr bool is_nothrow_constructible = noexcept(
- std::is_nothrow_copy_constructible_v<Compare>
- );
- Member Class::* pointer;
- Compare compare;
- public:
- constexpr explicit
- member_compare_t(Member Class::* pointer, const Compare& compare) noexcept(is_nothrow_constructible)
- : pointer(pointer), compare(compare) {}
- constexpr bool operator()(const Class& left, const Class& right) const noexcept(is_nothrow_comparable) {
- if constexpr(std::is_member_object_pointer_v<Member Class::*>) {
- return compare(left.*pointer, right.*pointer);
- } else {
- return compare((left.*pointer)(), (right.*pointer)());
- }
- }
- };
- }
- template<typename Member, typename Class, typename Compare = std::less<details::member_result_t<Member, Class>>>
- constexpr decltype(auto) mem_compare(Member Class::* pointer, const Compare& compare = Compare()) {
- return details::member_compare_t<Member, Class, Compare>(pointer, compare);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement