Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into actor-yield
[simgrid.git] / include / xbt / algorithm.hpp
1 /* Copyright (c) 2015-2017. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef XBT_ALGORITHM_HPP
7 #define XBT_ALGORITHM_HPP
8
9 #include <utility>
10
11 namespace simgrid {
12 namespace xbt {
13
14 /** @brief Sorts the elements of the sequence [first, last) according to their color assuming elements can have only
15  * three colors.  Since there are only three colors, it is linear and much faster than a classical sort.  See for
16  * example http://en.wikipedia.org/wiki/Dutch_national_flag_problem
17  *
18  * \param first forward iterators to the initial position of the sequence to partition.
19  * \param last forward iterators to the final position of the sequence to partition.
20  * \param color the color function that accepts an element in the range as argument, and returns a value of 0, 1, or 2.
21  *
22  * At the end of the call, elements with color 0 are at the beginning of the range, elements with color 2 are at the end
23  * and elements with color 1 are in the middle.
24  */
25 template <class ForwardIterator, class ColorFunction>
26 void three_way_partition(ForwardIterator first, ForwardIterator last, ColorFunction color)
27 {
28   ForwardIterator iter = first;
29   while (iter < last) {
30     int c = color(*iter);
31     if (c == 1) {
32       ++iter;
33     } else if (c == 0) {
34       if (iter != first)
35         std::swap(*iter, *first);
36       ++iter;
37       ++first;
38     } else { // c == 2
39       --last;
40       if (iter != last)
41         std::swap(*iter, *last);
42     }
43   }
44 }
45 }
46 }
47
48 #endif