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