sort_subrange.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Copyright (c) Marshall Clow 2008-2012.
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. Revision history:
  6. 28 Sep 2015 mtc First version
  7. */
  8. /// \file sort_subrange.hpp
  9. /// \brief Sort a subrange
  10. /// \author Marshall Clow
  11. ///
  12. /// Suggested by Sean Parent in his CppCon 2015 keynote
  13. #ifndef BOOST_ALGORITHM_SORT_SUBRANGE_HPP
  14. #define BOOST_ALGORITHM_SORT_SUBRANGE_HPP
  15. #include <functional> // For std::less
  16. #include <iterator> // For std::iterator_traits
  17. #include <algorithm> // For nth_element and partial_sort
  18. #include <boost/config.hpp>
  19. #include <boost/range/begin.hpp>
  20. #include <boost/range/end.hpp>
  21. namespace boost { namespace algorithm {
  22. /// \fn sort_subrange ( T const& val,
  23. /// Iterator first, Iterator last,
  24. /// Iterator sub_first, Iterator sub_last,
  25. /// Pred p )
  26. /// \brief Sort the subrange [sub_first, sub_last) that is inside
  27. /// the range [first, last) as if you had sorted the entire range.
  28. ///
  29. /// \param first The start of the larger range
  30. /// \param last The end of the larger range
  31. /// \param sub_first The start of the sub range
  32. /// \param sub_last The end of the sub range
  33. /// \param p A predicate to use to compare the values.
  34. /// p ( a, b ) returns a boolean.
  35. ///
  36. template<typename Iterator, typename Pred>
  37. void sort_subrange (
  38. Iterator first, Iterator last,
  39. Iterator sub_first, Iterator sub_last,
  40. Pred p)
  41. {
  42. if (sub_first == sub_last) return; // the empty sub-range is already sorted.
  43. if (sub_first != first) { // sub-range is at the start, don't need to partition
  44. (void) std::nth_element(first, sub_first, last, p);
  45. ++sub_first;
  46. }
  47. std::partial_sort(sub_first, sub_last, last, p);
  48. }
  49. template<typename Iterator>
  50. void sort_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
  51. {
  52. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  53. return sort_subrange(first, last, sub_first, sub_last, std::less<value_type>());
  54. }
  55. /// range versions?
  56. /// \fn partition_subrange ( T const& val,
  57. /// Iterator first, Iterator last,
  58. /// Iterator sub_first, Iterator sub_last,
  59. /// Pred p )
  60. /// \brief Gather the elements of the subrange [sub_first, sub_last) that is
  61. /// inside the range [first, last) as if you had sorted the entire range.
  62. ///
  63. /// \param first The start of the larger range
  64. /// \param last The end of the larger range
  65. /// \param sub_first The start of the sub range
  66. /// \param sub_last The end of the sub range
  67. /// \param p A predicate to use to compare the values.
  68. /// p ( a, b ) returns a boolean.
  69. ///
  70. template<typename Iterator, typename Pred>
  71. void partition_subrange (
  72. Iterator first, Iterator last,
  73. Iterator sub_first, Iterator sub_last,
  74. Pred p)
  75. {
  76. if (sub_first != first) {
  77. (void) std::nth_element(first, sub_first, last, p);
  78. ++sub_first;
  79. }
  80. if (sub_last != last)
  81. (void) std::nth_element(sub_first, sub_last, last, p);
  82. }
  83. template<typename Iterator>
  84. void partition_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
  85. {
  86. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  87. return partition_subrange(first, last, sub_first, sub_last, std::less<value_type>());
  88. }
  89. }}
  90. #endif // BOOST_ALGORITHM_SORT_SUBRANGE_HPP