algorithms.qbk 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. [/
  2. Copyright 2010 Neil Groves
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. /]
  6. [section:algorithms Range Algorithms]
  7. [section:introduction Introduction and motivation]
  8. In its most simple form a [*Range Algorithm] (or range-based algorithm) is simply an iterator-based algorithm where the /two/ iterator arguments have been replaced by /one/ range argument. For example, we may write
  9. ``
  10. #include <boost/range/algorithm.hpp>
  11. #include <vector>
  12. std::vector<int> vec = ...;
  13. boost::sort(vec);
  14. ``
  15. instead of
  16. ``
  17. std::sort(vec.begin(), vec.end());
  18. ``
  19. However, the return type of range algorithms is almost always different from that of existing iterator-based algorithms.
  20. One group of algorithms, like `boost::sort()`, will simply return the same range so that we can continue to pass the range around and/or further modify it. Because of this we may write
  21. ``
  22. boost:unique(boost::sort(vec));
  23. ``
  24. to first sort the range and then run `unique()` on the sorted range.
  25. Algorithms like `boost::unique()` fall into another group of algorithms that return (potentially) narrowed views of the original range. By default `boost::unique(rng)` returns the range `[boost::begin(rng), found)` where `found` denotes the iterator returned by `std::unique(boost::begin(rng), boost::end(rng))`
  26. Therefore exactly the unique values can be copied by writing
  27. ``
  28. boost::copy(boost::unique(boost::sort(vec)),
  29. std::ostream_iterator<int>(std::cout));
  30. ``
  31. Algorithms like `boost::unique` usually return the range: `[boost::begin(rng), found)`.
  32. However, this behaviour may be changed by supplying a `range_return_value`
  33. as a template parameter to the algorithm:
  34. [table
  35. [[Expression] [Return]]
  36. [[`boost::unique<boost::return_found>(rng)`] [returns a single iterator like `std::unique`]]
  37. [[`boost::unique<boost::return_begin_found>(rng)`] [returns the range `[boost::begin(rng), found)` (this is the default)]]
  38. [[`boost::unique<boost::return_begin_next>(rng)`] [returns the range `[boost::begin(rng), boost::next(found))`]]
  39. [[`boost::unique<boost::return_found_end>(rng)`] [returns the range `[found, boost::end(rng))`]]
  40. [[`boost::unique<boost::return_next_end>(rng)`] [returns the range `[boost::next(found),boost::end(rng))`]]
  41. [[`boost::unique<boost::return_begin_end>(rng)`] [returns the entire original range.]]
  42. ]
  43. This functionality has the following advantages:
  44. # it allows for ['*seamless functional-style programming*] where you do not need to use named local variables to store intermediate results
  45. # it is very ['*safe*] because the algorithm can verify out-of-bounds conditions and handle tricky conditions that lead to empty ranges
  46. For example, consider how easy we may erase the duplicates in a sorted container:
  47. ``
  48. std::vector<int> vec = ...;
  49. boost::erase(vec, boost::unique<boost::return_found_end>(boost::sort(vec)));
  50. ``
  51. Notice the use of `boost::return_found_end`. What if we wanted to erase all the duplicates except one of them? In old-fashioned STL-programming we might write
  52. ``
  53. // assume 'vec' is already sorted
  54. std::vector<int>::iterator i = std::unique(vec.begin(), vec.end());
  55. // remember this check or you get into problems
  56. if (i != vec.end())
  57. ++i;
  58. vec.erase(i, vec.end());
  59. ``
  60. The same task may be accomplished simply with
  61. ``
  62. boost::erase(vec, boost::unique<boost::return_next_end>(vec));
  63. ``
  64. and there is no need to worry about generating an invalid range. Furthermore, if the container is complex, calling `vec.end()` several times will be more expensive than using a range algorithm.
  65. [endsect]
  66. [section:mutating Mutating algorithms]
  67. [include algorithm/copy.qbk]
  68. [include algorithm/copy_backward.qbk]
  69. [include algorithm/fill.qbk]
  70. [include algorithm/fill_n.qbk]
  71. [include algorithm/generate.qbk]
  72. [include algorithm/inplace_merge.qbk]
  73. [include algorithm/merge.qbk]
  74. [include algorithm/nth_element.qbk]
  75. [include algorithm/partial_sort.qbk]
  76. [include algorithm/partition.qbk]
  77. [include algorithm/random_shuffle.qbk]
  78. [include algorithm/remove.qbk]
  79. [include algorithm/remove_copy.qbk]
  80. [include algorithm/remove_copy_if.qbk]
  81. [include algorithm/remove_if.qbk]
  82. [include algorithm/replace.qbk]
  83. [include algorithm/replace_copy.qbk]
  84. [include algorithm/replace_copy_if.qbk]
  85. [include algorithm/replace_if.qbk]
  86. [include algorithm/reverse.qbk]
  87. [include algorithm/reverse_copy.qbk]
  88. [include algorithm/rotate.qbk]
  89. [include algorithm/rotate_copy.qbk]
  90. [include algorithm/sort.qbk]
  91. [include algorithm/stable_partition.qbk]
  92. [include algorithm/stable_sort.qbk]
  93. [include algorithm/swap_ranges.qbk]
  94. [include algorithm/transform.qbk]
  95. [include algorithm/unique.qbk]
  96. [include algorithm/unique_copy.qbk]
  97. [endsect]
  98. [section:non_mutating Non-mutating algorithms]
  99. [include algorithm/adjacent_find.qbk]
  100. [include algorithm/binary_search.qbk]
  101. [include algorithm/count.qbk]
  102. [include algorithm/count_if.qbk]
  103. [include algorithm/equal.qbk]
  104. [include algorithm/equal_range.qbk]
  105. [include algorithm/for_each.qbk]
  106. [include algorithm/find.qbk]
  107. [include algorithm/find_end.qbk]
  108. [include algorithm/find_first_of.qbk]
  109. [include algorithm/find_if.qbk]
  110. [include algorithm/lexicographical_compare.qbk]
  111. [include algorithm/lower_bound.qbk]
  112. [include algorithm/max_element.qbk]
  113. [include algorithm/min_element.qbk]
  114. [include algorithm/mismatch.qbk]
  115. [include algorithm/search.qbk]
  116. [include algorithm/search_n.qbk]
  117. [include algorithm/upper_bound.qbk]
  118. [endsect]
  119. [section:set Set algorithms]
  120. [include algorithm/includes.qbk]
  121. [include algorithm/set_union.qbk]
  122. [include algorithm/set_intersection.qbk]
  123. [include algorithm/set_difference.qbk]
  124. [include algorithm/set_symmetric_difference.qbk]
  125. [endsect]
  126. [section:heap Heap algorithms]
  127. [include algorithm/push_heap.qbk]
  128. [include algorithm/pop_heap.qbk]
  129. [include algorithm/make_heap.qbk]
  130. [include algorithm/sort_heap.qbk]
  131. [endsect]
  132. [section:permutation Permutation algorithms]
  133. [include algorithm/next_permutation.qbk]
  134. [include algorithm/prev_permutation.qbk]
  135. [endsect]
  136. [section:new New algorithms]
  137. [include algorithm_ext/copy_n.qbk]
  138. [include algorithm_ext/erase.qbk]
  139. [include algorithm_ext/for_each.qbk]
  140. [include algorithm_ext/insert.qbk]
  141. [include algorithm_ext/iota.qbk]
  142. [include algorithm_ext/is_sorted.qbk]
  143. [include algorithm_ext/overwrite.qbk]
  144. [include algorithm_ext/push_back.qbk]
  145. [include algorithm_ext/push_front.qbk]
  146. [include algorithm_ext/remove_erase.qbk]
  147. [include algorithm_ext/remove_erase_if.qbk]
  148. [endsect]
  149. [section:numeric Numeric algorithms]
  150. [include numeric/accumulate.qbk]
  151. [include numeric/adjacent_difference.qbk]
  152. [include numeric/inner_product.qbk]
  153. [include numeric/partial_sum.qbk]
  154. [endsect]
  155. [endsect]