3
3
#include < unordered_map>
4
4
#include < iterator>
5
5
#include < algorithm>
6
+ #include < functional>
6
7
7
8
using std::vector;
8
9
using std::unordered_map;
9
10
using std::iterator_traits;
10
- using std::back_inserter;
11
- using std::set_difference;
11
+ using std::hash;
12
+ using std::for_each;
13
+ using std::any_of;
14
+ using std::all_of;
15
+ using std::find;
16
+ using std::find_if;
17
+ using std::lower_bound;
12
18
using std::count;
13
19
using std::count_if;
14
- using std::find;
20
+ using std::transform;
21
+ using std::set_difference;
22
+ using std::back_inserter;
23
+
24
+
25
+
26
+
27
+ // ANY-OF
28
+ // ------
29
+
30
+ template <class I , class F >
31
+ auto anyOf (I ib, I ie, F fn) {
32
+ return any_of (ib, ie, fn);
33
+ }
34
+
35
+ template <class J , class F >
36
+ auto anyOf (const J& x, F fn) {
37
+ return any_of (x.begin (), x.end (), fn);
38
+ }
39
+
40
+
41
+
42
+
43
+ // ALL-OF
44
+ // ------
45
+
46
+ template <class I , class F >
47
+ auto allOf (I ib, I ie, F fn) {
48
+ return all_of (ib, ie, fn);
49
+ }
50
+
51
+ template <class J , class F >
52
+ auto allOf (const J& x, F fn) {
53
+ return all_of (x.begin (), x.end (), fn);
54
+ }
15
55
16
56
17
57
@@ -26,15 +66,86 @@ auto find(const J& x, const T& v) {
26
66
27
67
template <class J , class T >
28
68
int findIndex (const J& x, const T& v) {
29
- auto i = find (x.begin (), x.end (), v);
30
- return i==x.end ()? -1 : i-x.begin ();
69
+ return find (x.begin (), x.end (), v) - x.begin ();
31
70
}
32
71
72
+ template <class J , class T >
73
+ int findEqIndex (const J& x, const T& v) {
74
+ auto it = find (x.begin (), x.end (), v);
75
+ return it==x.end ()? -1 : it-x.begin ();
76
+ }
33
77
34
78
79
+ template <class I , class F >
80
+ auto findIf (I ib, I ie, F fn) {
81
+ return find_if (ib, ie, fn);
82
+ }
35
83
36
- // COUNT-*
37
- // -------
84
+ template <class J , class F >
85
+ auto findIf (const J& x, F fn) {
86
+ return find_if (x.begin (), x.end (), fn);
87
+ }
88
+
89
+ template <class J , class F >
90
+ int findIfIndex (const J& x, F fn) {
91
+ return find_if (x.begin (), x.end (), fn) - x.begin ();
92
+ }
93
+
94
+ template <class J , class F >
95
+ int findIfEqIndex (const J& x, F fn) {
96
+ auto it = find_if (x.begin (), x.end (), fn);
97
+ return it==x.end ()? -1 : it-x.begin ();
98
+ }
99
+
100
+
101
+
102
+
103
+ // LOWER-BOUND
104
+ // -----------
105
+
106
+ template <class J , class T >
107
+ auto lowerBound (const J& x, const T& v) {
108
+ return lower_bound (x.begin (), x.end (), v);
109
+ }
110
+
111
+ template <class J , class T , class F >
112
+ auto lowerBound (const J& x, const T& v, F fl) {
113
+ return lower_bound (x.begin (), x.end (), v, fl);
114
+ }
115
+
116
+ template <class J , class T >
117
+ int lowerBoundIndex (const J& x, const T& v) {
118
+ return lower_bound (x.begin (), x.end (), v) - x.begin ();
119
+ }
120
+
121
+ template <class J , class T , class F >
122
+ int lowerBoundIndex (const J& x, const T& v, F fl) {
123
+ return lower_bound (x.begin (), x.end (), v, fl) - x.begin ();
124
+ }
125
+
126
+ template <class J , class T >
127
+ int lowerBoundEqIndex (const J& x, const T& v) {
128
+ auto it = lower_bound (x.begin (), x.end (), v);
129
+ return it==x.end () || *it!=v? -1 : it-x.begin ();
130
+ }
131
+
132
+ template <class J , class T , class F >
133
+ int lowerBoundEqIndex (const J& x, const T& v, F fl) {
134
+ auto it = lower_bound (x.begin (), x.end (), v, fl);
135
+ return it==x.end () || *it!=v? -1 : it-x.begin ();
136
+ }
137
+
138
+ template <class J , class T , class F , class G >
139
+ int lowerBoundEqIndex (const J& x, const T& v, F fl, G fe) {
140
+ auto it = lower_bound (x.begin (), x.end (), v, fl);
141
+ return it==x.end () || !fe (*it, v)? -1 : it-x.begin ();
142
+ }
143
+
144
+
145
+
146
+
147
+ // COUNT
148
+ // -----
38
149
39
150
template <class J , class T >
40
151
int count (const J& x, const T& v) {
@@ -55,6 +166,25 @@ int countIf(const J& x, F fn) {
55
166
56
167
57
168
169
+ // COUNT-ALL
170
+ // ---------
171
+
172
+ template <class I >
173
+ auto countAll (I ib, I ie) {
174
+ using T = typename I::value_type;
175
+ unordered_map<T, int > a;
176
+ for_each (ib, ie, [&](const auto & v) { a[v]++; });
177
+ return a;
178
+ }
179
+
180
+ template <class J >
181
+ auto countAll (const J& x) {
182
+ return countAll (x.begin (), x.end ());
183
+ }
184
+
185
+
186
+
187
+
58
188
// INDICES
59
189
// -------
60
190
@@ -75,6 +205,37 @@ auto indices(J&& x) {
75
205
76
206
77
207
208
+ // IDENTIFIERS
209
+ // -----------
210
+
211
+ template <class I >
212
+ auto identifiers (I ib, I ie) {
213
+ using K = typename iterator_traits<I>::value_type;
214
+ unordered_map<K, int > a; int i = 0 ;
215
+ for (I it=ib; it!=ie; ++it)
216
+ if (a.count (*it)==0 ) a[*it] = i++;
217
+ return a;
218
+ }
219
+
220
+ template <class J >
221
+ auto identifiers (const J& x) {
222
+ return identifiers (x.begin (), x.end ());
223
+ }
224
+
225
+
226
+
227
+
228
+ // TRANSFORM
229
+ // ---------
230
+
231
+ template <class J , class F >
232
+ void transform (J& x, F fn) {
233
+ transform (x.begin (), x.end (), x.begin (), fn);
234
+ }
235
+
236
+
237
+
238
+
78
239
// SET-DIFFERENCE
79
240
// --------------
80
241
@@ -95,3 +256,66 @@ auto setDifference(J&& x, K&& y) {
95
256
vector<T> a; setDifference (a, x, y);
96
257
return a;
97
258
}
259
+
260
+
261
+
262
+
263
+ // TO-*
264
+ // ----
265
+
266
+ template <class T , class I >
267
+ void toVector (vector<T>& a, I ib, I ie) {
268
+ a.clear ();
269
+ for (I it=ib; it!=ie; ++it)
270
+ a.push_back (*it);;
271
+ }
272
+
273
+ template <class I >
274
+ auto toVector (I ib, I ie) {
275
+ using T = typename I::value_type;
276
+ vector<T> a; toVector (a, ib, ie);
277
+ return a;
278
+ }
279
+
280
+ template <class T , class J >
281
+ void toVector (vector<T>& a, const J& x) {
282
+ toVector (a, x.begin (), x.end ());
283
+ }
284
+
285
+ template <class J >
286
+ void toVector (const J& x) {
287
+ return toVector (x.begin (), x.end ());
288
+ }
289
+
290
+
291
+
292
+
293
+ // HASH-VALUE
294
+ // ----------
295
+
296
+ template <class T , class I >
297
+ size_t hashValue (vector<T>& vs, I ib, I ie) {
298
+ size_t a = 0 ;
299
+ toVector (vs, ib, ie);
300
+ sort (vs.begin (), vs.end ());
301
+ for (const T& v : vs)
302
+ a ^= hash<T>{}(v) + 0x9e3779b9 + (a<<6 ) + (a>>2 ); // from boost::hash_combine
303
+ return a;
304
+ }
305
+
306
+ template <class I >
307
+ size_t hashValue (I ib, I ie) {
308
+ using T = typename I::value_type;
309
+ vector<T> vs;
310
+ return hashValue (vs, ib, ie);
311
+ }
312
+
313
+ template <class T , class J >
314
+ size_t hashValue (vector<T>& vs, const J& x) {
315
+ return hashValue (vs, x.begin (), x.end ());
316
+ }
317
+
318
+ template <class J >
319
+ size_t hashValue (const J& x) {
320
+ return hashValue (x.begin (), x.end ());
321
+ }
0 commit comments