]> git.tdb.fi Git - libs/core.git/blob - source/core/algorithm.h
Add an algorithm to check for existence of a value in a container
[libs/core.git] / source / core / algorithm.h
1 #ifndef MSP_CORE_ALGORITHM_H_
2 #define MSP_CORE_ALGORITHM_H_
3
4 #include <algorithm>
5 #include <functional>
6
7 namespace Msp {
8
9 template<typename Container, typename T>
10 inline typename Container::iterator find(Container &cont, const T &value)
11 {
12         return std::find(cont.begin(), cont.end(), value);
13 }
14
15 template<typename Container, typename T>
16 inline typename Container::const_iterator find(const Container &cont, const T &value)
17 {
18         return std::find(cont.begin(), cont.end(), value);
19 }
20
21 template<typename Container, typename Predicate>
22 inline typename Container::iterator find_if(Container &cont, Predicate pred)
23 {
24         return std::find_if(cont.begin(), cont.end(), pred);
25 }
26
27 template<typename Container, typename Predicate>
28 inline typename Container::const_iterator find_if(const Container &cont, Predicate pred)
29 {
30         return std::find_if(cont.begin(), cont.end(), pred);
31 }
32
33 template<typename T>
34 struct ValueMatch
35 {
36         const T &value;
37
38         bool operator()(const T &v) { return v==value; }
39 };
40
41 template<typename Container, typename T>
42 inline bool any_equals(Container &cont, const T &value)
43 {
44         return std::any_of(cont.begin(), cont.end(), ValueMatch<T>{value});
45 }
46
47 template<typename Container, typename T>
48 inline typename Container::iterator lower_bound(Container &cont, const T &value)
49 {
50         return std::lower_bound(cont.begin(), cont.end(), value);
51 }
52
53 template<typename Container, typename T>
54 inline typename Container::const_iterator lower_bound(const Container &cont, const T &value)
55 {
56         return std::lower_bound(cont.begin(), cont.end(), value);
57 }
58
59 template<typename Container, typename T, typename Predicate>
60 inline typename Container::iterator lower_bound(Container &cont, const T &value, Predicate pred)
61 {
62         return std::lower_bound(cont.begin(), cont.end(), value, pred);
63 }
64
65 template<typename Container, typename T, typename Predicate>
66 inline typename Container::const_iterator lower_bound(const Container &cont, const T &value, Predicate pred)
67 {
68         return std::lower_bound(cont.begin(), cont.end(), value, pred);
69 }
70
71 template<typename Container, typename T>
72 inline typename Container::iterator upper_bound(Container &cont, const T &value)
73 {
74         return std::upper_bound(cont.begin(), cont.end(), value);
75 }
76
77 template<typename Container, typename T>
78 inline typename Container::const_iterator upper_bound(const Container &cont, const T &value)
79 {
80         return std::upper_bound(cont.begin(), cont.end(), value);
81 }
82
83 template<typename Container, typename T, typename Predicate>
84 inline typename Container::iterator upper_bound(Container &cont, const T &value, Predicate pred)
85 {
86         return std::upper_bound(cont.begin(), cont.end(), value, pred);
87 }
88
89 template<typename Container, typename T, typename Predicate>
90 inline typename Container::const_iterator upper_bound(const Container &cont, const T &value, Predicate pred)
91 {
92         return std::upper_bound(cont.begin(), cont.end(), value, pred);
93 }
94
95 template<typename Container>
96 inline void sort(Container &cont)
97 {
98         std::sort(cont.begin(), cont.end());
99 }
100
101 template<typename Container, typename Predicate>
102 inline void sort(Container &cont, Predicate pred)
103 {
104         std::sort(cont.begin(), cont.end(), pred);
105 }
106
107 template<typename Container>
108 inline void stable_sort(Container &cont)
109 {
110         std::stable_sort(cont.begin(), cont.end());
111 }
112
113 template<typename Container, typename Predicate>
114 inline void stable_sort(Container &cont, Predicate pred)
115 {
116         std::stable_sort(cont.begin(), cont.end(), pred);
117 }
118
119 template<typename C, typename T>
120 struct MemberMatch
121 {
122         const T &value;
123         T C::*mem_ptr;
124
125         bool operator()(const C &obj) { return obj.*mem_ptr==value; }
126 };
127
128 template<typename Container, typename T>
129 inline typename Container::iterator find_member(Container &cont, const T &value, T Container::value_type::*mp)
130 {
131         return find_if(cont, MemberMatch<typename Container::value_type, T>{ value, mp });
132 }
133
134 template<typename Container, typename T>
135 inline typename Container::const_iterator find_member(const Container &cont, const T &value, T Container::value_type::*mp)
136 {
137         return find_if(cont, MemberMatch<typename Container::value_type, T>{ value, mp });
138 }
139
140 template<typename C, typename T, typename P=std::less<T>>
141 struct MemberCompare
142 {
143         T C::*mem_ptr;
144         P pred;
145
146         bool operator()(const C &obj, const T &v) { return pred(obj.*mem_ptr, v); }
147         bool operator()(const T &v, const C &obj) { return pred(v, obj.*mem_ptr); }
148         bool operator()(const C &obj1, const C &obj2) { return pred(obj1.*mem_ptr, obj2.*mem_ptr); }
149 };
150
151 template<typename Container, typename T>
152 inline typename Container::iterator lower_bound_member(Container &cont, const T &value, T Container::value_type::*mp)
153 {
154         return lower_bound(cont, value, MemberCompare<typename Container::value_type, T>{ mp });
155 }
156
157 template<typename Container, typename T>
158 inline typename Container::const_iterator lower_bound_member(const Container &cont, const T &value, T Container::value_type::*mp)
159 {
160         return lower_bound(cont, value, MemberCompare<typename Container::value_type, T>{ mp });
161 }
162
163 template<typename Container, typename T>
164 inline typename Container::iterator upper_bound_member(Container &cont, const T &value, T Container::value_type::*mp)
165 {
166         return upper_bound(cont, value, MemberCompare<typename Container::value_type, T>{ mp });
167 }
168
169 template<typename Container, typename T>
170 inline typename Container::const_iterator upper_bound_member(const Container &cont, const T &value, T Container::value_type::*mp)
171 {
172         return upper_bound(cont, value, MemberCompare<typename Container::value_type, T>{ mp });
173 }
174
175 template<typename Container, typename T>
176 inline void sort_member(Container &cont, T Container::value_type::*mp)
177 {
178         sort(cont, MemberCompare<typename Container::value_type, T>{ mp });
179 }
180
181 template<typename Container, typename T>
182 inline void stable_sort_member(Container &cont, T Container::value_type::*mp)
183 {
184         stable_sort(cont, MemberCompare<typename Container::value_type, T>{ mp });
185 }
186
187 template<typename Container, typename Predicate>
188 inline void transform(Container &cont, Predicate pred)
189 {
190         transform(cont.begin(), cont.end(), cont.begin(), pred);
191 }
192
193 } // namespace Msp
194
195 #endif