From 6bb431a4fdd6b6437c25890a89627d206a9e52ac Mon Sep 17 00:00:00 2001
From: Mikko Rasa <tdb@tdb.fi>
Date: Sat, 10 Apr 2021 21:07:14 +0300
Subject: [PATCH] Add utility functions to search and sort containers based on
 a member

---
 source/core/algorithm.h | 70 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/source/core/algorithm.h b/source/core/algorithm.h
index 804db7b..b79114e 100644
--- a/source/core/algorithm.h
+++ b/source/core/algorithm.h
@@ -101,6 +101,76 @@ inline void stable_sort(Container &cont, Predicate pred)
 	std::stable_sort(cont.begin(), cont.end(), pred);
 }
 
+template<typename C, typename T>
+struct MemberMatch
+{
+	const T &value;
+	T C::*mem_ptr;
+
+	MemberMatch(const T &v, T C::*p): value(v), mem_ptr(p) { }
+
+	bool operator()(const C &obj) { return obj.*mem_ptr==value; }
+};
+
+template<typename Container, typename T>
+inline typename Container::iterator find_member(Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return find_if(cont, MemberMatch<typename Container::value_type, T>(value, mp));
+}
+
+template<typename Container, typename T>
+inline typename Container::const_iterator find_member(const Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return find_if(cont, MemberMatch<typename Container::value_type, T>(value, mp));
+}
+
+template<typename C, typename T>
+struct MemberCompare
+{
+	T C::*mem_ptr;
+
+	MemberCompare(T C::*p): mem_ptr(p) { }
+
+	bool operator()(const C &obj, const T &v) { return obj.*mem_ptr<v; }
+	bool operator()(const C &obj1, const C &obj2) { return obj1.*mem_ptr<obj2.*mem_ptr; }
+};
+
+template<typename Container, typename T>
+inline typename Container::iterator lower_bound_member(Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return lower_bound(cont, value, MemberCompare<typename Container::value_type, T>(mp));
+}
+
+template<typename Container, typename T>
+inline typename Container::const_iterator lower_bound_member(const Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return lower_bound(cont, value, MemberCompare<typename Container::value_type, T>(mp));
+}
+
+template<typename Container, typename T>
+inline typename Container::iterator upper_bound_member(Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return upper_bound(cont, value, MemberCompare<typename Container::value_type, T>(mp));
+}
+
+template<typename Container, typename T>
+inline typename Container::const_iterator upper_bound_member(const Container &cont, const T &value, T Container::value_type::*mp)
+{
+	return upper_bound(cont, value, MemberCompare<typename Container::value_type, T>(mp));
+}
+
+template<typename Container, typename T>
+inline void sort_member(Container &cont, T Container::value_type::*mp)
+{
+	sort(cont, MemberCompare<typename Container::value_type, T>(mp));
+}
+
+template<typename Container, typename T>
+inline void stable_sort_member(Container &cont, T Container::value_type::*mp)
+{
+	stable_sort(cont, MemberCompare<typename Container::value_type, T>(mp));
+}
+
 } // namespace Msp
 
 #endif
-- 
2.45.2