Build system improvements
[ustl.git] / uctralgo.h
blob36ff2b1a3c3ff913c3b45c697fdbc64153bc1e73
1 // This file is part of the ustl library, an STL implementation.
2 //
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
5 //
6 // \file uctralgo.h
7 //
8 // \brief Implementation of STL algorithms with container shortcuts.
9 //
10 // The function prototypes are copied
11 // exactly from the SGI version of STL documentation along with comments about
12 // their use. The code is NOT the same, though the functionality usually is.
15 #ifndef UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0
16 #define UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0
18 namespace ustl {
20 /// Copy copies elements from the range [first, last) to the range
21 /// [result, result + (last - first)). That is, it performs the assignments
22 /// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally,
23 /// for every integer n from 0 to last - first, copy performs the assignment
24 /// *(result + n) = *(first + n). Assignments are performed in forward order,
25 /// i.e. in order of increasing n.
26 /// \ingroup MutatingAlgorithms
27 ///
28 template <typename Container, typename OutputIterator>
29 inline OutputIterator copy (const Container& ctr, OutputIterator result)
31 return (copy (ctr.begin(), ctr.end(), result));
34 /// Copy_if copies elements from the range [first, last) to the range
35 /// [result, result + (last - first)) if pred(*i) returns true.
36 /// \ingroup MutatingAlgorithms
37 ///
38 template <typename Container, typename OutputIterator, typename Predicate>
39 inline OutputIterator copy_if (Container& ctr, OutputIterator result, Predicate pred)
41 return (copy_if (ctr.begin(), ctr.end(), result, pred));
44 /// For_each applies the function object f to each element in the range
45 /// [first, last); f's return value, if any, is ignored. Applications are
46 /// performed in forward order, i.e. from first to last. For_each returns
47 /// the function object after it has been applied to each element.
48 /// \ingroup MutatingAlgorithms
49 ///
50 template <typename Container, typename UnaryFunction>
51 inline UnaryFunction for_each (Container& ctr, UnaryFunction f)
53 return (for_each (ctr.begin(), ctr.end(), f));
56 /// For_each applies the function object f to each element in the range
57 /// [first, last); f's return value, if any, is ignored. Applications are
58 /// performed in forward order, i.e. from first to last. For_each returns
59 /// the function object after it has been applied to each element.
60 /// \ingroup MutatingAlgorithms
61 ///
62 template <typename Container, typename UnaryFunction>
63 inline UnaryFunction for_each (const Container& ctr, UnaryFunction f)
65 return (for_each (ctr.begin(), ctr.end(), f));
68 /// Returns the first iterator i in the range [first, last) such that
69 /// *i == value. Returns last if no such iterator exists.
70 /// \ingroup SearchingAlgorithms
71 ///
72 template <typename Container, typename EqualityComparable>
73 inline typename Container::const_iterator find (const Container& ctr, const EqualityComparable& value)
75 return (find (ctr.begin(), ctr.end(), value));
77 template <typename Container, typename EqualityComparable>
78 inline typename Container::iterator find (Container& ctr, const EqualityComparable& value)
80 return (find (ctr.begin(), ctr.end(), value));
83 /// Returns the first iterator i in the range [first, last) such that
84 /// pred(*i) is true. Returns last if no such iterator exists.
85 /// \ingroup SearchingAlgorithms
86 ///
87 template <typename Container, typename Predicate>
88 inline typename Container::const_iterator find_if (const Container& ctr, Predicate pred)
90 return (find_if (ctr.begin(), ctr.end(), pred));
92 template <typename Container, typename Predicate>
93 inline typename Container::iterator find_if (Container& ctr, Predicate pred)
95 return (find_if (ctr.begin(), ctr.end(), pred));
98 /// Count finds the number of elements in [first, last) that are equal
99 /// to value. More precisely, the first version of count returns the
100 /// number of iterators i in [first, last) such that *i == value.
101 /// \ingroup ConditionAlgorithms
103 template <typename Container, typename EqualityComparable>
104 inline size_t count (const Container& ctr, const EqualityComparable& value)
106 return (count (ctr.begin(), ctr.end(), value));
109 /// Count_if finds the number of elements in [first, last) that satisfy the
110 /// predicate pred. More precisely, the first version of count_if returns the
111 /// number of iterators i in [first, last) such that pred(*i) is true.
112 /// \ingroup ConditionAlgorithms
114 template <typename Container, typename Predicate>
115 inline size_t count_if (const Container& ctr, Predicate pred)
117 return (count_if (ctr.begin(), ctr.end(), pred));
120 /// The first version of transform performs the operation op(*i) for each
121 /// iterator i in the range [first, last), and assigns the result of that
122 /// operation to *o, where o is the corresponding output iterator. That is,
123 /// for each n such that 0 <= n < last - first, it performs the assignment
124 /// *(result + n) = op(*(first + n)).
125 /// The return value is result + (last - first).
126 /// \ingroup MutatingAlgorithms
128 template <typename Container, typename UnaryFunction>
129 inline void transform (Container& ctr, UnaryFunction op)
131 transform (ctr.begin(), ctr.end(), ctr.begin(), op);
134 /// The first version of transform performs the operation op(*i) for each
135 /// iterator i in the range [first, last), and assigns the result of that
136 /// operation to *o, where o is the corresponding output iterator. That is,
137 /// for each n such that 0 <= n < last - first, it performs the assignment
138 /// *(result + n) = op(*(first + n)).
139 /// The return value is result + (last - first).
140 /// \ingroup MutatingAlgorithms
142 template <typename Container, typename OutputIterator, typename UnaryFunction>
143 inline OutputIterator transform (Container& ctr, OutputIterator result, UnaryFunction op)
145 return (transform (ctr.begin(), ctr.end(), result, op));
148 /// The second version of transform is very similar, except that it uses a
149 /// Binary Function instead of a Unary Function: it performs the operation
150 /// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns
151 /// the result to *o, where i2 is the corresponding iterator in the second
152 /// input range and where o is the corresponding output iterator. That is,
153 /// for each n such that 0 <= n < last1 - first1, it performs the assignment
154 /// *(result + n) = op(*(first1 + n), *(first2 + n).
155 /// The return value is result + (last1 - first1).
156 /// \ingroup MutatingAlgorithms
158 template <typename Container, typename InputIterator, typename OutputIterator, typename BinaryFunction>
159 inline OutputIterator transform (Container& ctr, InputIterator first, OutputIterator result, BinaryFunction op)
161 return (transform (ctr.begin(), ctr.end(), first, result, op));
164 /// Replace replaces every element in the range [first, last) equal to
165 /// old_value with new_value. That is: for every iterator i,
166 /// if *i == old_value then it performs the assignment *i = new_value.
167 /// \ingroup MutatingAlgorithms
169 template <typename Container, typename T>
170 inline void replace (Container& ctr, const T& old_value, const T& new_value)
172 replace (ctr.begin(), ctr.end(), old_value, new_value);
175 /// Replace_if replaces every element in the range [first, last) for which
176 /// pred returns true with new_value. That is: for every iterator i, if
177 /// pred(*i) is true then it performs the assignment *i = new_value.
178 /// \ingroup MutatingAlgorithms
180 template <typename Container, typename Predicate, typename T>
181 inline void replace_if (Container& ctr, Predicate pred, const T& new_value)
183 replace_if (ctr.begin(), ctr.end(), pred, new_value);
186 /// Replace_copy copies elements from the range [first, last) to the range
187 /// [result, result + (last-first)), except that any element equal to old_value
188 /// is not copied; new_value is copied instead. More precisely, for every
189 /// integer n such that 0 <= n < last-first, replace_copy performs the
190 /// assignment *(result+n) = new_value if *(first+n) == old_value, and
191 /// *(result+n) = *(first+n) otherwise.
192 /// \ingroup MutatingAlgorithms
194 template <typename Container, typename OutputIterator, typename T>
195 inline OutputIterator replace_copy (const Container& ctr, OutputIterator result, const T& old_value, const T& new_value)
197 return (replace_copy (ctr.begin(), ctr.end(), result, old_value, new_value));
200 /// Replace_copy_if copies elements from the range [first, last) to the range
201 /// [result, result + (last-first)), except that any element for which pred is
202 /// true is not copied; new_value is copied instead. More precisely, for every
203 /// integer n such that 0 <= n < last-first, replace_copy_if performs the
204 /// assignment *(result+n) = new_value if pred(*(first+n)),
205 /// and *(result+n) = *(first+n) otherwise.
206 /// \ingroup MutatingAlgorithms
208 template <typename Container, typename OutputIterator, typename Predicate, typename T>
209 inline OutputIterator replace_copy_if (const Container& ctr, OutputIterator result, Predicate pred, const T& new_value)
211 return (replace_copy_if (ctr.begin(), ctr.end(), result, pred, new_value));
214 /// Fill assigns the value value to every element in the range [first, last).
215 /// That is, for every iterator i in [first, last),
216 /// it performs the assignment *i = value.
217 /// \ingroup GeneratorAlgorithms
219 template <typename Container, typename T>
220 inline void fill (Container& ctr, const T& value)
222 fill (ctr.begin(), ctr.end(), value);
225 /// Generate assigns the result of invoking gen, a function object that
226 /// takes no arguments, to each element in the range [first, last).
227 /// \ingroup GeneratorAlgorithms
229 template <typename Container, typename Generator>
230 inline void generate (Container& ctr, Generator gen)
232 generate (ctr.begin(), ctr.end(), gen);
235 /// Randomly permute the elements of the container.
236 /// \ingroup GeneratorAlgorithms
238 template <typename Container>
239 inline void random_shuffle (Container& ctr)
241 random_shuffle (ctr.begin(), ctr.end());
244 /// Remove_copy copies elements that are not equal to value from the range
245 /// [first, last) to a range beginning at result. The return value is the
246 /// end of the resulting range. This operation is stable, meaning that the
247 /// relative order of the elements that are copied is the same as in the
248 /// range [first, last).
249 /// \ingroup MutatingAlgorithms
251 template <typename Container, typename OutputIterator, typename T>
252 inline OutputIterator remove_copy (const Container& ctr, OutputIterator result, const T& value)
254 return (remove_copy (ctr.begin(), ctr.end(), result, value));
257 /// Remove_copy_if copies elements from the range [first, last) to a range
258 /// beginning at result, except that elements for which pred is true are not
259 /// copied. The return value is the end of the resulting range. This operation
260 /// is stable, meaning that the relative order of the elements that are copied
261 /// is the same as in the range [first, last).
262 /// \ingroup MutatingAlgorithms
264 template <typename Container, typename OutputIterator, typename Predicate>
265 inline OutputIterator remove_copy_if (const Container& ctr, OutputIterator result, Predicate pred)
267 return (remove_copy_if (ctr.begin(), ctr.end(), result, pred));
270 /// Remove removes from the range [first, last) all elements that are equal to
271 /// value. That is, remove returns an iterator new_last such that the range
272 /// [first, new_last) contains no elements equal to value. Remove is stable,
273 /// meaning that the relative order of elements that are not equal to value is
274 /// unchanged.
275 /// \ingroup MutatingAlgorithms
277 template <typename Container, typename T>
278 inline void remove (Container& ctr, const T& value)
280 ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), value), ctr.end());
283 /// Remove removes from the range [first, last) all elements that have an iterator
284 /// in range [rfirst, rlast). The range is assumed to be sorted. That is, remove
285 /// returns an iterator new_last such that the range [first, new_last) contains
286 /// no elements whose iterators are in [rfirst, rlast). Remove is stable,
287 /// meaning that the relative order of elements that are not equal to value is
288 /// unchanged. This version of the algorithm is a uSTL extension.
289 /// \ingroup MutatingAlgorithms
291 template <typename Container, typename ForwardIterator>
292 inline void remove (Container& ctr, ForwardIterator rfirst, ForwardIterator rlast)
294 ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), rfirst, rlast), ctr.end());
297 /// Remove_if removes from the range [first, last) every element x such that
298 /// pred(x) is true. That is, remove_if returns an iterator new_last such that
299 /// the range [first, new_last) contains no elements for which pred is true.
300 /// The iterators in the range [new_last, last) are all still dereferenceable,
301 /// but the elements that they point to are unspecified. Remove_if is stable,
302 /// meaning that the relative order of elements that are not removed is
303 /// unchanged.
304 /// \ingroup MutatingAlgorithms
306 template <typename Container, typename Predicate>
307 inline void remove_if (Container& ctr, Predicate pred)
309 ctr.erase (remove_copy_if (ctr.begin(), ctr.end(), ctr.begin(), pred), ctr.end());
312 /// Unique_copy copies elements from the range [first, last) to a range
313 /// beginning with result, except that in a consecutive group of duplicate
314 /// elements only the first one is copied. The return value is the end of
315 /// the range to which the elements are copied. This behavior is similar
316 /// to the Unix filter uniq.
317 /// \ingroup MutatingAlgorithms
319 template <typename Container, typename OutputIterator>
320 inline OutputIterator unique_copy (const Container& ctr, OutputIterator result)
322 return (unique_copy (ctr.begin(), ctr.end(), result));
325 /// Every time a consecutive group of duplicate elements appears in the range
326 /// [first, last), the algorithm unique removes all but the first element.
327 /// That is, unique returns an iterator new_last such that the range [first,
328 /// new_last) contains no two consecutive elements that are duplicates.
329 /// The iterators in the range [new_last, last) are all still dereferenceable,
330 /// but the elements that they point to are unspecified. Unique is stable,
331 /// meaning that the relative order of elements that are not removed is
332 /// unchanged.
333 /// \ingroup MutatingAlgorithms
335 template <typename Container>
336 inline void unique (Container& ctr)
338 ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin()), ctr.end());
341 /// Every time a consecutive group of duplicate elements appears in the range
342 /// [first, last), the algorithm unique removes all but the first element.
343 /// That is, unique returns an iterator new_last such that the range [first,
344 /// new_last) contains no two consecutive elements that are duplicates.
345 /// The iterators in the range [new_last, last) are all still dereferenceable,
346 /// but the elements that they point to are unspecified. Unique is stable,
347 /// meaning that the relative order of elements that are not removed is
348 /// unchanged.
349 /// \ingroup MutatingAlgorithms
351 template <typename Container, typename BinaryPredicate>
352 inline void unique (Container& ctr, BinaryPredicate binary_pred)
354 ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin(), binary_pred), ctr.end());
357 /// Reverse reverses a range.
358 /// That is: for every i such that 0 <= i <= (last - first) / 2),
359 /// it exchanges *(first + i) and *(last - (i + 1)).
360 /// \ingroup MutatingAlgorithms
362 template <typename Container>
363 inline void reverse (Container& ctr)
365 reverse (ctr.begin(), ctr.end());
368 /// Exchanges ranges [first, middle) and [middle, last)
369 /// \ingroup MutatingAlgorithms
371 template <typename Container>
372 inline void rotate (Container& ctr, off_t offset)
374 assert (size_t(offset > 0 ? offset : -offset) < ctr.size());
375 if (offset > 0)
376 rotate (ctr.begin(), ctr.end() - offset, ctr.end());
377 else
378 rotate (ctr.begin(), ctr.begin() - offset, ctr.end());
381 /// Returns the furthermost iterator i in [first, last) such that,
382 /// for every iterator j in [first, i), *j < value
383 /// Assumes the range is sorted.
384 /// \ingroup SearchingAlgorithms
386 template <typename Container, typename LessThanComparable>
387 inline typename Container::const_iterator lower_bound (const Container& ctr, const LessThanComparable& value)
389 return (lower_bound (ctr.begin(), ctr.end(), value));
391 template <typename Container, typename LessThanComparable>
392 inline typename Container::iterator lower_bound (Container& ctr, const LessThanComparable& value)
394 return (lower_bound (ctr.begin(), ctr.end(), value));
397 /// Returns the furthermost iterator i in [first,last) such that for
398 /// every iterator j in [first,i), value < *j is false.
399 /// \ingroup SearchingAlgorithms
401 template <typename Container, typename LessThanComparable>
402 inline typename Container::const_iterator upper_bound (const Container& ctr, const LessThanComparable& value)
404 return (upper_bound (ctr.begin(), ctr.end(), value));
406 template <typename Container, typename LessThanComparable>
407 inline typename Container::iterator upper_bound (Container& ctr, const LessThanComparable& value)
409 return (upper_bound (ctr.begin(), ctr.end(), value));
412 /// Performs a binary search for \p value.
413 /// Assumes the range is sorted.
414 /// \ingroup SearchingAlgorithms
416 template <typename Container>
417 inline typename Container::const_iterator binary_search (const Container& ctr, const typename Container::value_type& value)
419 return (binary_search (ctr.begin(), ctr.end(), value));
421 template <typename Container>
422 inline typename Container::iterator binary_search (Container& ctr, const typename Container::value_type& value)
424 return (binary_search (ctr.begin(), ctr.end(), value));
427 /// Returns pair<lower_bound,upper_bound>
428 /// \ingroup SearchingAlgorithms
430 template <typename Container, typename LessThanComparable>
431 inline pair<typename Container::const_iterator,typename Container::const_iterator> equal_range (const Container& ctr, const LessThanComparable& value)
433 return (equal_range (ctr.begin(), ctr.end(), value));
435 template <typename Container, typename LessThanComparable>
436 inline pair<typename Container::iterator,typename Container::iterator> equal_range (Container& ctr, const LessThanComparable& value)
438 return (equal_range (ctr.begin(), ctr.end(), value));
441 /// Sorts the container
442 /// \ingroup SortingAlgorithms
444 template <typename Container>
445 inline void sort (Container& ctr)
447 sort (ctr.begin(), ctr.end());
450 /// Sorts the container
451 /// \ingroup SortingAlgorithms
453 template <typename Container, typename Compare>
454 inline void sort (Container& ctr, Compare comp)
456 sort (ctr.begin(), ctr.end(), comp);
459 /// Sorts the container
460 /// \ingroup SortingAlgorithms
462 template <typename Container>
463 inline void stable_sort (Container& ctr)
465 stable_sort (ctr.begin(), ctr.end());
468 /// Sorts the container
469 /// \ingroup SortingAlgorithms
471 template <typename Container, typename Compare>
472 inline void stable_sort (Container& ctr, Compare comp)
474 stable_sort (ctr.begin(), ctr.end(), comp);
477 } // namespace ustl
479 #endif