]> git.tdb.fi Git - libs/core.git/commitdiff
Add utility functions to search and sort containers based on a member
authorMikko Rasa <tdb@tdb.fi>
Sat, 10 Apr 2021 18:07:14 +0000 (21:07 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 11 Apr 2021 12:56:46 +0000 (15:56 +0300)
source/core/algorithm.h

index 804db7b9d146905ae77cef973c8feae0233511fb..b79114e9d7a8de906b7be40e4c684e1a9758280a 100644 (file)
@@ -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